diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-03-04 17:57:01 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-03-04 17:57:01 +0000 |
commit | a9a43d01f29236b3427d94e55c65324626e46417 (patch) | |
tree | e348d8cd5babb0ebb4b8bc11a6504467e12411e3 /lib | |
parent | 86e85c1115b1f0aee1724c4a303a64caa056de76 (diff) | |
download | llvm-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.cpp | 36 |
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. |