From 9ad76aac5a5f2ac50d4e12ce1f4c08056f5b0946 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 14 Nov 2017 20:49:34 +0000 Subject: Merging r315310: ------------------------------------------------------------------------ r315310 | sdardis | 2017-10-10 06:34:45 -0700 (Tue, 10 Oct 2017) | 22 lines [mips] Partially fix PR34391 Previously, the parsing of the 'subu $reg, ($reg,) imm' relied on a parser which also rendered the operand to the instruction. In some cases the general parser could construct an MCExpr which was not a MCConstantExpr which MipsAsmParser was expecting. Address this by altering the special handling to cope with unexpected inputs and fine-tune the handling of cases where an register name that is not available in the current ABI is regarded as not a match for the custom parser but also not as an outright error. Also enforces the binutils restriction that only constants are accepted. This partially resolves PR34391. Thanks to Ed Maste for reporting the issue! Reviewers: nitesh.jain, arichardson Differential Revision: https://reviews.llvm.org/D37476 ------------------------------------------------------------------------ llvm-svn: 318192 --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 15 ++++++--- .../MC/Mips/macro-aliases-invalid-wrong-error.s | 38 ++++++++++++++++++++++ llvm/test/MC/Mips/macro-aliases.s | 35 ++++++++++++++++++++ 3 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 llvm/test/MC/Mips/macro-aliases-invalid-wrong-error.s create mode 100644 llvm/test/MC/Mips/macro-aliases.s diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e12188e70602..f75d23fe6a92 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -5793,14 +5793,21 @@ OperandMatchResultTy MipsAsmParser::parseInvNum(OperandVector &Operands) { MCAsmParser &Parser = getParser(); const MCExpr *IdVal; - // If the first token is '$' we may have register operand. - if (Parser.getTok().is(AsmToken::Dollar)) - return MatchOperand_NoMatch; + // If the first token is '$' we may have register operand. We have to reject + // cases where it is not a register. Complicating the matter is that + // register names are not reserved across all ABIs. + // Peek past the dollar to see if it's a register name for this ABI. SMLoc S = Parser.getTok().getLoc(); + if (Parser.getTok().is(AsmToken::Dollar)) { + return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1 + ? MatchOperand_ParseFail + : MatchOperand_NoMatch; + } if (getParser().parseExpression(IdVal)) return MatchOperand_ParseFail; const MCConstantExpr *MCE = dyn_cast(IdVal); - assert(MCE && "Unexpected MCExpr type."); + if (!MCE) + return MatchOperand_NoMatch; int64_t Val = MCE->getValue(); SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(MipsOperand::CreateImm( diff --git a/llvm/test/MC/Mips/macro-aliases-invalid-wrong-error.s b/llvm/test/MC/Mips/macro-aliases-invalid-wrong-error.s new file mode 100644 index 000000000000..b87646d0b09a --- /dev/null +++ b/llvm/test/MC/Mips/macro-aliases-invalid-wrong-error.s @@ -0,0 +1,38 @@ +# RUN: not llvm-mc -arch=mips %s 2>%t1 +# RUN: FileCheck --check-prefix=O32 %s < %t1 + +# RUN: not llvm-mc -arch=mips64 %s 2>%t1 +# RUN: FileCheck --check-prefix=N64 %s < %t1 + +# Check that subu only rejects any non-constant values. + +.globl end + subu $4, $4, %lo($start) # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $4, $start # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $a4, $a4 # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $4, %hi(end) # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $4, end + 4 # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $4, end # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $4, sp # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + + subu $4, %lo($start) # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $start # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, $a4 # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, %hi(end) # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, end + 4 # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, end # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + subu $4, sp # O32: [[@LINE]]:{{[0-9]+}}: error: unexpected token in argument list + # N64: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list + +$start: diff --git a/llvm/test/MC/Mips/macro-aliases.s b/llvm/test/MC/Mips/macro-aliases.s new file mode 100644 index 000000000000..daa1d8b2437c --- /dev/null +++ b/llvm/test/MC/Mips/macro-aliases.s @@ -0,0 +1,35 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips32r2 %s -show-inst | FileCheck %s + +# Test that subu accepts constant operands and inverts them when +# rendering the operand. + + subu $4, $4, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $gp, $gp, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $sp, $sp, 4 # CHECK: ADDiu + # CHECK; Imm:-4 + subu $4, $4, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $gp, $gp, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $sp, $sp, -4 # CHECK: ADDiu + # CHECK; Imm:4 + subu $sp, $sp, -(4 + 4) # CHECK: ADDiu + # CHECK: Imm:8 + + subu $4, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $gp, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $sp, 8 # CHECK: ADDiu + # CHECK; Imm:-8 + subu $4, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $gp, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $sp, -8 # CHECK: ADDiu + # CHECK; Imm:8 + subu $sp, -(4 + 4) # CHECK: ADDiu + # CHECK: Imm:8 + -- cgit v1.2.3