ARM: support emission of complex SO expressions
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 13 Mar 2014 07:02:41 +0000 (07:02 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 13 Mar 2014 07:02:41 +0000 (07:02 +0000)
Support to the IAS was added to actually parse and handle the complex SO
expressions.  However, the object file lowering was not updated to compensate
for the fact that the shift operand may be an absolute expression.

When trying to assemble to an object file, the lowering would fail while
succeeding when emitting purely assembly.  Add an appropriate test.

The test case is inspired by the test case provided by Jiangning Liu who also
brought the issue to light.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203762 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
test/MC/ARM/shift-offset-addressing-emission.s [new file with mode: 0644]

index 3b2ca73aecd1d7677a9c8d68eaf46d524edf7329..716b22e3b3761156e55f9b3a5d99acbd9d8a5865 100644 (file)
@@ -271,8 +271,19 @@ public:
   unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
                            SmallVectorImpl<MCFixup> &Fixups,
                            const MCSubtargetInfo &STI) const {
-    unsigned SoImm = MI.getOperand(Op).getImm();
-    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
+    int SoImmVal = -1;
+
+    const MCOperand &MO = MI.getOperand(Op);
+    if (MO.isImm()) {
+      SoImmVal = ARM_AM::getSOImmVal(MO.getImm());
+    } else if (MO.isExpr()) {
+      int64_t Value;
+      bool Invalid = MO.getExpr()->EvaluateAsAbsolute(Value);
+      assert(!Invalid && "non-constant expression is not a valid SOImm operand");
+      assert((Value >= INT32_MIN && Value <= INT32_MAX) &&
+             "expression must be representable in 32 bits");
+      SoImmVal = Value;
+    }
     assert(SoImmVal != -1 && "Not a valid so_imm value!");
 
     // Encode rotate_imm.
diff --git a/test/MC/ARM/shift-offset-addressing-emission.s b/test/MC/ARM/shift-offset-addressing-emission.s
new file mode 100644 (file)
index 0000000..1dbd80e
--- /dev/null
@@ -0,0 +1,9 @@
+@ RUN: llvm-mc -triple armv7-elf -filetype obj -o - %s \
+@ RUN:   | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s
+
+       cmp r0, #(.L2 - .L1)
+.L1:
+.L2:
+
+@ CHECK: 0:    cmp     r0, #0
+