summaryrefslogtreecommitdiff
path: root/lib/Target/X86/AsmParser/X86AsmParser.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2013-04-16 18:15:40 +0000
committerChad Rosier <mcrosier@apple.com>2013-04-16 18:15:40 +0000
commit8ccacf788aeb3834ba9b6a2dc4f524fe42c55076 (patch)
tree21cb30f02e6b95d13ae88a8bd5d40be0b8103e11 /lib/Target/X86/AsmParser/X86AsmParser.cpp
parent7e5d54c320f9f02284187ba0d34faf2e6e1988f6 (diff)
downloadllvm-8ccacf788aeb3834ba9b6a2dc4f524fe42c55076.tar.gz
llvm-8ccacf788aeb3834ba9b6a2dc4f524fe42c55076.tar.bz2
llvm-8ccacf788aeb3834ba9b6a2dc4f524fe42c55076.tar.xz
[ms-inline asm] Refactor. No functional change intended.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179610 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp824
1 files changed, 419 insertions, 405 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index da8824c2d0..90ac5058e5 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -33,11 +33,403 @@ using namespace llvm;
namespace {
struct X86Operand;
+static const char OpPrecedence[] = {
+ 0, // IC_PLUS
+ 0, // IC_MINUS
+ 1, // IC_MULTIPLY
+ 1, // IC_DIVIDE
+ 2, // IC_RPAREN
+ 3, // IC_LPAREN
+ 0, // IC_IMM
+ 0 // IC_REGISTER
+};
+
class X86AsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI;
MCAsmParser &Parser;
ParseInstructionInfo *InstInfo;
private:
+ enum InfixCalculatorTok {
+ IC_PLUS = 0,
+ IC_MINUS,
+ IC_MULTIPLY,
+ IC_DIVIDE,
+ IC_RPAREN,
+ IC_LPAREN,
+ IC_IMM,
+ IC_REGISTER
+ };
+
+ class InfixCalculator {
+ typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
+ SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
+ SmallVector<ICToken, 4> PostfixStack;
+
+ public:
+ int64_t popOperand() {
+ assert (!PostfixStack.empty() && "Poped an empty stack!");
+ ICToken Op = PostfixStack.pop_back_val();
+ assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
+ && "Expected and immediate or register!");
+ return Op.second;
+ }
+ void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
+ assert ((Op == IC_IMM || Op == IC_REGISTER) &&
+ "Unexpected operand!");
+ PostfixStack.push_back(std::make_pair(Op, Val));
+ }
+
+ void popOperator() { InfixOperatorStack.pop_back_val(); }
+ void pushOperator(InfixCalculatorTok Op) {
+ // Push the new operator if the stack is empty.
+ if (InfixOperatorStack.empty()) {
+ InfixOperatorStack.push_back(Op);
+ return;
+ }
+
+ // Push the new operator if it has a higher precedence than the operator
+ // on the top of the stack or the operator on the top of the stack is a
+ // left parentheses.
+ unsigned Idx = InfixOperatorStack.size() - 1;
+ InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
+ if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
+ InfixOperatorStack.push_back(Op);
+ return;
+ }
+
+ // The operator on the top of the stack has higher precedence than the
+ // new operator.
+ unsigned ParenCount = 0;
+ while (1) {
+ // Nothing to process.
+ if (InfixOperatorStack.empty())
+ break;
+
+ Idx = InfixOperatorStack.size() - 1;
+ StackOp = InfixOperatorStack[Idx];
+ if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
+ break;
+
+ // If we have an even parentheses count and we see a left parentheses,
+ // then stop processing.
+ if (!ParenCount && StackOp == IC_LPAREN)
+ break;
+
+ if (StackOp == IC_RPAREN) {
+ ++ParenCount;
+ InfixOperatorStack.pop_back_val();
+ } else if (StackOp == IC_LPAREN) {
+ --ParenCount;
+ InfixOperatorStack.pop_back_val();
+ } else {
+ InfixOperatorStack.pop_back_val();
+ PostfixStack.push_back(std::make_pair(StackOp, 0));
+ }
+ }
+ // Push the new operator.
+ InfixOperatorStack.push_back(Op);
+ }
+ int64_t execute() {
+ // Push any remaining operators onto the postfix stack.
+ while (!InfixOperatorStack.empty()) {
+ InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
+ if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
+ PostfixStack.push_back(std::make_pair(StackOp, 0));
+ }
+
+ if (PostfixStack.empty())
+ return 0;
+
+ SmallVector<ICToken, 16> OperandStack;
+ for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
+ ICToken Op = PostfixStack[i];
+ if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
+ OperandStack.push_back(Op);
+ } else {
+ assert (OperandStack.size() > 1 && "Too few operands.");
+ int64_t Val;
+ ICToken Op2 = OperandStack.pop_back_val();
+ ICToken Op1 = OperandStack.pop_back_val();
+ switch (Op.first) {
+ default:
+ report_fatal_error("Unexpected operator!");
+ break;
+ case IC_PLUS:
+ Val = Op1.second + Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_MINUS:
+ Val = Op1.second - Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_MULTIPLY:
+ assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Multiply operation with an immediate and a register!");
+ Val = Op1.second * Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_DIVIDE:
+ assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Divide operation with an immediate and a register!");
+ assert (Op2.second != 0 && "Division by zero!");
+ Val = Op1.second / Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ }
+ }
+ }
+ assert (OperandStack.size() == 1 && "Expected a single result.");
+ return OperandStack.pop_back_val().second;
+ }
+ };
+
+ enum IntelExprState {
+ IES_PLUS,
+ IES_MINUS,
+ IES_MULTIPLY,
+ IES_DIVIDE,
+ IES_LBRAC,
+ IES_RBRAC,
+ IES_LPAREN,
+ IES_RPAREN,
+ IES_REGISTER,
+ IES_REGISTER_STAR,
+ IES_INTEGER,
+ IES_INTEGER_STAR,
+ IES_IDENTIFIER,
+ IES_ERROR
+ };
+
+ class IntelExprStateMachine {
+ IntelExprState State;
+ unsigned BaseReg, IndexReg, TmpReg, Scale;
+ int64_t Disp;
+ const MCExpr *Sym;
+ StringRef SymName;
+ InfixCalculator IC;
+ public:
+ IntelExprStateMachine(int64_t disp) :
+ State(IES_PLUS), BaseReg(0), IndexReg(0), TmpReg(0), Scale(1), Disp(disp),
+ Sym(0) {}
+
+ 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(); }
+ bool isValidEndState() { return State == IES_RBRAC; }
+
+ void onPlus() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ State = IES_PLUS;
+ IC.pushOperator(IC_PLUS);
+ break;
+ case IES_REGISTER:
+ State = IES_PLUS;
+ // If we already have a BaseReg, then assume this is the IndexReg with a
+ // scale of 1.
+ if (!BaseReg) {
+ BaseReg = TmpReg;
+ } else {
+ assert (!IndexReg && "BaseReg/IndexReg already set!");
+ IndexReg = TmpReg;
+ Scale = 1;
+ }
+ IC.pushOperator(IC_PLUS);
+ break;
+ }
+ }
+ void onMinus() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_PLUS:
+ case IES_LPAREN:
+ IC.pushOperand(IC_IMM);
+ case IES_INTEGER:
+ case IES_RPAREN:
+ State = IES_MINUS;
+ IC.pushOperator(IC_MINUS);
+ break;
+ case IES_REGISTER:
+ State = IES_MINUS;
+ // If we already have a BaseReg, then assume this is the IndexReg with a
+ // scale of 1.
+ if (!BaseReg) {
+ BaseReg = TmpReg;
+ } else {
+ assert (!IndexReg && "BaseReg/IndexReg already set!");
+ IndexReg = TmpReg;
+ Scale = 1;
+ }
+ IC.pushOperator(IC_MINUS);
+ break;
+ }
+ }
+ void onRegister(unsigned Reg) {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_PLUS:
+ case IES_LPAREN:
+ State = IES_REGISTER;
+ TmpReg = Reg;
+ IC.pushOperand(IC_REGISTER);
+ break;
+ case IES_INTEGER_STAR:
+ assert (!IndexReg && "IndexReg already set!");
+ State = IES_INTEGER;
+ IndexReg = Reg;
+ Scale = IC.popOperand();
+ IC.pushOperand(IC_IMM);
+ IC.popOperator();
+ break;
+ }
+ }
+ void onDispExpr(const MCExpr *SymRef, StringRef SymRefName) {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_PLUS:
+ case IES_MINUS:
+ State = IES_INTEGER;
+ Sym = SymRef;
+ SymName = SymRefName;
+ IC.pushOperand(IC_IMM);
+ break;
+ }
+ }
+ void onInteger(int64_t TmpInt) {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_PLUS:
+ case IES_MINUS:
+ case IES_MULTIPLY:
+ case IES_DIVIDE:
+ case IES_LPAREN:
+ case IES_INTEGER_STAR:
+ State = IES_INTEGER;
+ IC.pushOperand(IC_IMM, TmpInt);
+ break;
+ case IES_REGISTER_STAR:
+ assert (!IndexReg && "IndexReg already set!");
+ State = IES_INTEGER;
+ IndexReg = TmpReg;
+ Scale = TmpInt;
+ IC.popOperator();
+ break;
+ }
+ }
+ void onStar() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ State = IES_INTEGER_STAR;
+ IC.pushOperator(IC_MULTIPLY);
+ break;
+ case IES_REGISTER:
+ State = IES_REGISTER_STAR;
+ IC.pushOperator(IC_MULTIPLY);
+ break;
+ case IES_RPAREN:
+ State = IES_MULTIPLY;
+ IC.pushOperator(IC_MULTIPLY);
+ break;
+ }
+ }
+ void onDivide() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ State = IES_DIVIDE;
+ IC.pushOperator(IC_DIVIDE);
+ break;
+ }
+ }
+ void onLBrac() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_RBRAC:
+ State = IES_PLUS;
+ IC.pushOperator(IC_PLUS);
+ break;
+ }
+ }
+ void onRBrac() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_RPAREN:
+ case IES_INTEGER:
+ State = IES_RBRAC;
+ break;
+ case IES_REGISTER:
+ State = IES_RBRAC;
+ // If we already have a BaseReg, then assume this is the IndexReg with a
+ // scale of 1.
+ if (!BaseReg) {
+ BaseReg = TmpReg;
+ } else {
+ assert (!IndexReg && "BaseReg/IndexReg already set!");
+ IndexReg = TmpReg;
+ Scale = 1;
+ }
+ break;
+ }
+ }
+ void onLParen() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_PLUS:
+ case IES_MINUS:
+ case IES_MULTIPLY:
+ case IES_DIVIDE:
+ case IES_INTEGER_STAR:
+ case IES_LPAREN:
+ State = IES_LPAREN;
+ IC.pushOperator(IC_LPAREN);
+ break;
+ }
+ }
+ void onRParen() {
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_REGISTER:
+ case IES_INTEGER:
+ case IES_PLUS:
+ case IES_MINUS:
+ case IES_MULTIPLY:
+ case IES_DIVIDE:
+ case IES_RPAREN:
+ State = IES_RPAREN;
+ IC.pushOperator(IC_RPAREN);
+ break;
+ }
+ }
+ };
+
MCAsmParser &getParser() const { return Parser; }
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
@@ -61,6 +453,7 @@ private:
X86Operand *ParseIntelOperator(unsigned OpKind);
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
SMLoc StartLoc);
+ X86Operand *ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
uint64_t ImmDisp, unsigned Size);
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
@@ -687,397 +1080,6 @@ static unsigned getIntelMemOperandSize(StringRef OpStr) {
return Size;
}
-enum InfixCalculatorTok {
- IC_PLUS = 0,
- IC_MINUS,
- IC_MULTIPLY,
- IC_DIVIDE,
- IC_RPAREN,
- IC_LPAREN,
- IC_IMM,
- IC_REGISTER
-};
-static const char OpPrecedence[] = {
- 0, // IC_PLUS
- 0, // IC_MINUS
- 1, // IC_MULTIPLY
- 1, // IC_DIVIDE
- 2, // IC_RPAREN
- 3, // IC_LPAREN
- 0, // IC_IMM
- 0 // IC_REGISTER
-};
-
-class InfixCalculator {
- typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
- SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
- SmallVector<ICToken, 4> PostfixStack;
-
-public:
- int64_t popOperand() {
- assert (!PostfixStack.empty() && "Poped an empty stack!");
- ICToken Op = PostfixStack.pop_back_val();
- assert ((Op.first == IC_IMM || Op.first == IC_REGISTER)
- && "Expected and immediate or register!");
- return Op.second;
- }
- void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
- assert ((Op == IC_IMM || Op == IC_REGISTER) &&
- "Unexpected operand!");
- PostfixStack.push_back(std::make_pair(Op, Val));
- }
-
- void popOperator() { InfixOperatorStack.pop_back_val(); }
- void pushOperator(InfixCalculatorTok Op) {
- // Push the new operator if the stack is empty.
- if (InfixOperatorStack.empty()) {
- InfixOperatorStack.push_back(Op);
- return;
- }
-
- // Push the new operator if it has a higher precedence than the operator on
- // the top of the stack or the operator on the top of the stack is a left
- // parentheses.
- unsigned Idx = InfixOperatorStack.size() - 1;
- InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
- if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
- InfixOperatorStack.push_back(Op);
- return;
- }
-
- // The operator on the top of the stack has higher precedence than the
- // new operator.
- unsigned ParenCount = 0;
- while (1) {
- // Nothing to process.
- if (InfixOperatorStack.empty())
- break;
-
- Idx = InfixOperatorStack.size() - 1;
- StackOp = InfixOperatorStack[Idx];
- if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
- break;
-
- // If we have an even parentheses count and we see a left parentheses,
- // then stop processing.
- if (!ParenCount && StackOp == IC_LPAREN)
- break;
-
- if (StackOp == IC_RPAREN) {
- ++ParenCount;
- InfixOperatorStack.pop_back_val();
- } else if (StackOp == IC_LPAREN) {
- --ParenCount;
- InfixOperatorStack.pop_back_val();
- } else {
- InfixOperatorStack.pop_back_val();
- PostfixStack.push_back(std::make_pair(StackOp, 0));
- }
- }
- // Push the new operator.
- InfixOperatorStack.push_back(Op);
- }
- int64_t execute() {
- // Push any remaining operators onto the postfix stack.
- while (!InfixOperatorStack.empty()) {
- InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
- if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
- PostfixStack.push_back(std::make_pair(StackOp, 0));
- }
-
- if (PostfixStack.empty())
- return 0;
-
- SmallVector<ICToken, 16> OperandStack;
- for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
- ICToken Op = PostfixStack[i];
- if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
- OperandStack.push_back(Op);
- } else {
- assert (OperandStack.size() > 1 && "Too few operands.");
- int64_t Val;
- ICToken Op2 = OperandStack.pop_back_val();
- ICToken Op1 = OperandStack.pop_back_val();
- switch (Op.first) {
- default:
- report_fatal_error("Unexpected operator!");
- break;
- case IC_PLUS:
- Val = Op1.second + Op2.second;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_MINUS:
- Val = Op1.second - Op2.second;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_MULTIPLY:
- assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Multiply operation with an immediate and a register!");
- Val = Op1.second * Op2.second;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- case IC_DIVIDE:
- assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
- "Divide operation with an immediate and a register!");
- assert (Op2.second != 0 && "Division by zero!");
- Val = Op1.second / Op2.second;
- OperandStack.push_back(std::make_pair(IC_IMM, Val));
- break;
- }
- }
- }
- assert (OperandStack.size() == 1 && "Expected a single result.");
- return OperandStack.pop_back_val().second;
- }
-};
-
-enum IntelBracExprState {
- IBES_PLUS,
- IBES_MINUS,
- IBES_MULTIPLY,
- IBES_DIVIDE,
- IBES_LBRAC,
- IBES_RBRAC,
- IBES_LPAREN,
- IBES_RPAREN,
- IBES_REGISTER,
- IBES_REGISTER_STAR,
- IBES_INTEGER,
- IBES_INTEGER_STAR,
- IBES_IDENTIFIER,
- IBES_ERROR
-};
-
-class IntelBracExprStateMachine {
- IntelBracExprState State;
- unsigned BaseReg, IndexReg, TmpReg, Scale;
- int64_t Disp;
- const MCExpr *Sym;
- StringRef SymName;
- InfixCalculator IC;
-public:
- IntelBracExprStateMachine(MCAsmParser &parser, int64_t disp) :
- State(IBES_PLUS), BaseReg(0), IndexReg(0), TmpReg(0), Scale(1), Disp(disp),
- Sym(0) {}
-
- unsigned getBaseReg() { return BaseReg; }
- unsigned getIndexReg() { return IndexReg; }
- unsigned getScale() { return Scale; }
- const MCExpr *getSym() { return Sym; }
- StringRef getSymName() { return SymName; }
- int64_t getImmDisp() { return Disp + IC.execute(); }
- bool isValidEndState() { return State == IBES_RBRAC; }
-
- void onPlus() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_INTEGER:
- case IBES_RPAREN:
- State = IBES_PLUS;
- IC.pushOperator(IC_PLUS);
- break;
- case IBES_REGISTER:
- State = IBES_PLUS;
- // If we already have a BaseReg, then assume this is the IndexReg with a
- // scale of 1.
- if (!BaseReg) {
- BaseReg = TmpReg;
- } else {
- assert (!IndexReg && "BaseReg/IndexReg already set!");
- IndexReg = TmpReg;
- Scale = 1;
- }
- IC.pushOperator(IC_PLUS);
- break;
- }
- }
- void onMinus() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_PLUS:
- case IBES_LPAREN:
- IC.pushOperand(IC_IMM);
- case IBES_INTEGER:
- case IBES_RPAREN:
- State = IBES_MINUS;
- IC.pushOperator(IC_MINUS);
- break;
- case IBES_REGISTER:
- State = IBES_MINUS;
- // If we already have a BaseReg, then assume this is the IndexReg with a
- // scale of 1.
- if (!BaseReg) {
- BaseReg = TmpReg;
- } else {
- assert (!IndexReg && "BaseReg/IndexReg already set!");
- IndexReg = TmpReg;
- Scale = 1;
- }
- IC.pushOperator(IC_MINUS);
- break;
- }
- }
- void onRegister(unsigned Reg) {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_PLUS:
- case IBES_LPAREN:
- State = IBES_REGISTER;
- TmpReg = Reg;
- IC.pushOperand(IC_REGISTER);
- break;
- case IBES_INTEGER_STAR:
- assert (!IndexReg && "IndexReg already set!");
- State = IBES_INTEGER;
- IndexReg = Reg;
- Scale = IC.popOperand();
- IC.pushOperand(IC_IMM);
- IC.popOperator();
- break;
- }
- }
- void onDispExpr(const MCExpr *SymRef, StringRef SymRefName) {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_PLUS:
- case IBES_MINUS:
- State = IBES_INTEGER;
- Sym = SymRef;
- SymName = SymRefName;
- IC.pushOperand(IC_IMM);
- break;
- }
- }
- void onInteger(int64_t TmpInt) {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_PLUS:
- case IBES_MINUS:
- case IBES_MULTIPLY:
- case IBES_DIVIDE:
- case IBES_LPAREN:
- case IBES_INTEGER_STAR:
- State = IBES_INTEGER;
- IC.pushOperand(IC_IMM, TmpInt);
- break;
- case IBES_REGISTER_STAR:
- assert (!IndexReg && "IndexReg already set!");
- State = IBES_INTEGER;
- IndexReg = TmpReg;
- Scale = TmpInt;
- IC.popOperator();
- break;
- }
- }
- void onStar() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_INTEGER:
- State = IBES_INTEGER_STAR;
- IC.pushOperator(IC_MULTIPLY);
- break;
- case IBES_REGISTER:
- State = IBES_REGISTER_STAR;
- IC.pushOperator(IC_MULTIPLY);
- break;
- case IBES_RPAREN:
- State = IBES_MULTIPLY;
- IC.pushOperator(IC_MULTIPLY);
- break;
- }
- }
- void onDivide() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_INTEGER:
- State = IBES_DIVIDE;
- IC.pushOperator(IC_DIVIDE);
- break;
- }
- }
- void onLBrac() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_RBRAC:
- State = IBES_PLUS;
- IC.pushOperator(IC_PLUS);
- break;
- }
- }
- void onRBrac() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_RPAREN:
- case IBES_INTEGER:
- State = IBES_RBRAC;
- break;
- case IBES_REGISTER:
- State = IBES_RBRAC;
- // If we already have a BaseReg, then assume this is the IndexReg with a
- // scale of 1.
- if (!BaseReg) {
- BaseReg = TmpReg;
- } else {
- assert (!IndexReg && "BaseReg/IndexReg already set!");
- IndexReg = TmpReg;
- Scale = 1;
- }
- break;
- }
- }
- void onLParen() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_PLUS:
- case IBES_MINUS:
- case IBES_MULTIPLY:
- case IBES_DIVIDE:
- case IBES_INTEGER_STAR:
- case IBES_LPAREN:
- State = IBES_LPAREN;
- IC.pushOperator(IC_LPAREN);
- break;
- }
- }
- void onRParen() {
- switch (State) {
- default:
- State = IBES_ERROR;
- break;
- case IBES_REGISTER:
- case IBES_INTEGER:
- case IBES_PLUS:
- case IBES_MINUS:
- case IBES_MULTIPLY:
- case IBES_DIVIDE:
- case IBES_RPAREN:
- State = IBES_RPAREN;
- IC.pushOperator(IC_RPAREN);
- break;
- }
- }
-};
-
X86Operand *
X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
unsigned BaseReg, unsigned IndexReg,
@@ -1182,21 +1184,11 @@ RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
}
}
-X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
- uint64_t ImmDisp,
- unsigned Size) {
+X86Operand *
+X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
const AsmToken &Tok = Parser.getTok();
- SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
- if (getLexer().isNot(AsmToken::LBrac))
- return ErrorOperand(BracLoc, "Expected '[' token!");
- Parser.Lex(); // Eat '['
- SMLoc StartInBrac = Tok.getLoc();
- // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
- // may have already parsed an immediate displacement before the bracketed
- // expression.
bool Done = false;
- IntelBracExprStateMachine SM(Parser, ImmDisp);
while (!Done) {
bool UpdateLocLex = true;
@@ -1253,6 +1245,28 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
Parser.Lex(); // Consume the token.
}
}
+ return 0;
+}
+
+X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
+ uint64_t ImmDisp,
+ unsigned Size) {
+ const AsmToken &Tok = Parser.getTok();
+ SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
+ if (getLexer().isNot(AsmToken::LBrac))
+ return ErrorOperand(BracLoc, "Expected '[' token!");
+ Parser.Lex(); // Eat '['
+
+ SMLoc StartInBrac = Tok.getLoc();
+ // Parse [ Symbol + ImmDisp ] and [ BaseReg + Scale*IndexReg + ImmDisp ]. We
+ // may have already parsed an immediate displacement before the bracketed
+ // expression.
+
+ StringRef SymName;
+
+ IntelExprStateMachine SM(ImmDisp);
+ if (X86Operand *Err = ParseIntelExpression(SM, End))
+ return Err;
const MCExpr *Disp;
if (const MCExpr *Sym = SM.getSym()) {
@@ -1260,11 +1274,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
Disp = Sym;
if (isParsingInlineAsm())
RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
- ImmDisp, SM.getImmDisp(), BracLoc, StartInBrac,
+ ImmDisp, SM.getImm(), BracLoc, StartInBrac,
End);
} else {
// An immediate displacement only.
- Disp = MCConstantExpr::Create(SM.getImmDisp(), getContext());
+ Disp = MCConstantExpr::Create(SM.getImm(), getContext());
}
// Parse the dot operator (e.g., [ebx].foo.bar).