From 13cef35cbae9824b7a96a717121c9e775863f168 Mon Sep 17 00:00:00 2001 From: Asiri Rathnayake Date: Thu, 4 Dec 2014 19:34:59 +0000 Subject: [PATCH] Fix yet another unseen regression caused by r223113 r223113 added support for ARM modified immediate assembly syntax. Which assumes all immediate operands are prefixed with a '#'. This assumption is wrong as per the ARMARM - which recommends that all '#' characters be treated optional. The current patch fixes this regression and adds a test case. A follow-up patch will expand the test coverage to other instructions. llvm-svn: 223381 --- llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 40 +++++++++++++++++--------- llvm/test/MC/ARM/basic-arm-instructions.s | 6 ++++ llvm/test/MC/ARM/ldr-pseudo-parse-errors.s | 2 +- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 4ccadf9..f291fe4 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4418,15 +4418,31 @@ ARMAsmParser::parseModImm(OperandVector &Operands) { MCAsmLexer &Lexer = getLexer(); int64_t Imm1, Imm2; - if ((Parser.getTok().isNot(AsmToken::Hash) && - Parser.getTok().isNot(AsmToken::Dollar)) - || Lexer.peekTok().is(AsmToken::Colon)) + SMLoc S = Parser.getTok().getLoc(); + + // 1) A mod_imm operand can appear in the place of a register name: + // add r0, #mod_imm + // add r0, r0, #mod_imm + // to correctly handle the latter, we bail out as soon as we see an + // identifier. + // + // 2) Similarly, we do not want to parse into complex operands: + // mov r0, #mod_imm + // mov r0, :lower16:(_foo) + if (Parser.getTok().is(AsmToken::Identifier) || + Parser.getTok().is(AsmToken::Colon)) return MatchOperand_NoMatch; - SMLoc S = Parser.getTok().getLoc(); + // Hash (dollar) is optional as per the ARMARM + if (Parser.getTok().is(AsmToken::Hash) || + Parser.getTok().is(AsmToken::Dollar)) { + // Avoid parsing into complex operands (#:) + if (Lexer.peekTok().is(AsmToken::Colon)) + return MatchOperand_NoMatch; - // Eat the hash (or dollar) - Parser.Lex(); + // Eat the hash (dollar) + Parser.Lex(); + } SMLoc Sx1, Ex1; Sx1 = Parser.getTok().getLoc(); @@ -4483,12 +4499,6 @@ ARMAsmParser::parseModImm(OperandVector &Operands) { return MatchOperand_ParseFail; } - if (Lexer.peekTok().isNot(AsmToken::Hash) && - Lexer.peekTok().isNot(AsmToken::Dollar)) { - Error(Lexer.peekTok().getLoc(), "immediate operand expected"); - return MatchOperand_ParseFail; - } - // Eat the comma Parser.Lex(); @@ -4496,8 +4506,10 @@ ARMAsmParser::parseModImm(OperandVector &Operands) { SMLoc Sx2, Ex2; Sx2 = Parser.getTok().getLoc(); - // Eat the hash (or dollar) - Parser.Lex(); + // Eat the optional hash (dollar) + if (Parser.getTok().is(AsmToken::Hash) || + Parser.getTok().is(AsmToken::Dollar)) + Parser.Lex(); const MCExpr *Imm2Exp; if (getParser().parseExpression(Imm2Exp, Ex2)) { diff --git a/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s index 878948a..b15701f 100644 --- a/llvm/test/MC/ARM/basic-arm-instructions.s +++ b/llvm/test/MC/ARM/basic-arm-instructions.s @@ -16,6 +16,9 @@ _func: @ ADC (immediate) @------------------------------------------------------------------------------ adc r1, r2, #0xf + adc r1, r2, $0xf + adc r1, r2, 0xf + adc r1, r2, 15 adc r7, r8, #42, #2 adc r7, r8, #-2147483638 adc r7, r8, #40, #2 @@ -34,6 +37,9 @@ _func: adceq r1, r2, #0xf00 @ CHECK: adc r1, r2, #15 @ encoding: [0x0f,0x10,0xa2,0xe2] +@ CHECK: adc r1, r2, #15 @ encoding: [0x0f,0x10,0xa2,0xe2] +@ CHECK: adc r1, r2, #15 @ encoding: [0x0f,0x10,0xa2,0xe2] +@ CHECK: adc r1, r2, #15 @ encoding: [0x0f,0x10,0xa2,0xe2] @ CHECK: adc r7, r8, #-2147483638 @ encoding: [0x2a,0x71,0xa8,0xe2] @ CHECK: adc r7, r8, #-2147483638 @ encoding: [0x2a,0x71,0xa8,0xe2] @ CHECK: adc r7, r8, #40, #2 @ encoding: [0x28,0x71,0xa8,0xe2] diff --git a/llvm/test/MC/ARM/ldr-pseudo-parse-errors.s b/llvm/test/MC/ARM/ldr-pseudo-parse-errors.s index 2e6114d..2516239 100644 --- a/llvm/test/MC/ARM/ldr-pseudo-parse-errors.s +++ b/llvm/test/MC/ARM/ldr-pseudo-parse-errors.s @@ -4,7 +4,7 @@ .text bar: mov r0, =0x101 -@ CHECK: error: unexpected token in operand +@ CHECK: error: unknown token in expression @ CHECK: mov r0, =0x101 @ CHECK: ^ -- 2.7.4