diff options
author | Asiri Rathnayake <asiri.rathnayake@arm.com> | 2014-12-04 14:49:07 +0000 |
---|---|---|
committer | Asiri Rathnayake <asiri.rathnayake@arm.com> | 2014-12-04 14:49:07 +0000 |
commit | d33304b3adfea0eb407984cc93a508d252a656e6 (patch) | |
tree | b9f48803c67a954bc9a81e27c2e047da9d6e5b06 /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | be8fd3fe28a3a5b7a9f708748e85fa2d16349956 (diff) | |
download | bcm5719-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.cpp | 32 |
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; |