summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
diff options
context:
space:
mode:
authorAsiri Rathnayake <asiri.rathnayake@arm.com>2014-12-02 10:53:20 +0000
committerAsiri Rathnayake <asiri.rathnayake@arm.com>2014-12-02 10:53:20 +0000
commita0199b9a594151cd8889665de57ab2b3f69ee137 (patch)
tree7c444e993f3b12062c93ed4b1c0771c4329ab23f /llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
parent9efe625962156bf389aa18c447e38b5b0efcafb9 (diff)
downloadbcm5719-llvm-a0199b9a594151cd8889665de57ab2b3f69ee137.tar.gz
bcm5719-llvm-a0199b9a594151cd8889665de57ab2b3f69ee137.zip
Add support for ARM modified-immediate assembly syntax.
Certain ARM instructions accept 32-bit immediate operands encoded as a 8-bit integer value (0-255) and a 4-bit rotation (0-30, even). Current ARM assembly syntax support in LLVM allows the decoded (32-bit) immediate to be specified as a single immediate operand for such instructions: mov r0, #4278190080 The ARMARM defines an extended assembly syntax allowing the encoding to be made more explicit, as in: mov r0, #255, #8 ; (same 32-bit value as above) The behaviour of the two instructions can be different w.r.t flags, which is documented under "Modified immediate constants" in ARMARM. This patch enables support for this extended syntax at the MC layer. llvm-svn: 223113
Diffstat (limited to 'llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp')
-rw-r--r--llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index 03e4e0a5e17..16eea335261 100644
--- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -1318,6 +1318,52 @@ void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
O << markup(">");
}
+void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ MCOperand Op = MI->getOperand(OpNum);
+
+ // Support for fixups (MCFixup)
+ if (Op.isExpr())
+ return printOperand(MI, OpNum, O);
+
+ unsigned Bits = Op.getImm() & 0xFF;
+ unsigned Rot = (Op.getImm() & 0xF00) >> 7;
+
+ bool PrintUnsigned = false;
+ switch (MI->getOpcode()){
+ case ARM::MOVi:
+ // Movs to PC should be treated unsigned
+ PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
+ break;
+ case ARM::MSRi:
+ // Movs to special registers should be treated unsigned
+ PrintUnsigned = true;
+ break;
+ }
+
+ int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
+ if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
+ // #rot has the least possible value
+ O << "#" << markup("<imm:");
+ if (PrintUnsigned)
+ O << static_cast<uint32_t>(Rotated);
+ else
+ O << Rotated;
+ O << markup(">");
+ return;
+ }
+
+ // Explicit #bits, #rot implied
+ O << "#"
+ << markup("<imm:")
+ << Bits
+ << markup(">")
+ << ", #"
+ << markup("<imm:")
+ << Rot
+ << markup(">");
+}
+
void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
O << markup("<imm:")
OpenPOWER on IntegriCloud