summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorAsiri Rathnayake <asiri.rathnayake@arm.com>2014-12-04 14:49:07 +0000
committerAsiri Rathnayake <asiri.rathnayake@arm.com>2014-12-04 14:49:07 +0000
commitd33304b3adfea0eb407984cc93a508d252a656e6 (patch)
treeb9f48803c67a954bc9a81e27c2e047da9d6e5b06 /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parentbe8fd3fe28a3a5b7a9f708748e85fa2d16349956 (diff)
downloadbcm5719-llvm-d33304b3adfea0eb407984cc93a508d252a656e6.tar.gz
bcm5719-llvm-d33304b3adfea0eb407984cc93a508d252a656e6.zip
Fix a minor regression introduced in r223113
r223113 added support for ARM modified immediate assembly syntax. That patch has broken support for immediate expressions, as in: add r0, #(4 * 4) It wasn't caught because we don't have any tests for this feature. This patch fixes this regression and adds test cases. llvm-svn: 223366
Diffstat (limited to 'llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 1e661d82dad..4ccadf915cc 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -4419,9 +4419,8 @@ ARMAsmParser::parseModImm(OperandVector &Operands) {
int64_t Imm1, Imm2;
if ((Parser.getTok().isNot(AsmToken::Hash) &&
- Parser.getTok().isNot(AsmToken::Dollar) /* looking for an immediate */ )
- || Lexer.peekTok().is(AsmToken::Colon)
- || Lexer.peekTok().is(AsmToken::LParen) /* avoid complex operands */ )
+ Parser.getTok().isNot(AsmToken::Dollar))
+ || Lexer.peekTok().is(AsmToken::Colon))
return MatchOperand_NoMatch;
SMLoc S = Parser.getTok().getLoc();
@@ -4440,7 +4439,7 @@ ARMAsmParser::parseModImm(OperandVector &Operands) {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
if (CE) {
- // immediate must fit within 32-bits
+ // Immediate must fit within 32-bits
Imm1 = CE->getValue();
if (Imm1 < INT32_MIN || Imm1 > UINT32_MAX) {
Error(Sx1, "immediate operand must be representable with 32 bits");
@@ -4455,19 +4454,30 @@ ARMAsmParser::parseModImm(OperandVector &Operands) {
Sx1, Ex1));
return MatchOperand_Success;
}
- } else {
- Error(Sx1, "constant expression expected");
- return MatchOperand_ParseFail;
- }
- if (Parser.getTok().isNot(AsmToken::Comma)) {
- // Consider [mov r0, #-10], which is aliased with mvn. We cannot fail
- // the parse here.
+ // We have parsed an immediate which is not for us, fallback to a plain
+ // immediate. This can happen for instruction aliases. For an example,
+ // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
+ // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
+ // instruction with a mod_imm operand. The alias is defined such that the
+ // parser method is shared, that's why we have to do this here.
+ if (Parser.getTok().is(AsmToken::EndOfStatement)) {
+ Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
+ return MatchOperand_Success;
+ }
+ } else {
+ // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
+ // MCFixup). Fallback to a plain immediate.
Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
return MatchOperand_Success;
}
// From this point onward, we expect the input to be a (#bits, #rot) pair
+ if (Parser.getTok().isNot(AsmToken::Comma)) {
+ Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]");
+ return MatchOperand_ParseFail;
+ }
+
if (Imm1 & ~0xFF) {
Error(Sx1, "immediate operand must a number in the range [0, 255]");
return MatchOperand_ParseFail;
OpenPOWER on IntegriCloud