diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e12188e7060..b72c9d53447 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 2907b771585..7caeb08589a 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 64bee5bfba1..edc0981e627 100644 --- a/lib/Target/Mips/MipsMTInstrFormats.td +++ b/lib/Target/Mips/MipsMTInstrFormats.td @@ -35,6 +35,8 @@ class FIELD5 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 : MipsMTInst { bits<32> Inst; @@ -50,6 +52,25 @@ class COP0_MFMC0_MT : MipsMTInst { let Inst{2-0} = 0b001; } +class COP0_MFTTR_MT : 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 ab6693f60fd..72e626cbec4 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; + +class MTTR_ENC : COP0_MFTTR_MT; + //===----------------------------------------------------------------------===// // MIPS MT Instruction Descriptions //===----------------------------------------------------------------------===// @@ -39,6 +50,22 @@ class MT_1R_DESC_BASE { 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 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 Pattern = []; + InstrItinClass Itinerary = II_MTTR; +} + class FORK_DESC { dag OutOperandList = (outs GPR32Opnd:$rs, GPR32Opnd:$rd); dag InOperandList = (ins GPR32Opnd:$rt); @@ -79,8 +106,73 @@ 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 c2947bb44ef..8ec55ab6284 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]>, InstrItinData]>, InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 7d9f99ce071..af24838665e 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, diff --git a/test/MC/Disassembler/Mips/mt/valid-r2-el.txt b/test/MC/Disassembler/Mips/mt/valid-r2-el.txt index 7025354d684..62e7092086a 100644 --- a/test/MC/Disassembler/Mips/mt/valid-r2-el.txt +++ b/test/MC/Disassembler/Mips/mt/valid-r2-el.txt @@ -10,4 +10,23 @@ 0x08 0x10 0x65 0x7c # CHECK: fork $2, $3, $5 0x09 0x00 0x80 0x7c # CHECK: yield $4 0x09 0x20 0xa0 0x7c # CHECK: yield $4, $5 - +0x02 0x20 0x05 0x41 # CHECK: mftr $4, $5, 0, 2, 0 +0x20 0x20 0x05 0x41 # CHECK: mftr $4, $5, 1, 0, 0 +0x21 0x20 0x00 0x41 # CHECK: mftr $4, $zero, 1, 1, 0 +0x21 0x20 0x0a 0x41 # CHECK: mftr $4, $10, 1, 1, 0 +0x22 0x20 0x0a 0x41 # CHECK: mftr $4, $10, 1, 2, 0 +0x32 0x20 0x0a 0x41 # CHECK: mftr $4, $10, 1, 2, 1 +0x23 0x20 0x1a 0x41 # CHECK: mftr $4, $26, 1, 3, 0 +0x23 0x20 0x1f 0x41 # CHECK: mftr $4, $ra, 1, 3, 0 +0x24 0x20 0x0e 0x41 # CHECK: mftr $4, $14, 1, 4, 0 +0x25 0x20 0x0f 0x41 # CHECK: mftr $4, $15, 1, 5, 0 +0x02 0x28 0x84 0x41 # CHECK: mttr $4, $5, 0, 2, 0 +0x20 0x28 0x84 0x41 # CHECK: mttr $4, $5, 1, 0, 0 +0x21 0x00 0x84 0x41 # CHECK: mttr $4, $zero, 1, 1, 0 +0x21 0x50 0x84 0x41 # CHECK: mttr $4, $10, 1, 1, 0 +0x22 0x50 0x84 0x41 # CHECK: mttr $4, $10, 1, 2, 0 +0x32 0x50 0x84 0x41 # CHECK: mttr $4, $10, 1, 2, 1 +0x23 0xd0 0x84 0x41 # CHECK: mttr $4, $26, 1, 3, 0 +0x23 0xf8 0x84 0x41 # CHECK: mttr $4, $ra, 1, 3, 0 +0x24 0x70 0x84 0x41 # CHECK: mttr $4, $14, 1, 4, 0 +0x25 0x78 0x84 0x41 # CHECK: mttr $4, $15, 1, 5, 0 diff --git a/test/MC/Disassembler/Mips/mt/valid-r2.txt b/test/MC/Disassembler/Mips/mt/valid-r2.txt index 17c42c0614a..4786d8b5591 100644 --- a/test/MC/Disassembler/Mips/mt/valid-r2.txt +++ b/test/MC/Disassembler/Mips/mt/valid-r2.txt @@ -10,4 +10,23 @@ 0x7c 0x65 0x10 0x08 # CHECK: fork $2, $3, $5 0x7c 0x80 0x00 0x09 # CHECK: yield $4 0x7c 0xa0 0x20 0x09 # CHECK: yield $4, $5 - +0x41 0x05 0x20 0x02 # CHECK: mftr $4, $5, 0, 2, 0 +0x41 0x05 0x20 0x20 # CHECK: mftr $4, $5, 1, 0, 0 +0x41 0x00 0x20 0x21 # CHECK: mftr $4, $zero, 1, 1, 0 +0x41 0x0a 0x20 0x21 # CHECK: mftr $4, $10, 1, 1, 0 +0x41 0x0a 0x20 0x22 # CHECK: mftr $4, $10, 1, 2, 0 +0x41 0x0a 0x20 0x32 # CHECK: mftr $4, $10, 1, 2, 1 +0x41 0x1a 0x20 0x23 # CHECK: mftr $4, $26, 1, 3, 0 +0x41 0x1f 0x20 0x23 # CHECK: mftr $4, $ra, 1, 3, 0 +0x41 0x0e 0x20 0x24 # CHECK: mftr $4, $14, 1, 4, 0 +0x41 0x0f 0x20 0x25 # CHECK: mftr $4, $15, 1, 5, 0 +0x41 0x84 0x28 0x02 # CHECK: mttr $4, $5, 0, 2, 0 +0x41 0x84 0x28 0x20 # CHECK: mttr $4, $5, 1, 0, 0 +0x41 0x84 0x00 0x21 # CHECK: mttr $4, $zero, 1, 1, 0 +0x41 0x84 0x50 0x21 # CHECK: mttr $4, $10, 1, 1, 0 +0x41 0x84 0x50 0x22 # CHECK: mttr $4, $10, 1, 2, 0 +0x41 0x84 0x50 0x32 # CHECK: mttr $4, $10, 1, 2, 1 +0x41 0x84 0xd0 0x23 # CHECK: mttr $4, $26, 1, 3, 0 +0x41 0x84 0xf8 0x23 # CHECK: mttr $4, $ra, 1, 3, 0 +0x41 0x84 0x70 0x24 # CHECK: mttr $4, $14, 1, 4, 0 +0x41 0x84 0x78 0x25 # CHECK: mttr $4, $15, 1, 5, 0 diff --git a/test/MC/Mips/mt/invalid-wrong-error.s b/test/MC/Mips/mt/invalid-wrong-error.s new file mode 100644 index 00000000000..942d6091450 --- /dev/null +++ b/test/MC/Mips/mt/invalid-wrong-error.s @@ -0,0 +1,4 @@ +# RUN: not llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt %s 2>%t1 +# RUN: FileCheck %s < %t1 + mftr 0($4), $5, 0, 0, 0 # CHECK: error: unexpected token in argument list + mttr 0($4), $5, 0, 0, 0 # CHECK: error: unexpected token in argument list diff --git a/test/MC/Mips/mt/invalid.s b/test/MC/Mips/mt/invalid.s index 5a145a7e085..bc561916f9c 100644 --- a/test/MC/Mips/mt/invalid.s +++ b/test/MC/Mips/mt/invalid.s @@ -1,13 +1,28 @@ -# RUN: not llvm-mc -arch=mips -mcpu=mips32 -mattr=+mt < %s 2>&1 | FileCheck %s - dmt 4 # CHECK: error: invalid operand for instruction - dmt $4, $5 # CHECK: error: invalid operand for instruction - dmt $5, 0($4) # CHECK: error: invalid operand for instruction - emt 4 # CHECK: error: invalid operand for instruction - emt $4, $5 # CHECK: error: invalid operand for instruction - emt $5, 0($5) # CHECK: error: invalid operand for instruction - dvpe 4 # CHECK: error: invalid operand for instruction - dvpe $4, $5 # CHECK: error: invalid operand for instruction - dvpe $5, 0($4) # CHECK: error: invalid operand for instruction - evpe 4 # CHECK: error: invalid operand for instruction - evpe $4, $5 # CHECK: error: invalid operand for instruction - evpe $5, 0($5) # CHECK: error: invalid operand for instruction +# RUN: not llvm-mc -triple=mips-unknown-linux -mcpu=mips32 -mattr=+mt %s 2>%t1 +# RUN: FileCheck %s < %t1 + dmt 4 # CHECK: error: invalid operand for instruction + dmt $4, $5 # CHECK: error: invalid operand for instruction + dmt $5, 0($4) # CHECK: error: invalid operand for instruction + emt 4 # CHECK: error: invalid operand for instruction + emt $4, $5 # CHECK: error: invalid operand for instruction + emt $5, 0($5) # CHECK: error: invalid operand for instruction + dvpe 4 # CHECK: error: invalid operand for instruction + dvpe $4, $5 # CHECK: error: invalid operand for instruction + dvpe $5, 0($4) # CHECK: error: invalid operand for instruction + evpe 4 # CHECK: error: invalid operand for instruction + evpe $4, $5 # CHECK: error: invalid operand for instruction + evpe $5, 0($5) # CHECK: error: invalid operand for instruction + mftr $4, 0($5), 0, 0, 0 # CHECK: error: invalid operand for instruction + mftr $4, $5, 2, 0, 0 # CHECK: error: expected 1-bit unsigned immediate + mftr $4, $5, -1, 0, 0 # CHECK: error: expected 1-bit unsigned immediate + mftr $4, $5, 0, 8, 0 # CHECK: error: expected 3-bit unsigned immediate + mftr $4, $5, 0, -1, 0 # CHECK: error: expected 3-bit unsigned immediate + mftr $4, $4, 0, 0, 2 # CHECK: error: expected 1-bit unsigned immediate + mftr $4, $5, 0, 0, -1 # CHECK: error: expected 1-bit unsigned immediate + mttr $4, 0($5), 0, 0, 0 # CHECK: error: invalid operand for instruction + mttr $4, $5, 2, 0, 0 # CHECK: error: expected 1-bit unsigned immediate + mttr $4, $5, -1, 0, 0 # CHECK: error: expected 1-bit unsigned immediate + mttr $4, $5, 0, 8, 0 # CHECK: error: expected 3-bit unsigned immediate + mttr $4, $5, 0, -1, 0 # CHECK: error: expected 3-bit unsigned immediate + mttr $4, $4, 0, 0, 2 # CHECK: error: expected 1-bit unsigned immediate + mttr $4, $5, 0, 0, -1 # CHECK: error: expected 1-bit unsigned immediate diff --git a/test/MC/Mips/mt/mftr-mttr-aliases-invalid-wrong-error.s b/test/MC/Mips/mt/mftr-mttr-aliases-invalid-wrong-error.s new file mode 100644 index 00000000000..7c6270c9ce4 --- /dev/null +++ b/test/MC/Mips/mt/mftr-mttr-aliases-invalid-wrong-error.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt -show-encoding %s 2>%t1 +# RUN: FileCheck %s < %t1 + +# The integrated assembler produces a wrong or misleading error message. + + mftc0 0($4), $5 # CHECK: error: unexpected token in argument list + mftc0 0($4), $5, 1 # CHECK: error: unexpected token in argument list + mftgpr 0($4), $5 # CHECK: error: unexpected token in argument list + mftlo 0($3) # CHECK: error: unexpected token in argument list + mftlo 0($3), $ac1 # CHECK: error: unexpected token in argument list + mfthi 0($3) # CHECK: error: unexpected token in argument list + mfthi 0($3), $ac1 # CHECK: error: unexpected token in argument list + mftacx 0($3) # CHECK: error: unexpected token in argument list + mftacx 0($3), $ac1 # CHECK: error: unexpected token in argument list + mftdsp 0($4) # CHECK: error: unexpected token in argument list + mftc1 0($4), $f4 # CHECK: error: unexpected token in argument list + mfthc1 0($4), $f4 # CHECK: error: unexpected token in argument list + cftc1 0($4), $f8 # CHECK: error: unexpected token in argument list diff --git a/test/MC/Mips/mt/mftr-mttr-aliases-invalid.s b/test/MC/Mips/mt/mftr-mttr-aliases-invalid.s new file mode 100644 index 00000000000..d93458774e2 --- /dev/null +++ b/test/MC/Mips/mt/mftr-mttr-aliases-invalid.s @@ -0,0 +1,23 @@ +# RUN: not llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt -show-encoding %s 2>%t1 +# RUN: FileCheck %s < %t1 + + mftc0 $4, 0($5) # CHECK: error: invalid operand for instruction + mftc0 $4, 0($5), 1 # CHECK: error: invalid operand for instruction + mftc0 $4, $5, -1 # CHECK: error: expected 3-bit unsigned immediate + mftc0 $4, $5, 9 # CHECK: error: expected 3-bit unsigned immediate + mftc0 $4, $5, $6 # CHECK: error: expected 3-bit unsigned immediate + mftgpr $4, 0($5) # CHECK: error: invalid operand for instruction + mftgpr $4, $5, $6 # CHECK: error: invalid operand for instruction + mftlo $3, 0($ac1) # CHECK: error: invalid operand for instruction + mftlo $4, $ac1, $4 # CHECK: error: invalid operand for instruction + mfthi $3, 0($ac1) # CHECK: error: invalid operand for instruction + mfthi $4, $ac1, $4 # CHECK: error: invalid operand for instruction + mftacx $3, 0($ac1) # CHECK: error: invalid operand for instruction + mftacx $4, $ac1, $4 # CHECK: error: invalid operand for instruction + mftdsp $4, $5 # CHECK: error: invalid operand for instruction + mftdsp $4, $f5 # CHECK: error: invalid operand for instruction + mftdsp $4, $ac0 # CHECK: error: invalid operand for instruction + mftc1 $4, 0($f4) # CHECK: error: invalid operand for instruction + mfthc1 $4, 0($f4) # CHECK: error: invalid operand for instruction + cftc1 $4, 0($f4) # CHECK: error: invalid operand for instruction + cftc1 $4, $f4, $5 # CHECK: error: invalid operand for instruction diff --git a/test/MC/Mips/mt/mftr-mttr-aliases.s b/test/MC/Mips/mt/mftr-mttr-aliases.s new file mode 100644 index 00000000000..92ed9f9281f --- /dev/null +++ b/test/MC/Mips/mt/mftr-mttr-aliases.s @@ -0,0 +1,47 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt -show-encoding < %s | FileCheck %s + +# Check the various aliases of the m[ft]tr instruction. + + mftc0 $4, $5 # CHECK: mftr $4, $5, 0, 0, 0 # encoding: [0x41,0x05,0x20,0x00] + mftc0 $6, $7, 1 # CHECK: mftr $6, $7, 0, 1, 0 # encoding: [0x41,0x07,0x30,0x01] + mftgpr $5, $9 # CHECK: mftr $5, $9, 1, 0, 0 # encoding: [0x41,0x09,0x28,0x20] + mftlo $3 # CHECK: mftr $3, $zero, 1, 1, 0 # encoding: [0x41,0x00,0x18,0x21] + mftlo $3, $ac0 # CHECK: mftr $3, $zero, 1, 1, 0 # encoding: [0x41,0x00,0x18,0x21] + mftlo $3, $ac1 # CHECK: mftr $3, $4, 1, 1, 0 # encoding: [0x41,0x04,0x18,0x21] + mftlo $3, $ac2 # CHECK: mftr $3, $8, 1, 1, 0 # encoding: [0x41,0x08,0x18,0x21] + mftlo $3, $ac3 # CHECK: mftr $3, $12, 1, 1, 0 # encoding: [0x41,0x0c,0x18,0x21] + mfthi $3, $ac0 # CHECK: mftr $3, $1, 1, 1, 0 # encoding: [0x41,0x01,0x18,0x21] + mfthi $3, $ac1 # CHECK: mftr $3, $5, 1, 1, 0 # encoding: [0x41,0x05,0x18,0x21] + mfthi $3, $ac2 # CHECK: mftr $3, $9, 1, 1, 0 # encoding: [0x41,0x09,0x18,0x21] + mfthi $3, $ac3 # CHECK: mftr $3, $13, 1, 1, 0 # encoding: [0x41,0x0d,0x18,0x21] + mftacx $3, $ac0 # CHECK: mftr $3, $2, 1, 1, 0 # encoding: [0x41,0x02,0x18,0x21] + mftacx $3, $ac1 # CHECK: mftr $3, $6, 1, 1, 0 # encoding: [0x41,0x06,0x18,0x21] + mftacx $3, $ac2 # CHECK: mftr $3, $10, 1, 1, 0 # encoding: [0x41,0x0a,0x18,0x21] + mftacx $3, $ac3 # CHECK: mftr $3, $14, 1, 1, 0 # encoding: [0x41,0x0e,0x18,0x21] + mftdsp $4 # CHECK: mftr $4, $16, 1, 1, 0 # encoding: [0x41,0x10,0x20,0x21] + mftc1 $4, $f5 # CHECK: mftr $4, $5, 1, 2, 0 # encoding: [0x41,0x05,0x20,0x22] + mfthc1 $4, $f5 # CHECK: mftr $4, $5, 1, 2, 1 # encoding: [0x41,0x05,0x20,0x32] + cftc1 $4, $f9 # CHECK: mftr $4, $9, 1, 3, 0 # encoding: [0x41,0x09,0x20,0x23] + + mttc0 $4, $5 # CHECK: mttr $4, $5, 0, 0, 0 # encoding: [0x41,0x84,0x28,0x00] + mttc0 $6, $7, 1 # CHECK: mttr $6, $7, 0, 1, 0 # encoding: [0x41,0x86,0x38,0x01] + mttgpr $5, $9 # CHECK: mttr $5, $9, 1, 0, 0 # encoding: [0x41,0x85,0x48,0x20] + mttlo $3 # CHECK: mttr $3, $zero, 1, 1, 0 # encoding: [0x41,0x83,0x00,0x21] + mttlo $3, $ac0 # CHECK: mttr $3, $zero, 1, 1, 0 # encoding: [0x41,0x83,0x00,0x21] + mttlo $3, $ac1 # CHECK: mttr $3, $4, 1, 1, 0 # encoding: [0x41,0x83,0x20,0x21] + mttlo $3, $ac2 # CHECK: mttr $3, $8, 1, 1, 0 # encoding: [0x41,0x83,0x40,0x21] + mttlo $3, $ac3 # CHECK: mttr $3, $12, 1, 1, 0 # encoding: [0x41,0x83,0x60,0x21] + mtthi $3 # CHECK: mttr $3, $1, 1, 1, 0 # encoding: [0x41,0x83,0x08,0x21] + mtthi $3, $ac0 # CHECK: mttr $3, $1, 1, 1, 0 # encoding: [0x41,0x83,0x08,0x21] + mtthi $3, $ac1 # CHECK: mttr $3, $5, 1, 1, 0 # encoding: [0x41,0x83,0x28,0x21] + mtthi $3, $ac2 # CHECK: mttr $3, $9, 1, 1, 0 # encoding: [0x41,0x83,0x48,0x21] + mtthi $3, $ac3 # CHECK: mttr $3, $13, 1, 1, 0 # encoding: [0x41,0x83,0x68,0x21] + mttacx $3 # CHECK: mttr $3, $2, 1, 1, 0 # encoding: [0x41,0x83,0x10,0x21] + mttacx $3, $ac0 # CHECK: mttr $3, $2, 1, 1, 0 # encoding: [0x41,0x83,0x10,0x21] + mttacx $3, $ac1 # CHECK: mttr $3, $6, 1, 1, 0 # encoding: [0x41,0x83,0x30,0x21] + mttacx $3, $ac2 # CHECK: mttr $3, $10, 1, 1, 0 # encoding: [0x41,0x83,0x50,0x21] + mttacx $3, $ac3 # CHECK: mttr $3, $14, 1, 1, 0 # encoding: [0x41,0x83,0x70,0x21] + mttdsp $4 # CHECK: mttr $4, $16, 1, 1, 0 # encoding: [0x41,0x84,0x80,0x21] + mttc1 $4, $f5 # CHECK: mttr $4, $5, 1, 2, 0 # encoding: [0x41,0x84,0x28,0x22] + mtthc1 $4, $f5 # CHECK: mttr $4, $5, 1, 2, 1 # encoding: [0x41,0x84,0x28,0x32] + cttc1 $4, $f9 # CHECK: mttr $4, $9, 1, 3, 0 # encoding: [0x41,0x84,0x48,0x23] diff --git a/test/MC/Mips/mt/mftr-mttr-reserved-valid.s b/test/MC/Mips/mt/mftr-mttr-reserved-valid.s new file mode 100644 index 00000000000..c40e81bfc7d --- /dev/null +++ b/test/MC/Mips/mt/mftr-mttr-reserved-valid.s @@ -0,0 +1,8 @@ +# RUN: llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt -show-encoding < %s | FileCheck %s + +# The selector value and register values here are marked as reserved in the +# documentation, but GAS accepts them without warning. + mftr $31, $31, 1, 1, 0 # CHECK: mftr $ra, $ra, 1, 1, 0 # encoding: [0x41,0x1f,0xf8,0x21] + mttr $31, $31, 1, 1, 0 # CHECK: mttr $ra, $ra, 1, 1, 0 # encoding: [0x41,0x9f,0xf8,0x21] + mftr $31, $13, 1, 6, 0 # CHECK: mftr $ra, $13, 1, 6, 0 # encoding: [0x41,0x0d,0xf8,0x26] + mttr $31, $13, 1, 6, 0 # CHECK: mttr $ra, $13, 1, 6, 0 # encoding: [0x41,0x9f,0x68,0x26] diff --git a/test/MC/Mips/mt/module-directive-invalid.s b/test/MC/Mips/mt/module-directive-invalid.s index 38baaa07cdc..c5d563b5775 100644 --- a/test/MC/Mips/mt/module-directive-invalid.s +++ b/test/MC/Mips/mt/module-directive-invalid.s @@ -1,4 +1,5 @@ -# RUN: not llvm-mc -arch=mips -mcpu=mips32r5 < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -arch=mips -mcpu=mips32r5 %s 2>%t1 +# RUN: FileCheck %s < %t1 # CHECK: error: .module directive must appear before any code .set nomips16 diff --git a/test/MC/Mips/mt/valid.s b/test/MC/Mips/mt/valid.s index ab1179d05c6..9fa07870a61 100644 --- a/test/MC/Mips/mt/valid.s +++ b/test/MC/Mips/mt/valid.s @@ -1,13 +1,33 @@ # RUN: llvm-mc -arch=mips -mcpu=mips32r2 -mattr=+mt -show-encoding < %s \ # RUN: | FileCheck %s - dmt # CHECK: dmt # encoding: [0x41,0x60,0x0b,0xc1] - dmt $5 # CHECK: dmt $5 # encoding: [0x41,0x65,0x0b,0xc1] - emt # CHECK: emt # encoding: [0x41,0x60,0x0b,0xe1] - emt $4 # CHECK: emt $4 # encoding: [0x41,0x64,0x0b,0xe1] - dvpe # CHECK: dvpe # encoding: [0x41,0x60,0x00,0x01] - dvpe $6 # CHECK: dvpe $6 # encoding: [0x41,0x66,0x00,0x01] - evpe # CHECK: evpe # encoding: [0x41,0x60,0x00,0x21] - evpe $4 # CHECK: evpe $4 # encoding: [0x41,0x64,0x00,0x21] - fork $2, $3, $5 # CHECK: fork $2, $3, $5 # encoding: [0x7c,0x65,0x10,0x08] - yield $4 # CHECK: yield $4 # encoding: [0x7c,0x80,0x00,0x09] - yield $4, $5 # CHECK: yield $4, $5 # encoding: [0x7c,0xa0,0x20,0x09] + dmt # CHECK: dmt # encoding: [0x41,0x60,0x0b,0xc1] + dmt $5 # CHECK: dmt $5 # encoding: [0x41,0x65,0x0b,0xc1] + emt # CHECK: emt # encoding: [0x41,0x60,0x0b,0xe1] + emt $4 # CHECK: emt $4 # encoding: [0x41,0x64,0x0b,0xe1] + dvpe # CHECK: dvpe # encoding: [0x41,0x60,0x00,0x01] + dvpe $6 # CHECK: dvpe $6 # encoding: [0x41,0x66,0x00,0x01] + evpe # CHECK: evpe # encoding: [0x41,0x60,0x00,0x21] + evpe $4 # CHECK: evpe $4 # encoding: [0x41,0x64,0x00,0x21] + fork $2, $3, $5 # CHECK: fork $2, $3, $5 # encoding: [0x7c,0x65,0x10,0x08] + yield $4 # CHECK: yield $4 # encoding: [0x7c,0x80,0x00,0x09] + yield $4, $5 # CHECK: yield $4, $5 # encoding: [0x7c,0xa0,0x20,0x09] + mftr $4, $5, 0, 2, 0 # CHECK: mftr $4, $5, 0, 2, 0 # encoding: [0x41,0x05,0x20,0x02] + mftr $4, $5, 1, 0, 0 # CHECK: mftr $4, $5, 1, 0, 0 # encoding: [0x41,0x05,0x20,0x20] + mftr $4, $0, 1, 1, 0 # CHECK: mftr $4, $zero, 1, 1, 0 # encoding: [0x41,0x00,0x20,0x21] + mftr $4, $10, 1, 1, 0 # CHECK: mftr $4, $10, 1, 1, 0 # encoding: [0x41,0x0a,0x20,0x21] + mftr $4, $10, 1, 2, 0 # CHECK: mftr $4, $10, 1, 2, 0 # encoding: [0x41,0x0a,0x20,0x22] + mftr $4, $10, 1, 2, 1 # CHECK: mftr $4, $10, 1, 2, 1 # encoding: [0x41,0x0a,0x20,0x32] + mftr $4, $26, 1, 3, 0 # CHECK: mftr $4, $26, 1, 3, 0 # encoding: [0x41,0x1a,0x20,0x23] + mftr $4, $31, 1, 3, 0 # CHECK: mftr $4, $ra, 1, 3, 0 # encoding: [0x41,0x1f,0x20,0x23] + mftr $4, $14, 1, 4, 0 # CHECK: mftr $4, $14, 1, 4, 0 # encoding: [0x41,0x0e,0x20,0x24] + mftr $4, $15, 1, 5, 0 # CHECK: mftr $4, $15, 1, 5, 0 # encoding: [0x41,0x0f,0x20,0x25] + mttr $4, $5, 0, 2, 0 # CHECK: mttr $4, $5, 0, 2, 0 # encoding: [0x41,0x84,0x28,0x02] + mttr $4, $5, 1, 0, 0 # CHECK: mttr $4, $5, 1, 0, 0 # encoding: [0x41,0x84,0x28,0x20] + mttr $4, $0, 1, 1, 0 # CHECK: mttr $4, $zero, 1, 1, 0 # encoding: [0x41,0x84,0x00,0x21] + mttr $4, $10, 1, 1, 0 # CHECK: mttr $4, $10, 1, 1, 0 # encoding: [0x41,0x84,0x50,0x21] + mttr $4, $10, 1, 2, 0 # CHECK: mttr $4, $10, 1, 2, 0 # encoding: [0x41,0x84,0x50,0x22] + mttr $4, $10, 1, 2, 1 # CHECK: mttr $4, $10, 1, 2, 1 # encoding: [0x41,0x84,0x50,0x32] + mttr $4, $26, 1, 3, 0 # CHECK: mttr $4, $26, 1, 3, 0 # encoding: [0x41,0x84,0xd0,0x23] + mttr $4, $31, 1, 3, 0 # CHECK: mttr $4, $ra, 1, 3, 0 # encoding: [0x41,0x84,0xf8,0x23] + mttr $4, $14, 1, 4, 0 # CHECK: mttr $4, $14, 1, 4, 0 # encoding: [0x41,0x84,0x70,0x24] + mttr $4, $15, 1, 5, 0 # CHECK: mttr $4, $15, 1, 5, 0 # encoding: [0x41,0x84,0x78,0x25]