[llvm] r198735 - ARM IAS: properly handle expression operands

Saleem Abdulrasool compnerd at compnerd.org
Tue Jan 7 19:28:14 PST 2014


Author: compnerd
Date: Tue Jan  7 21:28:14 2014
New Revision: 198735

URL: http://llvm.org/viewvc/llvm-project?rev=198735&view=rev
Log:
ARM IAS: properly handle expression operands

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

Added:
    llvm/trunk/test/MC/ARM/complex-operands.s
Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=198735&r1=198734&r2=198735&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Jan  7 21:28:14 2014
@@ -8775,12 +8775,24 @@ unsigned ARMAsmParser::validateTargetOpe
   // 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;
+      assert((Value >= INT32_MIN && Value <= INT32_MAX) &&
+             "expression value must be representiable in 32 bits");
+    }
+    break;
   }
   return Match_InvalidOperand;
 }

Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=198735&r1=198734&r2=198735&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Tue Jan  7 21:28:14 2014
@@ -307,17 +307,30 @@ void ARMInstPrinter::printOperand(const
       << 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)) {
-      O << "0x";
-      O.write_hex((uint32_t)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;
+      } else {
+        O << "0x";
+        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;
     }
   }
 }

Added: llvm/trunk/test/MC/ARM/complex-operands.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/complex-operands.s?rev=198735&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/complex-operands.s (added)
+++ llvm/trunk/test/MC/ARM/complex-operands.s Tue Jan  7 21:28:14 2014
@@ -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
+





More information about the llvm-commits mailing list