mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Implementation of microMIPS 16-bit instructions MOVE and JALR.
Differential Revision: http://llvm-reviews.chandlerc.com/D3112 llvm-svn: 204325
This commit is contained in:
parent
2b07814904
commit
35c85f0c11
@ -1,3 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MicroMIPS Base Classes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//
|
||||
// Base class for MicroMips instructions.
|
||||
// This class does not depend on the instruction size.
|
||||
//
|
||||
class MicroMipsInstBase<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin, Format f> : Instruction
|
||||
{
|
||||
let Namespace = "Mips";
|
||||
let DecoderNamespace = "MicroMips";
|
||||
|
||||
let OutOperandList = outs;
|
||||
let InOperandList = ins;
|
||||
|
||||
let AsmString = asmstr;
|
||||
let Pattern = pattern;
|
||||
let Itinerary = itin;
|
||||
|
||||
let Predicates = [InMicroMips];
|
||||
|
||||
Format Form = f;
|
||||
}
|
||||
|
||||
//
|
||||
// Base class for MicroMIPS 16-bit instructions.
|
||||
//
|
||||
class MicroMipsInst16<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin, Format f> :
|
||||
MicroMipsInstBase<outs, ins, asmstr, pattern, itin, f>
|
||||
{
|
||||
let Size = 2;
|
||||
field bits<16> Inst;
|
||||
field bits<16> SoftFail = 0;
|
||||
bits<6> Opcode = 0x0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MicroMIPS 16-bit Instruction Formats
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class MOVE_FM_MM16<bits<6> funct> {
|
||||
bits<5> rs;
|
||||
bits<5> rd;
|
||||
|
||||
bits<16> Inst;
|
||||
|
||||
let Inst{15-10} = funct;
|
||||
let Inst{9-5} = rd;
|
||||
let Inst{4-0} = rs;
|
||||
}
|
||||
|
||||
class JALR_FM_MM16<bits<5> op> {
|
||||
bits<5> rs;
|
||||
|
||||
bits<16> Inst;
|
||||
|
||||
let Inst{15-10} = 0x11;
|
||||
let Inst{9-5} = op;
|
||||
let Inst{4-0} = rs;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MicroMIPS 32-bit Instruction Formats
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class MMArch {
|
||||
string Arch = "micromips";
|
||||
list<dag> Pattern = [];
|
||||
@ -226,7 +294,7 @@ class JR_FM_MM<bits<8> funct> : MMArch {
|
||||
let Inst{5-0} = 0x3c;
|
||||
}
|
||||
|
||||
class JALR_FM_MM<bits<10> funct> : MMArch {
|
||||
class JALR_FM_MM<bits<10> funct> {
|
||||
bits<5> rs;
|
||||
bits<5> rd;
|
||||
|
||||
|
@ -70,6 +70,31 @@ class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
class MoveMM16<string opstr, RegisterOperand RO, bit isComm = 0,
|
||||
InstrItinClass Itin = NoItinerary> :
|
||||
MicroMipsInst16<(outs RO:$rd), (ins RO:$rs),
|
||||
!strconcat(opstr, "\t$rd, $rs"), [], Itin, FrmR> {
|
||||
let isCommutable = isComm;
|
||||
let isReMaterializable = 1;
|
||||
}
|
||||
|
||||
// MicroMIPS Call
|
||||
def MicroMipsJmpLink : SDNode<"MipsISD::JmpLinkMM",SDT_MipsJmpLink,
|
||||
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
|
||||
SDNPVariadic]>;
|
||||
|
||||
// 16-bit Jump and Link (Call)
|
||||
class JumpLinkRegMM16<string opstr, RegisterOperand RO> :
|
||||
MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"),
|
||||
[(MicroMipsJmpLink RO:$rs)], IIBranch, FrmR> {
|
||||
let isCall = 1;
|
||||
let hasDelaySlot = 1;
|
||||
let Defs = [RA];
|
||||
}
|
||||
|
||||
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>;
|
||||
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>;
|
||||
|
||||
let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
|
||||
/// Arithmetic Instructions (ALU Immediate)
|
||||
def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>,
|
||||
@ -207,7 +232,7 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
|
||||
def JAL_MM : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>;
|
||||
}
|
||||
def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>;
|
||||
def JALR_MM : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>;
|
||||
def JALR_MM : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>;
|
||||
def RET_MM : MMRel, RetBase<"ret", GPR32Opnd>, JR_FM_MM<0x3c>;
|
||||
|
||||
/// Branch Instructions
|
||||
|
@ -115,6 +115,7 @@ SDValue MipsTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty,
|
||||
const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
case MipsISD::JmpLink: return "MipsISD::JmpLink";
|
||||
case MipsISD::JmpLinkMM: return "MipsISD::JmpLinkMM";
|
||||
case MipsISD::TailCall: return "MipsISD::TailCall";
|
||||
case MipsISD::Hi: return "MipsISD::Hi";
|
||||
case MipsISD::Lo: return "MipsISD::Lo";
|
||||
@ -2543,7 +2544,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
if (IsTailCall)
|
||||
return DAG.getNode(MipsISD::TailCall, DL, MVT::Other, &Ops[0], Ops.size());
|
||||
|
||||
Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, &Ops[0], Ops.size());
|
||||
MipsISD::NodeType JmpLink = isMicroMips ? MipsISD::JmpLinkMM
|
||||
: MipsISD::JmpLink;
|
||||
Chain = DAG.getNode(JmpLink, DL, NodeTys, &Ops[0], Ops.size());
|
||||
SDValue InFlag = Chain.getValue(1);
|
||||
|
||||
// Create the CALLSEQ_END node.
|
||||
|
@ -34,6 +34,9 @@ namespace llvm {
|
||||
// Jump and link (call)
|
||||
JmpLink,
|
||||
|
||||
// MicroMIPS Jump and link (call)
|
||||
JmpLinkMM,
|
||||
|
||||
// Tail call
|
||||
TailCall,
|
||||
|
||||
|
@ -375,7 +375,7 @@ class LUI_FM : StdArch {
|
||||
let Inst{15-0} = imm16;
|
||||
}
|
||||
|
||||
class JALR_FM : StdArch {
|
||||
class JALR_FM {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
|
||||
|
@ -616,7 +616,7 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in {
|
||||
|
||||
class JumpLinkReg<string opstr, RegisterOperand RO>:
|
||||
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
|
||||
[], IIBranch, FrmR, opstr>;
|
||||
[], IIBranch, FrmR>;
|
||||
|
||||
class BGEZAL_FT<string opstr, DAGOperand opnd, RegisterOperand RO> :
|
||||
InstSE<(outs), (ins RO:$rs, opnd:$offset),
|
||||
@ -1042,7 +1042,9 @@ def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
|
||||
def B : UncondBranch<BEQ>;
|
||||
|
||||
def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
|
||||
def JALR : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
|
||||
let Predicates = [NotInMicroMips] in {
|
||||
def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
|
||||
}
|
||||
def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>;
|
||||
def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
|
||||
def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>;
|
||||
@ -1148,7 +1150,7 @@ def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>;
|
||||
//===----------------------------------------------------------------------===//
|
||||
def : InstAlias<"move $dst, $src",
|
||||
(ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
|
||||
Requires<[NotMips64]>;
|
||||
Requires<[NotMips64, NotInMicroMips]>;
|
||||
def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
|
||||
def : InstAlias<"addu $rs, $rt, $imm",
|
||||
(ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
|
||||
@ -1157,7 +1159,9 @@ def : InstAlias<"add $rs, $rt, $imm",
|
||||
def : InstAlias<"and $rs, $rt, $imm",
|
||||
(ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
|
||||
def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
|
||||
let Predicates = [NotInMicroMips] in {
|
||||
def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
|
||||
}
|
||||
def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
|
||||
def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
|
||||
def : InstAlias<"not $rt, $rs",
|
||||
|
@ -84,11 +84,15 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const {
|
||||
unsigned Opc = 0, ZeroReg = 0;
|
||||
bool isMicroMips = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode();
|
||||
|
||||
if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.
|
||||
if (Mips::GPR32RegClass.contains(SrcReg))
|
||||
Opc = Mips::ADDu, ZeroReg = Mips::ZERO;
|
||||
else if (Mips::CCRRegClass.contains(SrcReg))
|
||||
if (Mips::GPR32RegClass.contains(SrcReg)) {
|
||||
if (isMicroMips)
|
||||
Opc = Mips::MOVE16_MM;
|
||||
else
|
||||
Opc = Mips::ADDu, ZeroReg = Mips::ZERO;
|
||||
} else if (Mips::CCRRegClass.contains(SrcReg))
|
||||
Opc = Mips::CFC1;
|
||||
else if (Mips::FGR32RegClass.contains(SrcReg))
|
||||
Opc = Mips::MFC1;
|
||||
|
21
test/MC/Mips/micromips-16-bit-instructions.s
Normal file
21
test/MC/Mips/micromips-16-bit-instructions.s
Normal file
@ -0,0 +1,21 @@
|
||||
# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips | \
|
||||
# RUN: FileCheck -check-prefix=CHECK-EL %s
|
||||
# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips | \
|
||||
# RUN: FileCheck -check-prefix=CHECK-EB %s
|
||||
# Check that the assembler can handle the documented syntax
|
||||
# for arithmetic and logical instructions.
|
||||
#------------------------------------------------------------------------------
|
||||
# MicroMIPS 16-bit Instructions
|
||||
#------------------------------------------------------------------------------
|
||||
# Little endian
|
||||
#------------------------------------------------------------------------------
|
||||
# CHECK-EL: move $25, $1 # encoding: [0x21,0x0f]
|
||||
# CHECK-EL: jalr $9 # encoding: [0xc9,0x45]
|
||||
#------------------------------------------------------------------------------
|
||||
# Big endian
|
||||
#------------------------------------------------------------------------------
|
||||
# CHECK-EB: move $25, $1 # encoding: [0x0f,0x21]
|
||||
# CHECK-EB: jalr $9 # encoding: [0x45,0xc9]
|
||||
|
||||
move $25, $1
|
||||
jalr $9
|
@ -17,7 +17,6 @@
|
||||
# CHECK-EL: subu $4, $3, $5 # encoding: [0xa3,0x00,0xd0,0x21]
|
||||
# CHECK-EL: neg $6, $7 # encoding: [0xe0,0x00,0x90,0x31]
|
||||
# CHECK-EL: negu $6, $7 # encoding: [0xe0,0x00,0xd0,0x31]
|
||||
# CHECK-EL: move $7, $8 # encoding: [0x08,0x00,0x50,0x39]
|
||||
# CHECK-EL: slt $3, $3, $5 # encoding: [0xa3,0x00,0x50,0x1b]
|
||||
# CHECK-EL: slti $3, $3, 103 # encoding: [0x63,0x90,0x67,0x00]
|
||||
# CHECK-EL: slti $3, $3, 103 # encoding: [0x63,0x90,0x67,0x00]
|
||||
@ -52,7 +51,6 @@
|
||||
# CHECK-EB: subu $4, $3, $5 # encoding: [0x00,0xa3,0x21,0xd0]
|
||||
# CHECK-EB: neg $6, $7 # encoding: [0x00,0xe0,0x31,0x90]
|
||||
# CHECK-EB: negu $6, $7 # encoding: [0x00,0xe0,0x31,0xd0]
|
||||
# CHECK-EB: move $7, $8 # encoding: [0x00,0x08,0x39,0x50]
|
||||
# CHECK-EB: slt $3, $3, $5 # encoding: [0x00,0xa3,0x1b,0x50]
|
||||
# CHECK-EB: slti $3, $3, 103 # encoding: [0x90,0x63,0x00,0x67]
|
||||
# CHECK-EB: slti $3, $3, 103 # encoding: [0x90,0x63,0x00,0x67]
|
||||
|
@ -13,7 +13,7 @@
|
||||
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EL: jal 1328 # encoding: [0x00,0xf4,0x98,0x02]
|
||||
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EL: jalr $6 # encoding: [0xe6,0x03,0x3c,0x0f]
|
||||
# CHECK-EL: jalr $ra, $6 # encoding: [0xe6,0x03,0x3c,0x0f]
|
||||
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EL: jr $7 # encoding: [0x07,0x00,0x3c,0x0f]
|
||||
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
@ -26,7 +26,7 @@
|
||||
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EB: jal 1328 # encoding: [0xf4,0x00,0x02,0x98]
|
||||
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EB: jalr $6 # encoding: [0x03,0xe6,0x0f,0x3c]
|
||||
# CHECK-EB: jalr $ra, $6 # encoding: [0x03,0xe6,0x0f,0x3c]
|
||||
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
# CHECK-EB: jr $7 # encoding: [0x00,0x07,0x0f,0x3c]
|
||||
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||
@ -35,6 +35,6 @@
|
||||
|
||||
j 1328
|
||||
jal 1328
|
||||
jalr $6
|
||||
jalr $ra, $6
|
||||
jr $7
|
||||
j $7
|
||||
|
Loading…
Reference in New Issue
Block a user