From 8ccacf788aeb3834ba9b6a2dc4f524fe42c55076 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 16 Apr 2013 18:15:40 +0000 Subject: [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 --- lib/Target/X86/AsmParser/X86AsmParser.cpp | 824 +++++++++++++++--------------- 1 file changed, 419 insertions(+), 405 deletions(-) (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp') 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 InfixOperatorStack; + SmallVector 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 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 InfixOperatorStack; - SmallVector 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 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 *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). -- cgit v1.2.3