diff options
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; |