summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 78c3e224a00..09ae6a5d43c 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/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 <unsigned Bits>
+ 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<MCConstantExpr>(getImm());
}
+ bool isConstantImmz() const {
+ return isConstantImm() && getConstantImm() == 0;
+ }
template <unsigned Bits> bool isUImm() const {
return isImm() && isConstantImm() && isUInt<Bits>(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!");
OpenPOWER on IntegriCloud