summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>2014-03-20 10:18:24 +0000
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>2014-03-20 10:18:24 +0000
commit3ac3e7451b93ee1d21380b75ad1432b9f28a076d (patch)
tree78ee6500d79bca12d0724cdb5bd537bf8f7dbecd
parentb71fd20f2d38e7e1a6f41bdc575196dd23ab716b (diff)
downloadllvm-3ac3e7451b93ee1d21380b75ad1432b9f28a076d.tar.gz
llvm-3ac3e7451b93ee1d21380b75ad1432b9f28a076d.tar.bz2
llvm-3ac3e7451b93ee1d21380b75ad1432b9f28a076d.tar.xz
Implementation of microMIPS 16-bit instructions MOVE and JALR.
Differential Revision: http://llvm-reviews.chandlerc.com/D3112 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204325 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/MicroMipsInstrFormats.td70
-rw-r--r--lib/Target/Mips/MicroMipsInstrInfo.td27
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp5
-rw-r--r--lib/Target/Mips/MipsISelLowering.h3
-rw-r--r--lib/Target/Mips/MipsInstrFormats.td2
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td10
-rw-r--r--lib/Target/Mips/MipsSEInstrInfo.cpp10
-rw-r--r--test/MC/Mips/micromips-16-bit-instructions.s21
-rw-r--r--test/MC/Mips/micromips-alu-instructions.s2
-rw-r--r--test/MC/Mips/micromips-jump-instructions.s6
10 files changed, 141 insertions, 15 deletions
diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td
index 9382099c9a..1dc8f428a3 100644
--- a/lib/Target/Mips/MicroMipsInstrFormats.td
+++ b/lib/Target/Mips/MicroMipsInstrFormats.td
@@ -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;
diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td
index 4147405571..588eacb8f2 100644
--- a/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -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
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index bee4700625..92250b8208 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -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.
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index af01035c6e..27492a8046 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -34,6 +34,9 @@ namespace llvm {
// Jump and link (call)
JmpLink,
+ // MicroMIPS Jump and link (call)
+ JmpLinkMM,
+
// Tail call
TailCall,
diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td
index 8926264594..1ee4d1387c 100644
--- a/lib/Target/Mips/MipsInstrFormats.td
+++ b/lib/Target/Mips/MipsInstrFormats.td
@@ -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;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index e4c6785aca..b6ee7b1b4c 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -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",
diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp
index 195ad8ee1c..3393dafe1d 100644
--- a/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -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;
diff --git a/test/MC/Mips/micromips-16-bit-instructions.s b/test/MC/Mips/micromips-16-bit-instructions.s
new file mode 100644
index 0000000000..453a3d59fc
--- /dev/null
+++ b/test/MC/Mips/micromips-16-bit-instructions.s
@@ -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
diff --git a/test/MC/Mips/micromips-alu-instructions.s b/test/MC/Mips/micromips-alu-instructions.s
index 276a83e82c..1131d1f3ea 100644
--- a/test/MC/Mips/micromips-alu-instructions.s
+++ b/test/MC/Mips/micromips-alu-instructions.s
@@ -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]
diff --git a/test/MC/Mips/micromips-jump-instructions.s b/test/MC/Mips/micromips-jump-instructions.s
index 6f571b6879..a6c7676f80 100644
--- a/test/MC/Mips/micromips-jump-instructions.s
+++ b/test/MC/Mips/micromips-jump-instructions.s
@@ -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