From f8bb23e50923e550de71af44ead47cf37b486deb Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Mon, 1 Feb 2016 15:13:31 +0000 Subject: [mips] Range check uimm16 and fix several bugs this revealed. Summary: The bugs were: * teq and similar take 4-bit unsigned immediates on microMIPS. * teqi and similar have side-effects like teq do. * shll_s.w and shra_r.w take 5-bit unsigned immediates. * The various DSP ext* instructions take a 5-bit immediate. * repl.qh takes an 8-bit unsigned immediate. * repl.ph takes a 10-bit unsigned immediate. * rddsp/wrdsp take a 10-bit unsigned immediate. * teqi and similar take signed 16-bit immediates (10-bit for microMIPS). * Out-of-range immediate macros for or/xor take a simm32/simm64 depending on architecture. I'll fix the simm64 case properly when I reach simm32. lui is a bit more lenient than GAS and accepts signed immediates in addition to unsigned. This is because MipsMCExpr can produce signed values when constant folding and it currently lacks a way of knowing it should fold to an unsigned value. Reviewers: vkalintiris Subscribers: dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D15446 llvm-svn: 259360 --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 27 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp') diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 192b3444936..7e53e4b1cc8 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -941,6 +941,15 @@ public: Inst.addOperand(MCOperand::createImm(Imm)); } + template + void addUImmOperands(MCInst &Inst, unsigned N) const { + if (isImm() && !isConstantImm()) { + addExpr(Inst, getImm()); + return; + } + addConstantUImmOperands(Inst, N); + } + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCExpr *Expr = getImm(); @@ -1006,6 +1015,14 @@ public: template bool isConstantUImm() const { return isConstantImm() && isUInt(getConstantImm() - Offset); } + template bool isUImm() const { + return isConstantImm() ? isUInt(getConstantImm()) : isImm(); + } + template bool isAnyImm() const { + return isConstantImm() ? (isInt(getConstantImm()) || + isUInt(getConstantImm())) + : isImm(); + } template bool isConstantSImm() const { return isConstantImm() && isInt(getConstantImm()); } @@ -1854,12 +1871,6 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, if (Imm < -1 || Imm > 14) return Error(IDLoc, "immediate operand value out of range"); break; - case Mips::TEQ_MM: - case Mips::TGE_MM: - case Mips::TGEU_MM: - case Mips::TLT_MM: - case Mips::TLTU_MM: - case Mips::TNE_MM: case Mips::SB16_MM: case Mips::SB16_MMR6: Opnd = Inst.getOperand(2); @@ -3700,6 +3711,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_UImm10_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 10-bit unsigned immediate"); + case Match_UImm16: + case Match_UImm16_Relaxed: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 16-bit unsigned immediate"); } llvm_unreachable("Implement any new match types added!"); -- cgit v1.2.3