From 35c85f0c119d4c84116145bee13b78847d8f9d18 Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Thu, 20 Mar 2014 10:18:24 +0000 Subject: [PATCH] Implementation of microMIPS 16-bit instructions MOVE and JALR. Differential Revision: http://llvm-reviews.chandlerc.com/D3112 llvm-svn: 204325 --- lib/Target/Mips/MicroMipsInstrFormats.td | 70 +++++++++++++++++++- lib/Target/Mips/MicroMipsInstrInfo.td | 27 +++++++- lib/Target/Mips/MipsISelLowering.cpp | 5 +- lib/Target/Mips/MipsISelLowering.h | 3 + lib/Target/Mips/MipsInstrFormats.td | 2 +- lib/Target/Mips/MipsInstrInfo.td | 10 ++- lib/Target/Mips/MipsSEInstrInfo.cpp | 10 ++- test/MC/Mips/micromips-16-bit-instructions.s | 21 ++++++ test/MC/Mips/micromips-alu-instructions.s | 2 - test/MC/Mips/micromips-jump-instructions.s | 6 +- 10 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 test/MC/Mips/micromips-16-bit-instructions.s diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 9382099c9a0..1dc8f428a33 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 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 pattern, + InstrItinClass itin, Format f> : + MicroMipsInstBase +{ + 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 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 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 Pattern = []; @@ -226,7 +294,7 @@ class JR_FM_MM funct> : MMArch { let Inst{5-0} = 0x3c; } -class JALR_FM_MM funct> : MMArch { +class JALR_FM_MM funct> { bits<5> rs; bits<5> rd; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 41474055711..588eacb8f2f 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -70,6 +70,31 @@ class LoadMM : + 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 : + 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 bee47006256..92250b82088 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 af01035c6ed..27492a8046c 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 8926264594e..1ee4d1387ce 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 e4c6785aca9..b6ee7b1b4cd 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: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [], IIBranch, FrmR, opstr>; + [], IIBranch, FrmR>; class BGEZAL_FT : InstSE<(outs), (ins RO:$rs, opnd:$offset), @@ -1042,7 +1042,9 @@ def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, def B : UncondBranch; 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; 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 195ad8ee1cc..3393dafe1d3 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().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 00000000000..453a3d59fcc --- /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 276a83e82c0..1131d1f3eae 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 6f571b68791..a6c7676f809 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