mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-29 13:29:28 +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 {
|
namespace {
|
||||||
struct X86Operand;
|
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 {
|
class X86AsmParser : public MCTargetAsmParser {
|
||||||
MCSubtargetInfo &STI;
|
MCSubtargetInfo &STI;
|
||||||
MCAsmParser &Parser;
|
MCAsmParser &Parser;
|
||||||
ParseInstructionInfo *InstInfo;
|
ParseInstructionInfo *InstInfo;
|
||||||
private:
|
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; }
|
MCAsmParser &getParser() const { return Parser; }
|
||||||
|
|
||||||
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
|
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
|
||||||
@ -61,6 +453,7 @@ private:
|
|||||||
X86Operand *ParseIntelOperator(unsigned OpKind);
|
X86Operand *ParseIntelOperator(unsigned OpKind);
|
||||||
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
|
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
|
||||||
SMLoc StartLoc);
|
SMLoc StartLoc);
|
||||||
|
X86Operand *ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
|
||||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||||
uint64_t ImmDisp, unsigned Size);
|
uint64_t ImmDisp, unsigned Size);
|
||||||
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
|
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
|
||||||
@ -687,397 +1080,6 @@ static unsigned getIntelMemOperandSize(StringRef OpStr) {
|
|||||||
return Size;
|
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 *
|
X86Operand *
|
||||||
X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
|
X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp,
|
||||||
unsigned BaseReg, unsigned IndexReg,
|
unsigned BaseReg, unsigned IndexReg,
|
||||||
@ -1182,21 +1184,11 @@ RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> *AsmRewrites,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
X86Operand *
|
||||||
uint64_t ImmDisp,
|
X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
|
||||||
unsigned Size) {
|
|
||||||
const AsmToken &Tok = Parser.getTok();
|
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;
|
bool Done = false;
|
||||||
IntelBracExprStateMachine SM(Parser, ImmDisp);
|
|
||||||
while (!Done) {
|
while (!Done) {
|
||||||
bool UpdateLocLex = true;
|
bool UpdateLocLex = true;
|
||||||
|
|
||||||
@ -1253,6 +1245,28 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
|||||||
Parser.Lex(); // Consume the token.
|
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;
|
const MCExpr *Disp;
|
||||||
if (const MCExpr *Sym = SM.getSym()) {
|
if (const MCExpr *Sym = SM.getSym()) {
|
||||||
@ -1260,11 +1274,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
|||||||
Disp = Sym;
|
Disp = Sym;
|
||||||
if (isParsingInlineAsm())
|
if (isParsingInlineAsm())
|
||||||
RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
|
RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(),
|
||||||
ImmDisp, SM.getImmDisp(), BracLoc, StartInBrac,
|
ImmDisp, SM.getImm(), BracLoc, StartInBrac,
|
||||||
End);
|
End);
|
||||||
} else {
|
} else {
|
||||||
// An immediate displacement only.
|
// 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).
|
// Parse the dot operator (e.g., [ebx].foo.bar).
|
||||||
|
Loading…
Reference in New Issue
Block a user