Add support for parsing the XOR operator in Intel syntax inline assembly.

Differential Revision: http://reviews.llvm.org/D10385
Patch by marina.yatsina@intel.com


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239695 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Kuperstein 2015-06-14 12:59:45 +00:00
parent 6ea3ad7e6e
commit 3dd555171e
2 changed files with 41 additions and 12 deletions

View File

@ -42,15 +42,16 @@ namespace {
static const char OpPrecedence[] = { static const char OpPrecedence[] = {
0, // IC_OR 0, // IC_OR
1, // IC_AND 1, // IC_XOR
2, // IC_LSHIFT 2, // IC_AND
2, // IC_RSHIFT 3, // IC_LSHIFT
3, // IC_PLUS 3, // IC_RSHIFT
3, // IC_MINUS 4, // IC_PLUS
4, // IC_MULTIPLY 4, // IC_MINUS
4, // IC_DIVIDE 5, // IC_MULTIPLY
5, // IC_RPAREN 5, // IC_DIVIDE
6, // IC_LPAREN 6, // IC_RPAREN
7, // IC_LPAREN
0, // IC_IMM 0, // IC_IMM
0 // IC_REGISTER 0 // IC_REGISTER
}; };
@ -70,6 +71,7 @@ private:
enum InfixCalculatorTok { enum InfixCalculatorTok {
IC_OR = 0, IC_OR = 0,
IC_XOR,
IC_AND, IC_AND,
IC_LSHIFT, IC_LSHIFT,
IC_RSHIFT, IC_RSHIFT,
@ -204,6 +206,12 @@ private:
Val = Op1.second | Op2.second; Val = Op1.second | Op2.second;
OperandStack.push_back(std::make_pair(IC_IMM, Val)); OperandStack.push_back(std::make_pair(IC_IMM, Val));
break; break;
case IC_XOR:
assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Xor operation with an immediate and a register!");
Val = Op1.second ^ Op2.second;
OperandStack.push_back(std::make_pair(IC_IMM, Val));
break;
case IC_AND: case IC_AND:
assert (Op1.first == IC_IMM && Op2.first == IC_IMM && assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
"And operation with an immediate and a register!"); "And operation with an immediate and a register!");
@ -232,6 +240,7 @@ private:
enum IntelExprState { enum IntelExprState {
IES_OR, IES_OR,
IES_XOR,
IES_AND, IES_AND,
IES_LSHIFT, IES_LSHIFT,
IES_RSHIFT, IES_RSHIFT,
@ -297,6 +306,21 @@ private:
} }
PrevState = CurrState; PrevState = CurrState;
} }
void onXor() {
IntelExprState CurrState = State;
switch (State) {
default:
State = IES_ERROR;
break;
case IES_INTEGER:
case IES_RPAREN:
case IES_REGISTER:
State = IES_XOR;
IC.pushOperator(IC_XOR);
break;
}
PrevState = CurrState;
}
void onAnd() { void onAnd() {
IntelExprState CurrState = State; IntelExprState CurrState = State;
switch (State) { switch (State) {
@ -473,6 +497,7 @@ private:
case IES_MINUS: case IES_MINUS:
case IES_NOT: case IES_NOT:
case IES_OR: case IES_OR:
case IES_XOR:
case IES_AND: case IES_AND:
case IES_LSHIFT: case IES_LSHIFT:
case IES_RSHIFT: case IES_RSHIFT:
@ -496,7 +521,7 @@ private:
PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC || PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
PrevState == IES_NOT) && PrevState == IES_NOT || PrevState == IES_XOR) &&
CurrState == IES_MINUS) { CurrState == IES_MINUS) {
// Unary minus. No need to pop the minus operand because it was never // Unary minus. No need to pop the minus operand because it was never
// pushed. // pushed.
@ -506,7 +531,7 @@ private:
PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC || PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
PrevState == IES_NOT) && PrevState == IES_NOT || PrevState == IES_XOR) &&
CurrState == IES_NOT) { CurrState == IES_NOT) {
// Unary not. No need to pop the not operand because it was never // Unary not. No need to pop the not operand because it was never
// pushed. // pushed.
@ -593,6 +618,7 @@ private:
case IES_MINUS: case IES_MINUS:
case IES_NOT: case IES_NOT:
case IES_OR: case IES_OR:
case IES_XOR:
case IES_AND: case IES_AND:
case IES_LSHIFT: case IES_LSHIFT:
case IES_RSHIFT: case IES_RSHIFT:
@ -605,7 +631,7 @@ private:
PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC || PrevState == IES_LPAREN || PrevState == IES_LBRAC ||
PrevState == IES_NOT) && PrevState == IES_NOT || PrevState == IES_XOR) &&
(CurrState == IES_MINUS || CurrState == IES_NOT)) { (CurrState == IES_MINUS || CurrState == IES_NOT)) {
State = IES_ERROR; State = IES_ERROR;
break; break;
@ -1217,6 +1243,7 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
case AsmToken::Star: SM.onStar(); break; case AsmToken::Star: SM.onStar(); break;
case AsmToken::Slash: SM.onDivide(); break; case AsmToken::Slash: SM.onDivide(); break;
case AsmToken::Pipe: SM.onOr(); break; case AsmToken::Pipe: SM.onOr(); break;
case AsmToken::Caret: SM.onXor(); break;
case AsmToken::Amp: SM.onAnd(); break; case AsmToken::Amp: SM.onAnd(); break;
case AsmToken::LessLess: case AsmToken::LessLess:
SM.onLShift(); break; SM.onLShift(); break;

View File

@ -20,3 +20,5 @@
add eax, 9876 >> 1 add eax, 9876 >> 1
// CHECK: addl $19752, %eax // CHECK: addl $19752, %eax
add eax, 9876 << 1 add eax, 9876 << 1
// CHECK: addl $5, %eax
add eax, 6 ^ 3