summaryrefslogtreecommitdiff
path: root/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
authorZlatko Buljan <Zlatko.Buljan@imgtec.com>2016-05-09 08:07:28 +0000
committerZlatko Buljan <Zlatko.Buljan@imgtec.com>2016-05-09 08:07:28 +0000
commitdc02050702e6bf776bfd95f380e546d7d14ebabf (patch)
tree7a373331ac03ded7613abf17b1b53d91e3cab9cc /lib/Target/Mips/AsmParser/MipsAsmParser.cpp
parentc0fdf88ac7cba96db948838325209dd9ee968166 (diff)
[mips][microMIPS] Implement LWP and SWP instructions
Differential Revision: http://reviews.llvm.org/D10640 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268896 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp33
1 files changed, 26 insertions, 7 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 001a9be332d..1b61535c75a 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1007,9 +1007,19 @@ public:
void addRegPairOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
+ assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
unsigned RegNo = getRegPair();
- Inst.addOperand(MCOperand::createReg(RegNo++));
- Inst.addOperand(MCOperand::createReg(RegNo));
+ AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
+ Inst.addOperand(MCOperand::createReg(
+ RegIdx.RegInfo->getRegClass(
+ AsmParser.getABI().AreGprs64bit()
+ ? Mips::GPR64RegClassID
+ : Mips::GPR32RegClassID).getRegister(RegNo++)));
+ Inst.addOperand(MCOperand::createReg(
+ RegIdx.RegInfo->getRegClass(
+ AsmParser.getABI().AreGprs64bit()
+ ? Mips::GPR64RegClassID
+ : Mips::GPR32RegClassID).getRegister(RegNo)));
}
void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
@@ -1156,7 +1166,9 @@ public:
assert(Kind == k_Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
}
- bool isRegPair() const { return Kind == k_RegPair; }
+ bool isRegPair() const {
+ return Kind == k_RegPair && RegIdx.Index <= 30;
+ }
unsigned getReg() const override {
// As a special case until we sort out the definition of div/divu, pretend
@@ -1311,9 +1323,9 @@ public:
}
static std::unique_ptr<MipsOperand>
- CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
+ CreateRegPair(MipsOperand MOP, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
- Op->RegIdx.Index = RegNo;
+ Op->RegIdx.Index = MOP.RegIdx.Index;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
@@ -3618,11 +3630,15 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// As described by the Mips32r2 spec, the registers Rd and Rs for
// jalr.hb must be different.
// It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
+ // and registers Rd and Base for microMIPS lwp instruction
unsigned Opcode = Inst.getOpcode();
if ((Opcode == Mips::JALR_HB || Opcode == Mips::JALRC_HB_MMR6) &&
(Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
return Match_RequiresDifferentSrcAndDst;
+ else if ((Opcode == Mips::LWP_MM || Opcode == Mips::LWP_MMR6) &&
+ (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()))
+ return Match_RequiresDifferentSrcAndDst;
return Match_Success;
}
@@ -3786,6 +3802,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_MemSImm11:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected memory with 11-bit signed offset");
+ case Match_MemSImm12:
+ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+ "expected memory with 12-bit signed offset");
case Match_MemSImm16:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected memory with 16-bit signed offset");
@@ -4673,9 +4692,9 @@ MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
SMLoc E = Parser.getTok().getLoc();
MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
- unsigned Reg = Op.getGPR32Reg();
+
Operands.pop_back();
- Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
+ Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
return MatchOperand_Success;
}