mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
[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:
parent
7e5d54c320
commit
8ccacf788a
@ -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).
|
||||
|
Loading…
Reference in New Issue
Block a user