summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-03-04 17:57:01 +0000
committerReid Kleckner <reid@kleckner.net>2014-03-04 17:57:01 +0000
commita9a43d01f29236b3427d94e55c65324626e46417 (patch)
treee348d8cd5babb0ebb4b8bc11a6504467e12411e3 /lib
parent86e85c1115b1f0aee1724c4a303a64caa056de76 (diff)
downloadllvm-a9a43d01f29236b3427d94e55c65324626e46417.tar.gz
llvm-a9a43d01f29236b3427d94e55c65324626e46417.tar.bz2
llvm-a9a43d01f29236b3427d94e55c65324626e46417.tar.xz
MS asm: Attempt to parse variables followed by a bracketed displacement
This is required to include MSVC's <atomic> header, which we do now in LLVM. Tests forthcoming in Clang, since that's where we test semantic inline asm changes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202865 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 59d78461f4..fdd538450b 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1307,6 +1307,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, SMLoc Start,
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
if (getLexer().is(AsmToken::LBrac))
return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
+ assert(ImmDisp == 0);
const MCExpr *Val;
if (!isParsingInlineAsm()) {
@@ -1321,8 +1322,39 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, SMLoc Start,
if (ParseIntelIdentifier(Val, Identifier, Info,
/*Unevaluated=*/false, End))
return 0;
- return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
- /*Scale=*/1, Start, End, Size, Identifier, Info);
+
+ if (!getLexer().is(AsmToken::LBrac))
+ return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
+ /*Scale=*/1, Start, End, Size, Identifier, Info);
+
+ Parser.Lex(); // Eat '['
+
+ // Parse Identifier [ ImmDisp ]
+ IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
+ /*AddImmPrefix=*/false);
+ if (ParseIntelExpression(SM, End))
+ return 0;
+
+ if (SM.getSym()) {
+ Error(Start, "cannot use more than one symbol in memory operand");
+ return 0;
+ }
+ if (SM.getBaseReg()) {
+ Error(Start, "cannot use base register with variable reference");
+ return 0;
+ }
+ if (SM.getIndexReg()) {
+ Error(Start, "cannot use index register with variable reference");
+ return 0;
+ }
+
+ const MCExpr *Disp = MCConstantExpr::Create(SM.getImm(), getContext());
+ // BaseReg is non-zero to avoid assertions. In the context of inline asm,
+ // we're pointing to a local variable in memory, so the base register is
+ // really the frame or stack pointer.
+ return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0,
+ /*Scale=*/1, Start, End, Size, Identifier,
+ Info.OpDecl);
}
/// Parse the '.' operator.