Update the X86 assembler for .intel_syntax to accept

the | and & bitwise operators.

rdar://15570412


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kevin Enderby 2014-01-15 19:05:24 +00:00
parent 03f1cb72a4
commit 96f3b25e8a
2 changed files with 81 additions and 7 deletions

View File

@ -35,12 +35,14 @@ namespace {
struct X86Operand; struct X86Operand;
static const char OpPrecedence[] = { static const char OpPrecedence[] = {
0, // IC_PLUS 0, // IC_OR
0, // IC_MINUS 1, // IC_AND
1, // IC_MULTIPLY 2, // IC_PLUS
1, // IC_DIVIDE 2, // IC_MINUS
2, // IC_RPAREN 3, // IC_MULTIPLY
3, // IC_LPAREN 3, // IC_DIVIDE
4, // IC_RPAREN
5, // IC_LPAREN
0, // IC_IMM 0, // IC_IMM
0 // IC_REGISTER 0 // IC_REGISTER
}; };
@ -57,7 +59,9 @@ private:
} }
enum InfixCalculatorTok { enum InfixCalculatorTok {
IC_PLUS = 0, IC_OR = 0,
IC_AND,
IC_PLUS,
IC_MINUS, IC_MINUS,
IC_MULTIPLY, IC_MULTIPLY,
IC_DIVIDE, IC_DIVIDE,
@ -182,6 +186,18 @@ 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_OR:
assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
"Or 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:
assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
"And operation with an immediate and a register!");
Val = Op1.second & Op2.second;
OperandStack.push_back(std::make_pair(IC_IMM, Val));
break;
} }
} }
} }
@ -191,6 +207,8 @@ private:
}; };
enum IntelExprState { enum IntelExprState {
IES_OR,
IES_AND,
IES_PLUS, IES_PLUS,
IES_MINUS, IES_MINUS,
IES_MULTIPLY, IES_MULTIPLY,
@ -237,6 +255,36 @@ private:
return Info; return Info;
} }
void onOr() {
IntelExprState CurrState = State;
switch (State) {
default:
State = IES_ERROR;
break;
case IES_INTEGER:
case IES_RPAREN:
case IES_REGISTER:
State = IES_OR;
IC.pushOperator(IC_OR);
break;
}
PrevState = CurrState;
}
void onAnd() {
IntelExprState CurrState = State;
switch (State) {
default:
State = IES_ERROR;
break;
case IES_INTEGER:
case IES_RPAREN:
case IES_REGISTER:
State = IES_AND;
IC.pushOperator(IC_AND);
break;
}
PrevState = CurrState;
}
void onPlus() { void onPlus() {
IntelExprState CurrState = State; IntelExprState CurrState = State;
switch (State) { switch (State) {
@ -351,6 +399,8 @@ private:
break; break;
case IES_PLUS: case IES_PLUS:
case IES_MINUS: case IES_MINUS:
case IES_OR:
case IES_AND:
case IES_DIVIDE: case IES_DIVIDE:
case IES_MULTIPLY: case IES_MULTIPLY:
case IES_LPAREN: case IES_LPAREN:
@ -363,6 +413,7 @@ private:
// Get the scale and replace the 'Register * Scale' with '0'. // Get the scale and replace the 'Register * Scale' with '0'.
IC.popOperator(); IC.popOperator();
} else if ((PrevState == IES_PLUS || PrevState == IES_MINUS || } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
PrevState == IES_OR || PrevState == IES_AND ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC) && PrevState == IES_LPAREN || PrevState == IES_LBRAC) &&
CurrState == IES_MINUS) { CurrState == IES_MINUS) {
@ -448,11 +499,14 @@ private:
break; break;
case IES_PLUS: case IES_PLUS:
case IES_MINUS: case IES_MINUS:
case IES_OR:
case IES_AND:
case IES_MULTIPLY: case IES_MULTIPLY:
case IES_DIVIDE: case IES_DIVIDE:
case IES_LPAREN: case IES_LPAREN:
// FIXME: We don't handle this type of unary minus, yet. // FIXME: We don't handle this type of unary minus, yet.
if ((PrevState == IES_PLUS || PrevState == IES_MINUS || if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
PrevState == IES_OR || PrevState == IES_AND ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC) && PrevState == IES_LPAREN || PrevState == IES_LBRAC) &&
CurrState == IES_MINUS) { CurrState == IES_MINUS) {
@ -1379,6 +1433,8 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
case AsmToken::Minus: SM.onMinus(); break; case AsmToken::Minus: SM.onMinus(); break;
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::Amp: SM.onAnd(); break;
case AsmToken::LBrac: SM.onLBrac(); break; case AsmToken::LBrac: SM.onLBrac(); break;
case AsmToken::RBrac: SM.onRBrac(); break; case AsmToken::RBrac: SM.onRBrac(); break;
case AsmToken::LParen: SM.onLParen(); break; case AsmToken::LParen: SM.onLParen(); break;

View File

@ -0,0 +1,18 @@
// RUN: llvm-mc -triple x86_64-unknown-unknown -x86-asm-syntax=att %s | FileCheck %s
.intel_syntax
// CHECK: andl $3, %ecx
and ecx, 1+2
// CHECK: andl $3, %ecx
and ecx, 1|2
// CHECK: andl $3, %ecx
and ecx, 1*3
// CHECK: andl $1, %ecx
and ecx, 1&3
// CHECK: andl $0, %ecx
and ecx, (1&2)
// CHECK: andl $3, %ecx
and ecx, ((1)|2)
// CHECK: andl $1, %ecx
and ecx, 1&2+3