[PATCH] ARM IAS: properly handle expression operands

Saleem Abdulrasool compnerd at compnerd.org
Sat Dec 28 19:43:22 PST 2013


Hi rengolin, t.p.northover, logan,

Operands which involved label arithmetic would previously fail to parse.  This
corrects that by adding the additional case for the shift operand validation.

http://llvm-reviews.chandlerc.com/D2489

Files:
  lib/Target/ARM/AsmParser/ARMAsmParser.cpp
  lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
  test/MC/ARM/complex-operands.s

Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8729,12 +8729,22 @@
   // If the kind is a token for a literal immediate, check if our asm
   // operand matches. This is for InstAliases which have a fixed-value
   // immediate in the syntax.
-  if (Kind == MCK__35_0 && Op->isImm()) {
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
-    if (!CE)
-      return Match_InvalidOperand;
-    if (CE->getValue() == 0)
-      return Match_Success;
+  switch (Kind) {
+  default: break;
+  case MCK__35_0:
+    if (Op->isImm())
+      if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()))
+        if (CE->getValue() == 0)
+          return Match_Success;
+    break;
+  case MCK_ARMSOImm:
+    if (Op->isImm()) {
+      const MCExpr *SOExpr = Op->getImm();
+      int64_t Value;
+      if (!SOExpr->EvaluateAsAbsolute(Value))
+        return Match_Success;
+    }
+    break;
   }
   return Match_InvalidOperand;
 }
Index: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
===================================================================
--- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -307,17 +307,30 @@
       << markup(">");
   } else {
     assert(Op.isExpr() && "unknown operand kind in printOperand");
-    // If a symbolic branch target was added as a constant expression then print
-    // that address in hex. And only print 32 unsigned bits for the address.
-    const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
-    int64_t Address;
-    if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
+    const MCExpr *Expr = Op.getExpr();
+    switch (Expr->getKind()) {
+    case MCExpr::Binary:
+      O << '#' << *Expr;
+      break;
+    case MCExpr::Constant: {
+      // If a symbolic branch target was added as a constant expression then
+      // print that address in hex. And only print 32 unsigned bits for the
+      // address.
+      const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
+      int64_t TargetAddress;
+      if (!Constant->EvaluateAsAbsolute(TargetAddress)) {
+        O << '#' << *Expr;
+        break;
+      }
       O << "0x";
-      O.write_hex((uint32_t)Address);
+      O.write_hex(static_cast<uint32_t>(TargetAddress));
+      break;
     }
-    else {
-      // Otherwise, just print the expression.
-      O << *Op.getExpr();
+    default:
+      // FIXME: Should we always treat this as if it is a constant literal and
+      // prefix it with '#'?
+      O << *Expr;
+      break;
     }
   }
 }
Index: test/MC/ARM/complex-operands.s
===================================================================
--- /dev/null
+++ test/MC/ARM/complex-operands.s
@@ -0,0 +1,40 @@
+@ RUN: llvm-mc -triple armv7-eabi -filetype asm -o - %s | FileCheck %s
+
+	.syntax unified
+
+	.data
+
+	.type .L_table_begin,%object
+.L_table_begin:
+	.rep 2
+	.long 0xd15ab1ed
+	.long 0x0ff1c1a1
+	.endr
+.L_table_end:
+
+	.text
+
+	.type return,%function
+return:
+	bx lr
+
+	.global arm_function
+	.type arm_function,%function
+arm_function:
+	mov r0, #(.L_table_end - .L_table_begin) >> 2
+	blx return
+
+@ CHECK-LABEL: arm_function
+@ CHECK:  	movw r0, #(.L_table_end-.L_table_begin)>>2
+@ CHECK:  	blx return
+
+	.global thumb_function
+	.type thumb_function,%function
+thumb_function:
+	mov r0, #(.L_table_end - .L_table_begin) >> 2
+	blx return
+
+@ CHECK-LABEL: thumb_function
+@ CHECK:  	movw r0, #(.L_table_end-.L_table_begin)>>2
+@ CHECK:  	blx return
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2489.1.patch
Type: text/x-patch
Size: 3683 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131228/a8d69eb9/attachment.bin>


More information about the llvm-commits mailing list