summaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@mips.com>2017-11-16 10:13:49 +0000
committerSimon Dardis <simon.dardis@mips.com>2017-11-16 10:13:49 +0000
commit52e96d1e3ae8fcf28bd2c238d88ef5d302bd317d (patch)
treea01ffba471084a9f0158c86d3e16dab04967054b /lib/Target
parent399df16520c8ce68a73dfbe129e70e4fd0109fdb (diff)
Merging r318207:
------------------------------------------------------------------------ r318207 | sdardis | 2017-11-14 22:26:42 +0000 (Tue, 14 Nov 2017) | 18 lines Reland "[mips][mt][6/7] Add support for mftr, mttr instructions." This adjusts the tests to hopfully pacify the llvm-clang-x86_64-expensive-checks-win buildbot. Unlike many other instructions, these instructions have aliases which take coprocessor registers, gpr register, accumulator (and dsp accumulator) registers, floating point registers, floating point control registers and coprocessor 2 data and control operands. For the moment, these aliases are treated as pseudo instructions which are expanded into the underlying instruction. As a result, disassembling these instructions shows the underlying instruction and not the alias. Reviewers: slthakur, atanasyan Differential Revision: https://reviews.llvm.org/D35253 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@318386 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp219
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp15
-rw-r--r--lib/Target/Mips/MipsMTInstrFormats.td21
-rw-r--r--lib/Target/Mips/MipsMTInstrInfo.td110
-rw-r--r--lib/Target/Mips/MipsSchedule.td4
-rw-r--r--lib/Target/Mips/MipsScheduleGeneric.td4
-rw-r--r--lib/Target/Mips/MipsTargetStreamer.h3
7 files changed, 375 insertions, 1 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index f75d23fe6a92..a294004b9f68 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -304,6 +304,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
+ bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@@ -2511,6 +2514,16 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::SEQIMacro:
return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
+ case Mips::MFTC0: case Mips::MTTC0:
+ case Mips::MFTGPR: case Mips::MTTGPR:
+ case Mips::MFTLO: case Mips::MTTLO:
+ case Mips::MFTHI: case Mips::MTTHI:
+ case Mips::MFTACX: case Mips::MTTACX:
+ case Mips::MFTDSP: case Mips::MTTDSP:
+ case Mips::MFTC1: case Mips::MTTC1:
+ case Mips::MFTHC1: case Mips::MTTHC1:
+ case Mips::CFTC1: case Mips::CTTC1:
+ return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
}
}
@@ -4882,6 +4895,212 @@ bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
+// Map the DSP accumulator and control register to the corresponding gpr
+// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
+// do not map the DSP registers contigously to gpr registers.
+static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
+ switch (Inst.getOpcode()) {
+ case Mips::MFTLO:
+ case Mips::MTTLO:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::ZERO;
+ case Mips::AC1:
+ return Mips::A0;
+ case Mips::AC2:
+ return Mips::T0;
+ case Mips::AC3:
+ return Mips::T4;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTHI:
+ case Mips::MTTHI:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::AT;
+ case Mips::AC1:
+ return Mips::A1;
+ case Mips::AC2:
+ return Mips::T1;
+ case Mips::AC3:
+ return Mips::T5;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTACX:
+ case Mips::MTTACX:
+ switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
+ case Mips::AC0:
+ return Mips::V0;
+ case Mips::AC1:
+ return Mips::A2;
+ case Mips::AC2:
+ return Mips::T2;
+ case Mips::AC3:
+ return Mips::T6;
+ default:
+ llvm_unreachable("Unknown register for 'mttr' alias!");
+ }
+ case Mips::MFTDSP:
+ case Mips::MTTDSP:
+ return Mips::S0;
+ default:
+ llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
+ }
+}
+
+// Map the floating point register operand to the corresponding register
+// operand.
+static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
+ switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
+ case Mips::F0: return Mips::ZERO;
+ case Mips::F1: return Mips::AT;
+ case Mips::F2: return Mips::V0;
+ case Mips::F3: return Mips::V1;
+ case Mips::F4: return Mips::A0;
+ case Mips::F5: return Mips::A1;
+ case Mips::F6: return Mips::A2;
+ case Mips::F7: return Mips::A3;
+ case Mips::F8: return Mips::T0;
+ case Mips::F9: return Mips::T1;
+ case Mips::F10: return Mips::T2;
+ case Mips::F11: return Mips::T3;
+ case Mips::F12: return Mips::T4;
+ case Mips::F13: return Mips::T5;
+ case Mips::F14: return Mips::T6;
+ case Mips::F15: return Mips::T7;
+ case Mips::F16: return Mips::S0;
+ case Mips::F17: return Mips::S1;
+ case Mips::F18: return Mips::S2;
+ case Mips::F19: return Mips::S3;
+ case Mips::F20: return Mips::S4;
+ case Mips::F21: return Mips::S5;
+ case Mips::F22: return Mips::S6;
+ case Mips::F23: return Mips::S7;
+ case Mips::F24: return Mips::T8;
+ case Mips::F25: return Mips::T9;
+ case Mips::F26: return Mips::K0;
+ case Mips::F27: return Mips::K1;
+ case Mips::F28: return Mips::GP;
+ case Mips::F29: return Mips::SP;
+ case Mips::F30: return Mips::FP;
+ case Mips::F31: return Mips::RA;
+ default: llvm_unreachable("Unknown register for mttc1 alias!");
+ }
+}
+
+// Map the coprocessor operand the corresponding gpr register operand.
+static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
+ switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
+ case Mips::COP00: return Mips::ZERO;
+ case Mips::COP01: return Mips::AT;
+ case Mips::COP02: return Mips::V0;
+ case Mips::COP03: return Mips::V1;
+ case Mips::COP04: return Mips::A0;
+ case Mips::COP05: return Mips::A1;
+ case Mips::COP06: return Mips::A2;
+ case Mips::COP07: return Mips::A3;
+ case Mips::COP08: return Mips::T0;
+ case Mips::COP09: return Mips::T1;
+ case Mips::COP010: return Mips::T2;
+ case Mips::COP011: return Mips::T3;
+ case Mips::COP012: return Mips::T4;
+ case Mips::COP013: return Mips::T5;
+ case Mips::COP014: return Mips::T6;
+ case Mips::COP015: return Mips::T7;
+ case Mips::COP016: return Mips::S0;
+ case Mips::COP017: return Mips::S1;
+ case Mips::COP018: return Mips::S2;
+ case Mips::COP019: return Mips::S3;
+ case Mips::COP020: return Mips::S4;
+ case Mips::COP021: return Mips::S5;
+ case Mips::COP022: return Mips::S6;
+ case Mips::COP023: return Mips::S7;
+ case Mips::COP024: return Mips::T8;
+ case Mips::COP025: return Mips::T9;
+ case Mips::COP026: return Mips::K0;
+ case Mips::COP027: return Mips::K1;
+ case Mips::COP028: return Mips::GP;
+ case Mips::COP029: return Mips::SP;
+ case Mips::COP030: return Mips::FP;
+ case Mips::COP031: return Mips::RA;
+ default: llvm_unreachable("Unknown register for mttc0 alias!");
+ }
+}
+
+/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
+/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
+bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned rd = 0;
+ unsigned u = 1;
+ unsigned sel = 0;
+ unsigned h = 0;
+ bool IsMFTR = false;
+ switch (Inst.getOpcode()) {
+ case Mips::MFTC0:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTC0:
+ u = 0;
+ rd = getRegisterForMxtrC0(Inst, IsMFTR);
+ sel = Inst.getOperand(2).getImm();
+ break;
+ case Mips::MFTGPR:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTGPR:
+ rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
+ break;
+ case Mips::MFTLO:
+ case Mips::MFTHI:
+ case Mips::MFTACX:
+ case Mips::MFTDSP:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTLO:
+ case Mips::MTTHI:
+ case Mips::MTTACX:
+ case Mips::MTTDSP:
+ rd = getRegisterForMxtrDSP(Inst, IsMFTR);
+ sel = 1;
+ break;
+ case Mips::MFTHC1:
+ h = 1;
+ LLVM_FALLTHROUGH;
+ case Mips::MFTC1:
+ IsMFTR = true;
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 2;
+ break;
+ case Mips::MTTHC1:
+ h = 1;
+ LLVM_FALLTHROUGH;
+ case Mips::MTTC1:
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 2;
+ break;
+ case Mips::CFTC1:
+ IsMFTR = true;
+ LLVM_FALLTHROUGH;
+ case Mips::CTTC1:
+ rd = getRegisterForMxtrFP(Inst, IsMFTR);
+ sel = 3;
+ break;
+ }
+ unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
+ unsigned Op1 =
+ IsMFTR ? rd
+ : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
+ : Inst.getOperand(0).getReg());
+
+ TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
+ STI);
+ return false;
+}
+
unsigned
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
const OperandVector &Operands) {
diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index 2907b7715857..7caeb08589af 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -193,6 +193,21 @@ void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
}
+void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
+ unsigned Reg1, int16_t Imm0, int16_t Imm1,
+ int16_t Imm2, SMLoc IDLoc,
+ const MCSubtargetInfo *STI) {
+ MCInst TmpInst;
+ TmpInst.setOpcode(Opcode);
+ TmpInst.addOperand(MCOperand::createReg(Reg0));
+ TmpInst.addOperand(MCOperand::createReg(Reg1));
+ TmpInst.addOperand(MCOperand::createImm(Imm0));
+ TmpInst.addOperand(MCOperand::createImm(Imm1));
+ TmpInst.addOperand(MCOperand::createImm(Imm2));
+ TmpInst.setLoc(IDLoc);
+ getStreamer().EmitInstruction(TmpInst, *STI);
+}
+
void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
unsigned TrgReg, bool Is64Bit,
const MCSubtargetInfo *STI) {
diff --git a/lib/Target/Mips/MipsMTInstrFormats.td b/lib/Target/Mips/MipsMTInstrFormats.td
index 64bee5bfba18..edc0981e6278 100644
--- a/lib/Target/Mips/MipsMTInstrFormats.td
+++ b/lib/Target/Mips/MipsMTInstrFormats.td
@@ -35,6 +35,8 @@ class FIELD5<bits<5> Val> {
def FIELD5_1_DMT_EMT : FIELD5<0b00001>;
def FIELD5_2_DMT_EMT : FIELD5<0b01111>;
def FIELD5_1_2_DVPE_EVPE : FIELD5<0b00000>;
+def FIELD5_MFTR : FIELD5<0b01000>;
+def FIELD5_MTTR : FIELD5<0b01100>;
class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
bits<32> Inst;
@@ -50,6 +52,25 @@ class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
let Inst{2-0} = 0b001;
}
+class COP0_MFTTR_MT<FIELD5 Op> : MipsMTInst {
+ bits<32> Inst;
+
+ bits<5> rt;
+ bits<5> rd;
+ bits<1> u;
+ bits<1> h;
+ bits<3> sel;
+ let Inst{31-26} = 0b010000; // COP0
+ let Inst{25-21} = Op.Value; // MFMC0
+ let Inst{20-16} = rt;
+ let Inst{15-11} = rd;
+ let Inst{10-6} = 0b00000; // rx - currently unsupported.
+ let Inst{5} = u;
+ let Inst{4} = h;
+ let Inst{3} = 0b0;
+ let Inst{2-0} = sel;
+}
+
class SPECIAL3_MT_FORK : MipsMTInst {
bits<32> Inst;
diff --git a/lib/Target/Mips/MipsMTInstrInfo.td b/lib/Target/Mips/MipsMTInstrInfo.td
index ab6693f60fd9..72e626cbec40 100644
--- a/lib/Target/Mips/MipsMTInstrInfo.td
+++ b/lib/Target/Mips/MipsMTInstrInfo.td
@@ -6,6 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// This file describes the MIPS MT ASE as defined by MD00378 1.12.
+//
+// TODO: Add support for the microMIPS encodings for the MT ASE and add the
+// instruction mappings.
+//
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MIPS MT Instruction Encodings
@@ -27,6 +34,10 @@ class FORK_ENC : SPECIAL3_MT_FORK;
class YIELD_ENC : SPECIAL3_MT_YIELD;
+class MFTR_ENC : COP0_MFTTR_MT<FIELD5_MFTR>;
+
+class MTTR_ENC : COP0_MFTTR_MT<FIELD5_MTTR>;
+
//===----------------------------------------------------------------------===//
// MIPS MT Instruction Descriptions
//===----------------------------------------------------------------------===//
@@ -39,6 +50,22 @@ class MT_1R_DESC_BASE<string instr_asm, InstrItinClass Itin = NoItinerary> {
InstrItinClass Itinerary = Itin;
}
+class MFTR_DESC {
+ dag OutOperandList = (outs GPR32Opnd:$rd);
+ dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h);
+ string AsmString = "mftr\t$rd, $rt, $u, $sel, $h";
+ list<dag> Pattern = [];
+ InstrItinClass Itinerary = II_MFTR;
+}
+
+class MTTR_DESC {
+ dag OutOperandList = (outs GPR32Opnd:$rd);
+ dag InOperandList = (ins GPR32Opnd:$rt, uimm1:$u, uimm3:$sel, uimm1:$h);
+ string AsmString = "mttr\t$rt, $rd, $u, $sel, $h";
+ list<dag> Pattern = [];
+ InstrItinClass Itinerary = II_MTTR;
+}
+
class FORK_DESC {
dag OutOperandList = (outs GPR32Opnd:$rs, GPR32Opnd:$rd);
dag InOperandList = (ins GPR32Opnd:$rt);
@@ -79,9 +106,74 @@ let hasSideEffects = 1, isNotDuplicable = 1,
def FORK : FORK_ENC, FORK_DESC, ASE_MT;
def YIELD : YIELD_ENC, YIELD_DESC, ASE_MT;
+
+ def MFTR : MFTR_ENC, MFTR_DESC, ASE_MT;
+
+ def MTTR : MTTR_ENC, MTTR_DESC, ASE_MT;
}
//===----------------------------------------------------------------------===//
+// MIPS MT Pseudo Instructions - used to support mtfr & mttr aliases.
+//===----------------------------------------------------------------------===//
+def MFTC0 : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins COP0Opnd:$rt,
+ uimm3:$sel),
+ "mftc0 $rd, $rt, $sel">, ASE_MT;
+
+def MFTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rt,
+ uimm3:$sel),
+ "mftgpr $rd, $rt">, ASE_MT;
+
+def MFTLO : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mftlo $rt, $ac">, ASE_MT;
+
+def MFTHI : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mfthi $rt, $ac">, ASE_MT;
+
+def MFTACX : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins ACC64DSPOpnd:$ac),
+ "mftacx $rt, $ac">, ASE_MT;
+
+def MFTDSP : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins),
+ "mftdsp $rt">, ASE_MT;
+
+def MFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft),
+ "mftc1 $rt, $ft">, ASE_MT;
+
+def MFTHC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGR32Opnd:$ft),
+ "mfthc1 $rt, $ft">, ASE_MT;
+
+def CFTC1 : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins FGRCCOpnd:$ft),
+ "cftc1 $rt, $ft">, ASE_MT;
+
+
+def MTTC0 : MipsAsmPseudoInst<(outs COP0Opnd:$rd), (ins GPR32Opnd:$rt,
+ uimm3:$sel),
+ "mttc0 $rt, $rd, $sel">, ASE_MT;
+
+def MTTGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins GPR32Opnd:$rd),
+ "mttgpr $rd, $rt">, ASE_MT;
+
+def MTTLO : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mttlo $rt, $ac">, ASE_MT;
+
+def MTTHI : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mtthi $rt, $ac">, ASE_MT;
+
+def MTTACX : MipsAsmPseudoInst<(outs ACC64DSPOpnd:$ac), (ins GPR32Opnd:$rt),
+ "mttacx $rt, $ac">, ASE_MT;
+
+def MTTDSP : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rt),
+ "mttdsp $rt">, ASE_MT;
+
+def MTTC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt),
+ "mttc1 $rt, $ft">, ASE_MT;
+
+def MTTHC1 : MipsAsmPseudoInst<(outs FGR32Opnd:$ft), (ins GPR32Opnd:$rt),
+ "mtthc1 $rt, $ft">, ASE_MT;
+
+def CTTC1 : MipsAsmPseudoInst<(outs FGRCCOpnd:$ft), (ins GPR32Opnd:$rt),
+ "cttc1 $rt, $ft">, ASE_MT;
+
+//===----------------------------------------------------------------------===//
// MIPS MT Instruction Definitions
//===----------------------------------------------------------------------===//
@@ -95,4 +187,22 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"evpe", (EVPE ZERO), 1>, ASE_MT;
def : MipsInstAlias<"yield $rs", (YIELD ZERO, GPR32Opnd:$rs), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftc0 $rd, $rt", (MFTC0 GPR32Opnd:$rd, COP0Opnd:$rt, 0),
+ 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftlo $rt", (MFTLO GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mfthi $rt", (MFTHI GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mftacx $rt", (MFTACX GPR32Opnd:$rt, AC0), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttc0 $rd, $rt", (MTTC0 COP0Opnd:$rt, GPR32Opnd:$rd, 0),
+ 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttlo $rt", (MTTLO AC0, GPR32Opnd:$rt), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mtthi $rt", (MTTHI AC0, GPR32Opnd:$rt), 1>, ASE_MT;
+
+ def : MipsInstAlias<"mttacx $rt", (MTTACX AC0, GPR32Opnd:$rt), 1>, ASE_MT;
}
diff --git a/lib/Target/Mips/MipsSchedule.td b/lib/Target/Mips/MipsSchedule.td
index c2947bb44ef5..8ec55ab6284d 100644
--- a/lib/Target/Mips/MipsSchedule.td
+++ b/lib/Target/Mips/MipsSchedule.td
@@ -226,6 +226,7 @@ def II_MFC1 : InstrItinClass;
def II_MFHC1 : InstrItinClass;
def II_MFC2 : InstrItinClass;
def II_MFHI_MFLO : InstrItinClass; // mfhi and mflo
+def II_MFTR : InstrItinClass;
def II_MOD : InstrItinClass;
def II_MODU : InstrItinClass;
def II_MOVE : InstrItinClass;
@@ -255,6 +256,7 @@ def II_MTC1 : InstrItinClass;
def II_MTHC1 : InstrItinClass;
def II_MTC2 : InstrItinClass;
def II_MTHI_MTLO : InstrItinClass; // mthi and mtlo
+def II_MTTR : InstrItinClass;
def II_MUL : InstrItinClass;
def II_MUH : InstrItinClass;
def II_MUHU : InstrItinClass;
@@ -664,12 +666,14 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<II_MFHC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFC2 , [InstrStage<2, [ALU]>]>,
+ InstrItinData<II_MFTR , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTHC0 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTC2 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MFHC1 , [InstrStage<2, [ALU]>]>,
InstrItinData<II_MTHC1 , [InstrStage<2, [ALU]>]>,
+ InstrItinData<II_MTTR , [InstrStage<2, [ALU]>]>,
InstrItinData<II_CACHE , [InstrStage<1, [ALU]>]>,
InstrItinData<II_PREF , [InstrStage<1, [ALU]>]>,
InstrItinData<II_CACHEE , [InstrStage<1, [ALU]>]>,
diff --git a/lib/Target/Mips/MipsScheduleGeneric.td b/lib/Target/Mips/MipsScheduleGeneric.td
index 89cda676441e..e4c52a4e1825 100644
--- a/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/lib/Target/Mips/MipsScheduleGeneric.td
@@ -268,9 +268,11 @@ def : ItinRW<[GenericWriteLoad], [II_LWLE, II_LWRE]>;
// MIPS MT instructions
// ====================
-def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE]>;
+def : ItinRW<[GenericWriteMove], [II_DMT, II_DVPE, II_EMT, II_EVPE, II_MFTR,
+ II_MTTR]>;
def : ItinRW<[GenericReadWriteCOP0Long], [II_YIELD]>;
+
def : ItinRW<[GenericWriteCOP0Short], [II_FORK]>;
// MIPS32R6 and MIPS16e
diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h
index 7d9f99ce071e..af24838665e1 100644
--- a/lib/Target/Mips/MipsTargetStreamer.h
+++ b/lib/Target/Mips/MipsTargetStreamer.h
@@ -119,6 +119,9 @@ public:
SMLoc IDLoc, const MCSubtargetInfo *STI);
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
SMLoc IDLoc, const MCSubtargetInfo *STI);
+ void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0,
+ int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
+ const MCSubtargetInfo *STI);
void emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit,
const MCSubtargetInfo *STI);
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,