Reland "[mips][mt][6/7] Add support for mftr, mttr instructions.""

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

The last version of this patch broke one of the expensive checks buildbots,
this version changes the failing test/MC/Mips/mt/invalid.s and other invalid
tests to write the errors to a file and run FileCheck on that, rather than
relying on the 'not llvm-mc ... <%s 2>&1 | Filecheck %s' idiom.

Hopefully this will sarisfy the buildbot.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308023 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Simon Dardis 2017-07-14 13:44:12 +00:00
parent 8f691f1275
commit f98930962b
16 changed files with 573 additions and 27 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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,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;
}

View File

@ -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]>]>,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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]