OSDN Git Service

Changed the X86 assembler for intel syntax to work with directional labels.
authorKevin Enderby <enderby@apple.com>
Thu, 19 Dec 2013 22:02:03 +0000 (22:02 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 19 Dec 2013 22:02:03 +0000 (22:02 +0000)
The X86 assembler has a separate code to parser the intel assembly syntax
in X86AsmParser::ParseIntelOperand().  This did not parse directional labels.
And if something like 1f was used as a branch target it would get an
"Unexpected token" error.

The fix starts in X86AsmParser::ParseIntelExpression() in the case for
AsmToken::Integer, it needs to grab the IntVal from the current token
then look for a 'b' or 'f' following the Integer.  Then it basically needs to
do what is done in AsmParser::parsePrimaryExpr() for directional
labels.  It saves the MCExpr it creates in the IntelExprStateMachine
in the Sym field.

When it returns to X86AsmParser::ParseIntelOperand() it looks
for a non-zero Sym field in the IntelExprStateMachine and if
set it creates a memory operand not an immediate operand
it would normally do for the Integer.

rdar://14961158

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/X86/intel-syntax-directional-label.s [new file with mode: 0644]

index 15dcc5c..fe53396 100644 (file)
@@ -1329,12 +1329,37 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
       }
       return Error(Tok.getLoc(), "Unexpected identifier!");
     }
-    case AsmToken::Integer:
+    case AsmToken::Integer: {
       if (isParsingInlineAsm() && SM.getAddImmPrefix())
         InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
                                                     Tok.getLoc()));
-      SM.onInteger(Tok.getIntVal());
+      // Look for 'b' or 'f' following an Integer as a directional label
+      SMLoc Loc = getTok().getLoc();
+      int64_t IntVal = getTok().getIntVal();
+      End = consumeToken();
+      UpdateLocLex = false;
+      if (getLexer().getKind() == AsmToken::Identifier) {
+        StringRef IDVal = getTok().getString();
+        if (IDVal == "f" || IDVal == "b") {
+          MCSymbol *Sym =
+            getContext().GetDirectionalLocalSymbol(IntVal,
+                                                   IDVal == "f" ? 1 : 0);
+          MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+          const MCExpr *Val = 
+           MCSymbolRefExpr::Create(Sym, Variant, getContext());
+          if (IDVal == "b" && Sym->isUndefined())
+            return Error(Loc, "invalid reference to undefined symbol");
+          StringRef Identifier = Sym->getName();
+          SM.onIdentifierExpr(Val, Identifier);
+          End = consumeToken();
+        } else {
+          SM.onInteger(IntVal);
+        }
+      } else {
+        SM.onInteger(IntVal);
+      }
       break;
+    }
     case AsmToken::Plus:    SM.onPlus(); break;
     case AsmToken::Minus:   SM.onMinus(); break;
     case AsmToken::Star:    SM.onStar(); break;
@@ -1684,6 +1709,13 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
     }
 
     if (getLexer().isNot(AsmToken::LBrac)) {
+      // If a directional label (ie. 1f or 2b) was parsed above from
+      // ParseIntelExpression() then SM.getSym() was set to a pointer to
+      // to the MCExpr with the directional local symbol and this is a
+      // memory operand not an immediate operand.
+      if (SM.getSym())
+        return X86Operand::CreateMem(SM.getSym(), Start, End, Size);
+
       const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
       return X86Operand::CreateImm(ImmExpr, Start, End);
     }
diff --git a/test/MC/X86/intel-syntax-directional-label.s b/test/MC/X86/intel-syntax-directional-label.s
new file mode 100644 (file)
index 0000000..1ed1673
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: llvm-mc -triple x86_64-apple-darwin -x86-asm-syntax=intel %s | FileCheck %s
+// rdar://14961158
+       .text
+       .align 16
+       .globl FUNCTION_NAME
+       .private_extern FUNCTION_NAME
+FUNCTION_NAME:
+       .intel_syntax
+       cmp rdi, 1
+       jge 1f
+// CHECK:      jge     "L1\ 21"
+       add rdi, 2
+1:
+// CHECK:      "L1\ 21":
+       add rdi, 1
+       ret