summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp153
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp29
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp6
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td4
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrInfo.td28
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp3
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.td28
7 files changed, 117 insertions, 134 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index ae70fdd37c1..2e70d35fc4a 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -195,7 +195,6 @@ class MipsAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseImm(OperandVector &Operands);
OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
OperandMatchResultTy parseInvNum(OperandVector &Operands);
- OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
OperandMatchResultTy parseRegisterList(OperandVector &Operands);
bool searchSymbolAlias(OperandVector &Operands);
@@ -760,7 +759,6 @@ private:
k_RegisterIndex, /// A register index in one or more RegKind.
k_Token, /// A simple token
k_RegList, /// A physical register list
- k_RegPair /// A pair of physical register
} Kind;
public:
@@ -778,7 +776,6 @@ public:
delete RegList.List;
case k_RegisterIndex:
case k_Token:
- case k_RegPair:
break;
}
}
@@ -1038,6 +1035,17 @@ public:
Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
}
+ void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
+ }
+
+ void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
+ unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
+ }
+
/// Render the operand to an MCInst as a GPR64
/// Asserts if the wrong number of operands are requested, or the operand
/// is not a k_RegisterIndex compatible with RegKind_GPR
@@ -1217,29 +1225,6 @@ public:
Inst.addOperand(MCOperand::createReg(RegNo));
}
- void addRegPairOperands(MCInst &Inst, unsigned N) const {
- assert(N == 2 && "Invalid number of operands!");
- assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
- unsigned RegNo = getRegPair();
- 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 {
- assert(N == 2 && "Invalid number of operands!");
- for (auto RegNo : getRegList())
- Inst.addOperand(MCOperand::createReg(RegNo));
- }
-
bool isReg() const override {
// As a special case until we sort out the definition of div/divu, accept
// $0/$zero here so that MCK_ZERO works correctly.
@@ -1406,34 +1391,6 @@ public:
bool isRegList() const { return Kind == k_RegList; }
- bool isMovePRegPair() const {
- if (Kind != k_RegList || RegList.List->size() != 2)
- return false;
-
- unsigned R0 = RegList.List->front();
- unsigned R1 = RegList.List->back();
-
- if ((R0 == Mips::A1 && R1 == Mips::A2) ||
- (R0 == Mips::A1 && R1 == Mips::A3) ||
- (R0 == Mips::A2 && R1 == Mips::A3) ||
- (R0 == Mips::A0 && R1 == Mips::S5) ||
- (R0 == Mips::A0 && R1 == Mips::S6) ||
- (R0 == Mips::A0 && R1 == Mips::A1) ||
- (R0 == Mips::A0 && R1 == Mips::A2) ||
- (R0 == Mips::A0 && R1 == Mips::A3) ||
- (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
- (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
- (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
- (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
- (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
- (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
- (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
- (R0 == Mips::A0_64 && R1 == Mips::A3_64))
- return true;
-
- return false;
- }
-
StringRef getToken() const {
assert(Kind == k_Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
@@ -1481,11 +1438,6 @@ public:
return *(RegList.List);
}
- unsigned getRegPair() const {
- assert((Kind == k_RegPair) && "Invalid access!");
- return RegIdx.Index;
- }
-
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
MipsAsmParser &Parser) {
auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
@@ -1593,18 +1545,6 @@ public:
return Op;
}
- static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
- SMLoc S, SMLoc E,
- MipsAsmParser &Parser) {
- auto Op = llvm::make_unique<MipsOperand>(k_RegPair, Parser);
- Op->RegIdx.Index = MOP.RegIdx.Index;
- Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
- Op->RegIdx.Kind = MOP.RegIdx.Kind;
- Op->StartLoc = S;
- Op->EndLoc = E;
- return Op;
- }
-
bool isGPRZeroAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
}
@@ -1640,6 +1580,19 @@ public:
(RegIdx.Index >= 16 && RegIdx.Index <= 20));
}
+ bool isMM16AsmRegMovePPairFirst() const {
+ if (!(isRegIdx() && RegIdx.Kind))
+ return false;
+ return RegIdx.Index >= 4 && RegIdx.Index <= 6;
+ }
+
+ bool isMM16AsmRegMovePPairSecond() const {
+ if (!(isRegIdx() && RegIdx.Kind))
+ return false;
+ return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
+ (RegIdx.Index >= 5 && RegIdx.Index <= 7));
+ }
+
bool isFGRAsmReg() const {
// AFGR64 is $0-$15 but we handle this in getAFGR64()
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
@@ -1720,9 +1673,6 @@ public:
OS << Reg << " ";
OS << ">";
break;
- case k_RegPair:
- OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
- break;
}
}
@@ -2288,6 +2238,22 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
if (Inst.getOperand(0).getReg() == Mips::RA)
return Error(IDLoc, "invalid operand for instruction");
break;
+ case Mips::MOVEP_MM:
+ case Mips::MOVEP_MMR6: {
+ unsigned R0 = Inst.getOperand(0).getReg();
+ unsigned R1 = Inst.getOperand(1).getReg();
+ bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
+ (R0 == Mips::A1 && R1 == Mips::A3) ||
+ (R0 == Mips::A2 && R1 == Mips::A3) ||
+ (R0 == Mips::A0 && R1 == Mips::S5) ||
+ (R0 == Mips::A0 && R1 == Mips::S6) ||
+ (R0 == Mips::A0 && R1 == Mips::A1) ||
+ (R0 == Mips::A0 && R1 == Mips::A2) ||
+ (R0 == Mips::A0 && R1 == Mips::A3));
+ if (!RegPair)
+ return Error(IDLoc, "invalid operand for instruction");
+ break;
+ }
}
}
@@ -6278,45 +6244,6 @@ MipsAsmParser::parseRegisterList(OperandVector &Operands) {
return MatchOperand_Success;
}
-OperandMatchResultTy
-MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
- MCAsmParser &Parser = getParser();
- SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
- SmallVector<unsigned, 10> Regs;
-
- if (Parser.getTok().isNot(AsmToken::Dollar))
- return MatchOperand_ParseFail;
-
- SMLoc S = Parser.getTok().getLoc();
-
- if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
- return MatchOperand_ParseFail;
-
- MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
- unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
- Regs.push_back(RegNo);
-
- SMLoc E = Parser.getTok().getLoc();
- if (Parser.getTok().isNot(AsmToken::Comma)) {
- Error(E, "',' expected");
- return MatchOperand_ParseFail;
- }
-
- // Remove comma.
- Parser.Lex();
-
- if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
- return MatchOperand_ParseFail;
-
- Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
- RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
- Regs.push_back(RegNo);
-
- Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
-
- return MatchOperand_Success;
-}
-
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
/// either this.
/// ::= '(', register, ')'
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index b94afb9520e..27b27ff1e1e 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -538,6 +538,9 @@ static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+
namespace llvm {
Target &getTheMipselTarget();
@@ -2450,6 +2453,32 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
+ if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) ==
+ MCDisassembler::Fail)
+ return MCDisassembler::Fail;
+
+ unsigned RegRs;
+ if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6())
+ RegRs = fieldFromInstruction(Insn, 0, 2) |
+ (fieldFromInstruction(Insn, 3, 1) << 2);
+ else
+ RegRs = fieldFromInstruction(Insn, 1, 3);
+ if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) ==
+ MCDisassembler::Fail)
+ return MCDisassembler::Fail;
+
+ unsigned RegRt = fieldFromInstruction(Insn, 4, 3);
+ if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) ==
+ MCDisassembler::Fail)
+ return MCDisassembler::Fail;
+
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
uint64_t Address, const void *Decoder) {
switch (RegPair) {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index cd34b0ab70b..8e880b635c1 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -213,6 +213,12 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
TmpInst.setOpcode (NewOpcode);
Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
}
+
+ if (((MI.getOpcode() == Mips::MOVEP_MM) ||
+ (MI.getOpcode() == Mips::MOVEP_MMR6))) {
+ unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI);
+ Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
+ }
}
const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index 6b0aa7756ea..b5896060a71 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -1101,7 +1101,9 @@ class BREAK16_MMR6_DESC : BrkSdbbp16MM<"break16", II_BREAK>, MMR6Arch<"break16">
class LI16_MMR6_DESC : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>,
MMR6Arch<"li16">, IsAsCheapAsAMove;
class MOVE16_MMR6_DESC : MoveMM16<"move16", GPR32Opnd>, MMR6Arch<"move16">;
-class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMoveP>, MMR6Arch<"movep">;
+class MOVEP_MMR6_DESC : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
+ GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
+ MMR6Arch<"movep">;
class SDBBP16_MMR6_DESC : BrkSdbbp16MM<"sdbbp16", II_SDBBP>, MMR6Arch<"sdbbp16">;
class SUBU16_MMR6_DESC : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
MMR6Arch<"subu16"> {
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index 9f914bb9e87..174a05ea7af 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -231,27 +231,14 @@ class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
bit mayStore = 1;
}
-/// A register pair used by movep instruction.
-def MovePRegPairAsmOperand : AsmOperandClass {
- let Name = "MovePRegPair";
- let ParserMethod = "parseMovePRegPair";
- let PredicateMethod = "isMovePRegPair";
-}
-
-def movep_regpair : Operand<i32> {
- let EncoderMethod = "getMovePRegPairOpValue";
- let ParserMatchClass = MovePRegPairAsmOperand;
- let PrintMethod = "printRegisterList";
- let DecoderMethod = "DecodeMovePRegPair";
- let MIOperandInfo = (ops ptr_rc, ptr_rc);
-}
-
-class MovePMM16<string opstr, RegisterOperand RO> :
-MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt),
- !strconcat(opstr, "\t$dst_regs, $rs, $rt"), [],
+class MovePMM16<string opstr, RegisterOperand RO1, RegisterOperand RO2,
+ RegisterOperand RO3> :
+MicroMipsInst16<(outs RO1:$rd1, RO2:$rd2), (ins RO3:$rs, RO3:$rt),
+ !strconcat(opstr, "\t$rd1, $rd2, $rs, $rt"), [],
NoItinerary, FrmR> {
let isReMaterializable = 1;
let isMoveReg = 1;
+ let DecoderMethod = "DecodeMovePOperands";
}
class StorePairMM<string opstr, ComplexPattern Addr = addr>
@@ -682,8 +669,9 @@ def MFLO16_MM : MoveFromHILOMM<"mflo16", GPR32Opnd, AC0>,
MFHILO_FM_MM16<0x12>, ISA_MICROMIPS32_NOT_MIPS32R6;
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>,
ISA_MICROMIPS32_NOT_MIPS32R6;
-def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16,
- ISA_MICROMIPS32_NOT_MIPS32R6;
+def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMovePPairFirst,
+ GPRMM16OpndMovePPairSecond, GPRMM16OpndMoveP>,
+ MOVEP_FM_MM16, ISA_MICROMIPS32_NOT_MIPS32R6;
def LI16_MM : LoadImmMM16<"li16", li16_imm, GPRMM16Opnd>, LI_FM_MM16,
IsAsCheapAsAMove, ISA_MICROMIPS32_NOT_MIPS32R6;
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>,
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 96ca1cdd643..a0c80048c02 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -57,7 +57,10 @@ const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
switch (RC.getID()) {
case Mips::GPR32RegClassID:
case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
+ case Mips::GPRMM16MovePPairFirstRegClassID:
+ case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
+ case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
case Mips::SP32RegClassID:
return getRegBank(Mips::GPRBRegBankID);
default:
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td
index c85ee20273c..a943a0ad409 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.td
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td
@@ -335,6 +335,16 @@ def GPRMM16MoveP : RegisterClass<"Mips", [i32], 32, (add
// Callee save
S0, S2, S3, S4)>;
+def GPRMM16MovePPairFirst : RegisterClass<"Mips", [i32], 32, (add
+ // Arguments
+ A0, A1, A2)>;
+
+def GPRMM16MovePPairSecond : RegisterClass<"Mips", [i32], 32, (add
+ // Arguments
+ A1, A2, A3,
+ // Callee save
+ S5, S6)>;
+
def GPR64 : RegisterClass<"Mips", [i64], 64, (add
// Reserved
ZERO_64, AT_64,
@@ -522,6 +532,16 @@ def GPRMM16AsmOperandMoveP : MipsAsmRegOperand {
let PredicateMethod = "isMM16AsmRegMoveP";
}
+def GPRMM16AsmOperandMovePPairFirst : MipsAsmRegOperand {
+ let Name = "GPRMM16AsmRegMovePPairFirst";
+ let PredicateMethod = "isMM16AsmRegMovePPairFirst";
+}
+
+def GPRMM16AsmOperandMovePPairSecond : MipsAsmRegOperand {
+ let Name = "GPRMM16AsmRegMovePPairSecond";
+ let PredicateMethod = "isMM16AsmRegMovePPairSecond";
+}
+
def ACC64DSPAsmOperand : MipsAsmRegOperand {
let Name = "ACC64DSPAsmReg";
let PredicateMethod = "isACCAsmReg";
@@ -613,6 +633,14 @@ def GPRMM16OpndMoveP : RegisterOperand<GPRMM16MoveP> {
let EncoderMethod = "getMovePRegSingleOpValue";
}
+def GPRMM16OpndMovePPairFirst : RegisterOperand<GPRMM16MovePPairFirst> {
+ let ParserMatchClass = GPRMM16AsmOperandMovePPairFirst;
+}
+
+def GPRMM16OpndMovePPairSecond : RegisterOperand<GPRMM16MovePPairSecond> {
+ let ParserMatchClass = GPRMM16AsmOperandMovePPairSecond;
+}
+
def GPR64Opnd : RegisterOperand<GPR64> {
let ParserMatchClass = GPR64AsmOperand;
}
OpenPOWER on IntegriCloud