Skip to content

Commit 52e96d1

Browse files
author
Simon Dardis
committed
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
1 parent 399df16 commit 52e96d1

16 files changed

+547
-14
lines changed

lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ class MipsAsmParser : public MCTargetAsmParser {
304304
bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305305
const MCSubtargetInfo *STI);
306306

307+
bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308+
const MCSubtargetInfo *STI);
309+
307310
bool reportParseError(Twine ErrorMsg);
308311
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
309312

@@ -2511,6 +2514,16 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
25112514
return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
25122515
case Mips::SEQIMacro:
25132516
return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2517+
case Mips::MFTC0: case Mips::MTTC0:
2518+
case Mips::MFTGPR: case Mips::MTTGPR:
2519+
case Mips::MFTLO: case Mips::MTTLO:
2520+
case Mips::MFTHI: case Mips::MTTHI:
2521+
case Mips::MFTACX: case Mips::MTTACX:
2522+
case Mips::MFTDSP: case Mips::MTTDSP:
2523+
case Mips::MFTC1: case Mips::MTTC1:
2524+
case Mips::MFTHC1: case Mips::MTTHC1:
2525+
case Mips::CFTC1: case Mips::CTTC1:
2526+
return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
25142527
}
25152528
}
25162529

@@ -4882,6 +4895,212 @@ bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
48824895
return false;
48834896
}
48844897

