From b08deab89592720d68c8520fb00f2a9b400d52e3 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 6 Nov 2015 12:11:03 +0000 Subject: [PATCH] [mips][ias] Range check uimmz operands. Reviewers: vkalintiris Subscribers: dsanders, atanasyan, llvm-commits Differential Revision: http://reviews.llvm.org/D14013 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252294 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 27 +++++++++++++++++++-- lib/Target/Mips/MipsInstrInfo.td | 9 +++++++ test/MC/Mips/msa/invalid-64.s | 11 +++++++++ test/MC/Mips/msa/invalid.s | 11 +++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 test/MC/Mips/msa/invalid-64.s create mode 100644 test/MC/Mips/msa/invalid.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 78c3e224a00..09ae6a5d43c 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -383,7 +383,7 @@ class MipsAsmParser : public MCTargetAsmParser { public: enum MipsMatchResultTy { - Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY + Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -894,6 +894,13 @@ public: Inst.addOperand(MCOperand::createReg(getHWRegsReg())); } + template + void addConstantUImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + uint64_t Imm = getConstantImm() & ((1 << Bits) - 1); + Inst.addOperand(MCOperand::createImm(Imm)); + } + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCExpr *Expr = getImm(); @@ -953,6 +960,9 @@ public: bool isConstantImm() const { return isImm() && dyn_cast(getImm()); } + bool isConstantImmz() const { + return isConstantImm() && getConstantImm() == 0; + } template bool isUImm() const { return isImm() && isConstantImm() && isUInt(getConstantImm()); } @@ -3234,6 +3244,17 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { return Match_Success; } +static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, + uint64_t ErrorInfo) { + if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { + SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc(); + if (ErrorLoc == SMLoc()) + return Loc; + return ErrorLoc; + } + return Loc; +} + bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, @@ -3262,7 +3283,7 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); - ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); + ErrorLoc = Operands[ErrorInfo]->getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } @@ -3273,6 +3294,8 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "invalid instruction"); case Match_RequiresDifferentSrcAndDst: return Error(IDLoc, "source and destination must be different"); + case Match_Immz: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); } llvm_unreachable("Implement any new match types added!"); diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 4305198e402..0a32967b515 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -381,6 +381,14 @@ include "MipsInstrFormats.td" // Mips Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// +def ConstantImmzAsmOperandClass : AsmOperandClass { + let Name = "ConstantImmz"; + let RenderMethod = "addConstantUImmOperands<1>"; + let PredicateMethod = "isConstantImmz"; + let SuperClasses = []; + let DiagnosticType = "Immz"; +} + def MipsJumpTargetAsmOperand : AsmOperandClass { let Name = "JumpTarget"; let ParserMethod = "parseJumpTarget"; @@ -450,6 +458,7 @@ def simm16_64 : Operand { // Zero def uimmz : Operand { let PrintMethod = "printUnsignedImm"; + let ParserMatchClass = ConstantImmzAsmOperandClass; } // Unsigned Operand diff --git a/test/MC/Mips/msa/invalid-64.s b/test/MC/Mips/msa/invalid-64.s new file mode 100644 index 00000000000..cf1bff5596b --- /dev/null +++ b/test/MC/Mips/msa/invalid-64.s @@ -0,0 +1,11 @@ +# Instructions that are invalid +# +# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+msa \ +# RUN: -show-encoding 2>%t1 +# RUN: FileCheck %s < %t1 + + .set noat + insve.b $w25[3], $w9[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0' diff --git a/test/MC/Mips/msa/invalid.s b/test/MC/Mips/msa/invalid.s new file mode 100644 index 00000000000..cf1bff5596b --- /dev/null +++ b/test/MC/Mips/msa/invalid.s @@ -0,0 +1,11 @@ +# Instructions that are invalid +# +# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+msa \ +# RUN: -show-encoding 2>%t1 +# RUN: FileCheck %s < %t1 + + .set noat + insve.b $w25[3], $w9[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.h $w24[2], $w2[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.w $w0[2], $w13[1] # CHECK: :[[@LINE]]:26: error: expected '0' + insve.d $w3[0], $w18[1] # CHECK: :[[@LINE]]:26: error: expected '0' -- 2.34.1