summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-04-17 00:11:46 +0000
committerChad Rosier <mcrosier@apple.com>2013-04-17 00:11:46 +0000
commit4afa9b7ffc636104e225e815afc568af27a134da (patch)
tree70415250159a628b0cf2c22ba567597fbc845121 /lib
parentad74f335ef06fa3f6bb64120f8c6bb57a517ee58 (diff)
[ms-inline asm] Add support for parsing complex immediate expressions. Test
cases to be submitted on clang side shortly. rdar://13663768 and PR15760 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179655 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp83
1 files changed, 51 insertions, 32 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 66472622790..ec2f111602d 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -203,23 +203,26 @@ private:
class IntelExprStateMachine {
IntelExprState State;
unsigned BaseReg, IndexReg, TmpReg, Scale;
- int64_t Disp;
+ int64_t Imm;
const MCExpr *Sym;
StringRef SymName;
+ bool StopOnLBrac, AddImmPrefix;
InfixCalculator IC;
public:
- IntelExprStateMachine(int64_t disp) :
- State(IES_PLUS), BaseReg(0), IndexReg(0), TmpReg(0), Scale(1), Disp(disp),
- Sym(0) {}
+ IntelExprStateMachine(int64_t imm, bool stoponlbrac, bool addimmprefix) :
+ State(IES_PLUS), BaseReg(0), IndexReg(0), TmpReg(0), Scale(1), Imm(imm),
+ Sym(0), StopOnLBrac(stoponlbrac), AddImmPrefix(addimmprefix) {}
unsigned getBaseReg() { return BaseReg; }
unsigned getIndexReg() { return IndexReg; }
unsigned getScale() { return Scale; }
const MCExpr *getSym() { return Sym; }
StringRef getSymName() { return SymName; }
- int64_t getImm() { return Disp + IC.execute(); }
+ int64_t getImm() { return Imm + IC.execute(); }
bool isValidEndState() { return State == IES_RBRAC; }
-
+ bool getStopOnLBrac() { return StopOnLBrac; }
+ bool getAddImmPrefix() { return AddImmPrefix; }
+
void onPlus() {
switch (State) {
default:
@@ -1144,7 +1147,8 @@ RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
E = AsmRewrites->end(); I != E; ++I) {
if ((*I).Loc.getPointer() > BracLoc.getPointer())
continue;
- if ((*I).Kind == AOK_ImmPrefix) {
+ if ((*I).Kind == AOK_ImmPrefix || (*I).Kind == AOK_Imm) {
+ assert (!Found && "ImmDisp already rewritten.");
(*I).Kind = AOK_Imm;
(*I).Len = BracLoc.getPointer() - (*I).Loc.getPointer();
(*I).Val = FinalImmDisp;
@@ -1155,11 +1159,9 @@ RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
assert (Found && "Unable to rewrite ImmDisp.");
} else {
// We have a symbolic and an immediate displacement, but no displacement
+ // before the bracketed expression. Put the immediate displacement
// before the bracketed expression.
-
- // Put the immediate displacement before the bracketed expression.
- AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0,
- FinalImmDisp));
+ AsmRewrites->push_back(AsmRewrite(AOK_Imm, BracLoc, 0, FinalImmDisp));
}
}
// Remove all the ImmPrefix rewrites within the brackets.
@@ -1196,6 +1198,10 @@ X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
// identifier. Don't try an parse it as a register.
if (Tok.getString().startswith("."))
break;
+
+ // If we're parsing an immediate expression, we don't expect a '['.
+ if (SM.getStopOnLBrac() && getLexer().getKind() == AsmToken::LBrac)
+ break;
switch (getLexer().getKind()) {
default: {
@@ -1205,6 +1211,10 @@ X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
}
return ErrorOperand(Tok.getLoc(), "Unexpected token!");
}
+ case AsmToken::EndOfStatement: {
+ Done = true;
+ break;
+ }
case AsmToken::Identifier: {
// This could be a register or a symbolic displacement.
unsigned TmpReg;
@@ -1226,7 +1236,7 @@ X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
}
case AsmToken::Integer:
- if (isParsingInlineAsm())
+ if (isParsingInlineAsm() && SM.getAddImmPrefix())
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
Tok.getLoc()));
SM.onInteger(Tok.getIntVal());
@@ -1261,7 +1271,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
// Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
// may have already parsed an immediate displacement before the bracketed
// expression.
- IntelExprStateMachine SM(ImmDisp);
+ IntelExprStateMachine SM(ImmDisp, /*StopOnLBrac=*/false, /*AddImmPrefix=*/true);
if (X86Operand *Err = ParseIntelExpression(SM, End))
return Err;
@@ -1566,28 +1576,37 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
}
// Immediate.
- if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
- getLexer().is(AsmToken::Minus)) {
- const MCExpr *Val;
- bool isInteger = getLexer().is(AsmToken::Integer);
- if (!getParser().parseExpression(Val, End)) {
- if (isParsingInlineAsm())
+ if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
+ getLexer().is(AsmToken::LParen)) {
+ AsmToken StartTok = Tok;
+ IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
+ /*AddImmPrefix=*/false);
+ if (X86Operand *Err = ParseIntelExpression(SM, End))
+ return Err;
+
+ int64_t Imm = SM.getImm();
+ if (isParsingInlineAsm()) {
+ unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
+ if (StartTok.getString().size() == Len)
+ // Just add a prefix if this wasn't a complex immediate expression.
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
- // Immediate.
- if (getLexer().isNot(AsmToken::LBrac))
- return X86Operand::CreateImm(Val, Start, End);
-
- // Only positive immediates are valid.
- if (!isInteger) {
- Error(Tok.getLoc(), "expected a positive immediate "
- "displacement before bracketed expr.");
- return 0;
- }
+ else
+ // Otherwise, rewrite the complex expression as a single immediate.
+ InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, Start, Len, Imm));
+ }
- // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
- if (uint64_t ImmDisp = dyn_cast<MCConstantExpr>(Val)->getValue())
- return ParseIntelMemOperand(/*SegReg=*/0, ImmDisp, Start);
+ if (getLexer().isNot(AsmToken::LBrac)) {
+ const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
+ return X86Operand::CreateImm(ImmExpr, Start, End);
}
+
+ // Only positive immediates are valid.
+ if (Imm < 0)
+ return ErrorOperand(Start, "expected a positive immediate displacement "
+ "before bracketed expr.");
+
+ // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
+ return ParseIntelMemOperand(/*SegReg=*/0, Imm, Start);
}
// Register.