summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2014-02-06 01:21:15 +0000
committerKevin Enderby <enderby@apple.com>2014-02-06 01:21:15 +0000
commita2f4bb9077c4daff751c25218ef33b946fd21fc2 (patch)
treef87f2629132a713a03a70e4b9ca0abfe2fb86196
parentcc94d006f836f4278e99c998384fad7543ddf7b5 (diff)
downloadllvm-a2f4bb9077c4daff751c25218ef33b946fd21fc2.tar.gz
llvm-a2f4bb9077c4daff751c25218ef33b946fd21fc2.tar.bz2
llvm-a2f4bb9077c4daff751c25218ef33b946fd21fc2.tar.xz
Update the X86 assembler for .intel_syntax to accept
the << and >> bitwise operators. rdar://15975725 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200896 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp70
-rw-r--r--test/MC/X86/intel-syntax-bitwise-ops.s4
2 files changed, 68 insertions, 6 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 296416ec0a..ebad87aada 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -37,12 +37,14 @@ struct X86Operand;
static const char OpPrecedence[] = {
0, // IC_OR
1, // IC_AND
- 2, // IC_PLUS
- 2, // IC_MINUS
- 3, // IC_MULTIPLY
- 3, // IC_DIVIDE
- 4, // IC_RPAREN
- 5, // IC_LPAREN
+ 2, // IC_LSHIFT
+ 2, // IC_RSHIFT
+ 3, // IC_PLUS
+ 3, // IC_MINUS
+ 4, // IC_MULTIPLY
+ 4, // IC_DIVIDE
+ 5, // IC_RPAREN
+ 6, // IC_LPAREN
0, // IC_IMM
0 // IC_REGISTER
};
@@ -61,6 +63,8 @@ private:
enum InfixCalculatorTok {
IC_OR = 0,
IC_AND,
+ IC_LSHIFT,
+ IC_RSHIFT,
IC_PLUS,
IC_MINUS,
IC_MULTIPLY,
@@ -198,6 +202,18 @@ private:
Val = Op1.second & Op2.second;
OperandStack.push_back(std::make_pair(IC_IMM, Val));
break;
+ case IC_LSHIFT:
+ assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Left shift operation with an immediate and a register!");
+ Val = Op1.second << Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
+ case IC_RSHIFT:
+ assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
+ "Right shift operation with an immediate and a register!");
+ Val = Op1.second >> Op2.second;
+ OperandStack.push_back(std::make_pair(IC_IMM, Val));
+ break;
}
}
}
@@ -209,6 +225,8 @@ private:
enum IntelExprState {
IES_OR,
IES_AND,
+ IES_LSHIFT,
+ IES_RSHIFT,
IES_PLUS,
IES_MINUS,
IES_MULTIPLY,
@@ -285,6 +303,36 @@ private:
}
PrevState = CurrState;
}
+ void onLShift() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_LSHIFT;
+ IC.pushOperator(IC_LSHIFT);
+ break;
+ }
+ PrevState = CurrState;
+ }
+ void onRShift() {
+ IntelExprState CurrState = State;
+ switch (State) {
+ default:
+ State = IES_ERROR;
+ break;
+ case IES_INTEGER:
+ case IES_RPAREN:
+ case IES_REGISTER:
+ State = IES_RSHIFT;
+ IC.pushOperator(IC_RSHIFT);
+ break;
+ }
+ PrevState = CurrState;
+ }
void onPlus() {
IntelExprState CurrState = State;
switch (State) {
@@ -401,6 +449,8 @@ private:
case IES_MINUS:
case IES_OR:
case IES_AND:
+ case IES_LSHIFT:
+ case IES_RSHIFT:
case IES_DIVIDE:
case IES_MULTIPLY:
case IES_LPAREN:
@@ -418,6 +468,7 @@ private:
IC.popOperator();
} else if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
PrevState == IES_OR || PrevState == IES_AND ||
+ PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC) &&
CurrState == IES_MINUS) {
@@ -506,12 +557,15 @@ private:
case IES_MINUS:
case IES_OR:
case IES_AND:
+ case IES_LSHIFT:
+ case IES_RSHIFT:
case IES_MULTIPLY:
case IES_DIVIDE:
case IES_LPAREN:
// FIXME: We don't handle this type of unary minus, yet.
if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||
PrevState == IES_OR || PrevState == IES_AND ||
+ PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||
PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE ||
PrevState == IES_LPAREN || PrevState == IES_LBRAC) &&
CurrState == IES_MINUS) {
@@ -1547,6 +1601,10 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
case AsmToken::Slash: SM.onDivide(); break;
case AsmToken::Pipe: SM.onOr(); break;
case AsmToken::Amp: SM.onAnd(); break;
+ case AsmToken::LessLess:
+ SM.onLShift(); break;
+ case AsmToken::GreaterGreater:
+ SM.onRShift(); break;
case AsmToken::LBrac: SM.onLBrac(); break;
case AsmToken::RBrac: SM.onRBrac(); break;
case AsmToken::LParen: SM.onLParen(); break;
diff --git a/test/MC/X86/intel-syntax-bitwise-ops.s b/test/MC/X86/intel-syntax-bitwise-ops.s
index a38ae85e6e..c9c9b1d17b 100644
--- a/test/MC/X86/intel-syntax-bitwise-ops.s
+++ b/test/MC/X86/intel-syntax-bitwise-ops.s
@@ -16,3 +16,7 @@
and ecx, ((1)|2)
// CHECK: andl $1, %ecx
and ecx, 1&2+3
+// CHECK: addl $4938, %eax
+ add eax, 9876 >> 1
+// CHECK: addl $19752, %eax
+ add eax, 9876 << 1