4898+
// Map the DSP accumulator and control register to the corresponding gpr
4899+
// operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
4900+
// do not map the DSP registers contigously to gpr registers.
4901+
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
4902+
switch (Inst.getOpcode()) {
4903+
case Mips::MFTLO:
4904+
case Mips::MTTLO:
4905+
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4906+
case Mips::AC0:
4907+
return Mips::ZERO;
4908+
case Mips::AC1:
4909+
return Mips::A0;
4910+
case Mips::AC2:
4911+
return Mips::T0;
4912+
case Mips::AC3:
4913+
return Mips::T4;
4914+
default:
4915+
llvm_unreachable("Unknown register for 'mttr' alias!");
4916+
}
4917+
case Mips::MFTHI:
4918+
case Mips::MTTHI:
4919+
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4920+
case Mips::AC0:
4921+
return Mips::AT;
4922+
case Mips::AC1:
4923+
return Mips::A1;
4924+
case Mips::AC2:
4925+
return Mips::T1;
4926+
case Mips::AC3:
4927+
return Mips::T5;
4928+
default:
4929+
llvm_unreachable("Unknown register for 'mttr' alias!");
4930+
}
4931+
case Mips::MFTACX:
4932+
case Mips::MTTACX:
4933+
switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) {
4934+
case Mips::AC0:
4935+
return Mips::V0;
4936+
case Mips::AC1:
4937+
return Mips::A2;
4938+
case Mips::AC2:
4939+
return Mips::T2;
4940+
case Mips::AC3:
4941+
return Mips::T6;
4942+
default:
4943+
llvm_unreachable("Unknown register for 'mttr' alias!");
4944+
}
4945+
case Mips::MFTDSP:
4946+
case Mips::MTTDSP:
4947+
return Mips::S0;
4948+
default:
4949+
llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
4950+
}
4951+
}
4952+
4953+
// Map the floating point register operand to the corresponding register
4954+
// operand.
4955+
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
4956+
switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) {
4957+
case Mips::F0: return Mips::ZERO;
4958+
case Mips::F1: return Mips::AT;
4959+
case Mips::F2: return Mips::V0;
4960+
case Mips::F3: return Mips::V1;
4961+
case Mips::F4: return Mips::A0;
4962+
case Mips::F5: return Mips::A1;
4963+
case Mips::F6: return Mips::A2;
4964+
case Mips::F7: return Mips::A3;
4965+
case Mips::F8: return Mips::T0;
4966+
case Mips::F9: return Mips::T1;
4967+
case Mips::F10: return Mips::T2;
4968+
case Mips::F11: return Mips::T3;
4969+
case Mips::F12: return Mips::T4;
4970+
case Mips::F13: return Mips::T5;
4971+
case Mips::F14: return Mips::T6;
4972+
case Mips::F15: return Mips::T7;
4973+
case Mips::F16: return Mips::S0;
4974+
case Mips::F17: return Mips::S1;
4975+
case Mips::F18: return Mips::S2;
4976+
case Mips::F19: return Mips::S3;
4977+
case Mips::F20: return Mips::S4;
4978+
case Mips::F21: return Mips::S5;
4979+
case Mips::F22: return Mips::S6;
4980+
case Mips::F23: return Mips::S7;
4981+
case Mips::F24: return Mips::T8;
4982+
case Mips::F25: return Mips::T9;
4983+
case Mips::F26: return Mips::K0;
4984+
case Mips::F27: return Mips::K1;
4985+
case Mips::F28: return Mips::GP;
4986+
case Mips::F29: return Mips::SP;
4987+
case Mips::F30: return Mips::FP;
4988+
case Mips::F31: return Mips::RA;
4989+
default: llvm_unreachable("Unknown register for mttc1 alias!");
4990+
}
4991+
}
4992+
4993+
// Map the coprocessor operand the corresponding gpr register operand.
4994+
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
4995+
switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) {
4996+
case Mips::COP00: return Mips::ZERO;
4997+
case Mips::COP01: return Mips::AT;
4998+
case Mips::COP02: return Mips::V0;
4999+
case Mips::COP03: return Mips::V1;
5000+
case Mips::COP04: return Mips::A0;
5001+
case Mips::COP05: return Mips::A1;
5002+
case Mips::COP06: return Mips::A2;
5003+
case Mips::COP07: return Mips::A3;
5004+
case Mips::COP08: return Mips::T0;
5005+
case Mips::COP09: return Mips::T1;
5006+
case Mips::COP010: return Mips::T2;
5007+
case Mips::COP011: return Mips::T3;
5008+
case Mips::COP012: return Mips::T4;
5009+
case Mips::COP013: return Mips::T5;
5010+
case Mips::COP014: return Mips::T6;
5011+
case Mips::COP015: return Mips::T7;
5012+
case Mips::COP016: return Mips::S0;
5013+
case Mips::COP017: return Mips::S1;
5014+
case Mips::COP018: return Mips::S2;
5015+
case Mips::COP019: return Mips::S3;
5016+
case Mips::COP020: return Mips::S4;
5017+
case Mips::COP021: return Mips::S5;
5018+
case Mips::COP022: return Mips::S6;
5019+
case Mips::COP023: return Mips::S7;
5020+
case Mips::COP024: return Mips::T8;
5021+
case Mips::COP025: return Mips::T9;
5022+
case Mips::COP026: return Mips::K0;
5023+
case Mips::COP027: return Mips::K1;
5024+
case Mips::COP028: return Mips::GP;
5025+
case Mips::COP029: return Mips::SP;
5026+
case Mips::COP030: return Mips::FP;
5027+
case Mips::COP031: return Mips::RA;
5028+
default: llvm_unreachable("Unknown register for mttc0 alias!");
5029+
}
5030+
}
5031+
5032+
/// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5033+
/// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
5034+
bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5035+
const MCSubtargetInfo *STI) {
5036+
MipsTargetStreamer &TOut = getTargetStreamer();
5037+
unsigned rd = 0;
5038+
unsigned u = 1;
5039+
unsigned sel = 0;
5040+
unsigned h = 0;
5041+
bool IsMFTR = false;
5042+
switch (Inst.getOpcode()) {
5043+
case Mips::MFTC0:
5044+
IsMFTR = true;
5045+
LLVM_FALLTHROUGH;
5046+
case Mips::MTTC0:
5047+
u = 0;
5048+
rd = getRegisterForMxtrC0(Inst, IsMFTR);
5049+
sel = Inst.getOperand(2).getImm();
5050+
break;
5051+
case Mips::MFTGPR:
5052+
IsMFTR = true;
5053+
LLVM_FALLTHROUGH;
5054+
case Mips::MTTGPR:
5055+
rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5056+
break;
5057+
case Mips::MFTLO:
5058+
case Mips::MFTHI:
5059+
case Mips::MFTACX:
5060+
case Mips::MFTDSP:
5061+
IsMFTR = true;
5062+
LLVM_FALLTHROUGH;
5063+
case Mips::MTTLO:
5064+
case Mips::MTTHI:
5065+
case Mips::MTTACX:
5066+
case Mips::MTTDSP:
5067+
rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5068+
sel = 1;
5069+
break;
5070+
case Mips::MFTHC1:
5071+
h = 1;
5072+
LLVM_FALLTHROUGH;
5073+
case Mips::MFTC1:
5074+
IsMFTR = true;
5075+
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5076+
sel = 2;
5077+
break;
5078+
case Mips::MTTHC1:
5079+
h = 1;
5080+
LLVM_FALLTHROUGH;
5081+
case Mips::MTTC1:
5082+
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5083+
sel = 2;
5084+
break;
5085+
case Mips::CFTC1:
5086+
IsMFTR = true;
5087+
LLVM_FALLTHROUGH;
5088+
case Mips::CTTC1:
5089+
rd = getRegisterForMxtrFP(Inst, IsMFTR);
5090+
sel = 3;
5091+
break;
5092+
}
5093+
unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd;
5094+
unsigned Op1 =
5095+
IsMFTR ? rd
5096+
: (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5097+
: Inst.getOperand(0).getReg());
5098+
5099+
TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5100+
STI);
5101+
return false;
5102+
}
5103+
48855104
unsigned
48865105
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
48875106
const OperandVector &Operands) {

lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
193193
emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
194194
}
195195

