Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -383,7 +383,7 @@ 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 @@ 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 @@ bool isConstantImm() const { return isImm() && dyn_cast(getImm()); } + bool isConstantImmz() const { + return isConstantImm() && getConstantImm() == 0; + } template bool isUImm() const { return isImm() && isConstantImm() && isUInt(getConstantImm()); } @@ -3228,6 +3238,17 @@ return Match_Success; } +static SMLoc RefineErrorLoc(SMLoc Loc, OperandVector &Operands, + uint64_t &ErrorInfo) { + if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { + SMLoc ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); + if (ErrorLoc == SMLoc()) + return Loc; + return ErrorLoc; + } + return Loc; +} + bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, @@ -3267,6 +3288,8 @@ 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!"); Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -378,6 +378,14 @@ // 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"; @@ -447,6 +455,7 @@ // Zero def uimmz : Operand { let PrintMethod = "printUnsignedImm"; + let ParserMatchClass = ConstantImmzAsmOperandClass; } // Unsigned Operand Index: test/MC/Mips/msa/invalid-64.s =================================================================== --- /dev/null +++ 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' Index: test/MC/Mips/msa/invalid.s =================================================================== --- /dev/null +++ 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'