[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
This commit is contained in:
Chad Rosier 2013-04-16 18:15:40 +00:00
parent 7e5d54c320
commit 8ccacf788a

View File

@ -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).