196+
void MipsTargetStreamer::emitRRIII(unsigned Opcode, unsigned Reg0,
197+
unsigned Reg1, int16_t Imm0, int16_t Imm1,
198+
int16_t Imm2, SMLoc IDLoc,
199+
const MCSubtargetInfo *STI) {
200+
MCInst TmpInst;
201+
TmpInst.setOpcode(Opcode);
202+
TmpInst.addOperand(MCOperand::createReg(Reg0));
203+
TmpInst.addOperand(MCOperand::createReg(Reg1));
204+
TmpInst.addOperand(MCOperand::createImm(Imm0));
205+
TmpInst.addOperand(MCOperand::createImm(Imm1));
206+
TmpInst.addOperand(MCOperand::createImm(Imm2));
207+
TmpInst.setLoc(IDLoc);
208+
getStreamer().EmitInstruction(TmpInst, *STI);
209+
}
210+
196211
void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
197212
unsigned TrgReg, bool Is64Bit,
198213
const MCSubtargetInfo *STI) {

lib/Target/Mips/MipsMTInstrFormats.td

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class FIELD5<bits<5> Val> {
3535
def FIELD5_1_DMT_EMT : FIELD5<0b00001>;
3636
def FIELD5_2_DMT_EMT : FIELD5<0b01111>;
3737
def FIELD5_1_2_DVPE_EVPE : FIELD5<0b00000>;
38+
def FIELD5_MFTR : FIELD5<0b01000>;
39+
def FIELD5_MTTR : FIELD5<0b01100>;
3840

3941
class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
4042
bits<32> Inst;
@@ -50,6 +52,25 @@ class COP0_MFMC0_MT<FIELD5 Op1, FIELD5 Op2, OPCODE1 sc> : MipsMTInst {
5052
let Inst{2-0} = 0b001;
5153
}
5254

55+
class COP0_MFTTR_MT<FIELD5 Op> : MipsMTInst {
56+
bits<32> Inst;
57+
58+
bits<5> rt;
59+
bits<5> rd;
60+
bits<1> u;
61+
bits<1> h;
62+
bits<3> sel;
63+
let Inst{31-26} = 0b010000; // COP0
64+
let Inst{25-21} = Op.Value; // MFMC0
65+
let Inst{20-16} = rt;
66+
let Inst{15-11} = rd;
67+
let Inst{10-6} = 0b00000; // rx - currently unsupported.
68+
let Inst{5} = u;
69+
let Inst{4} = h;
70+
let Inst{3} = 0b0;
71+
let Inst{2-0} = sel;
72+
}
73+
5374
class SPECIAL3_MT_FORK : MipsMTInst {
5475
bits<32> Inst;
5576

0 commit comments

Comments
 (0)