summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2016-02-01 15:13:31 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2016-02-01 15:13:31 +0000
commitf8bb23e50923e550de71af44ead47cf37b486deb (patch)
treee6f0e05af71e3a2ce6ebd0d524573b671884b62f /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
parent7e7b7b2def1fa3efb55a7af294a92a4723263f77 (diff)
downloadbcm5719-llvm-f8bb23e50923e550de71af44ead47cf37b486deb.tar.gz
bcm5719-llvm-f8bb23e50923e550de71af44ead47cf37b486deb.zip
[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
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp27
1 files changed, 21 insertions, 6 deletions
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 <unsigned Bits>
+ void addUImmOperands(MCInst &Inst, unsigned N) const {
+ if (isImm() && !isConstantImm()) {
+ addExpr(Inst, getImm());
+ return;
+ }
+ addConstantUImmOperands<Bits, 0, 0>(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 <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
}
+ template <unsigned Bits> bool isUImm() const {
+ return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
+ }
+ template <unsigned Bits> bool isAnyImm() const {
+ return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
+ isUInt<Bits>(getConstantImm()))
+ : isImm();
+ }
template <unsigned Bits> bool isConstantSImm() const {
return isConstantImm() && isInt<Bits>(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!");
OpenPOWER on IntegriCloud