diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-19 19:03:11 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-19 19:03:11 +0000 |
commit | f530aff9de2738db0e3471b259ff0b577a6603e6 (patch) | |
tree | 5d0b518e0eb750162abaed89e5e3681a190f7850 | |
parent | 8d99ec574849ca8266e6491ceafee6c6029692b3 (diff) |
[mips] First patch which adds support for micromips.
This patch adds support for recoded (meaning assembly-language compatible to
standard mips32) arithmetic 32-bit instructions.
Patch by Zoran Jovanovic.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179873 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrFormats.td | 70 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrInfo.td | 39 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFormats.td | 30 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 71 |
5 files changed, 190 insertions, 35 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 5cdbcf4fe21..9460731c191 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -27,6 +27,9 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/raw_ostream.h" +#define GET_INSTRMAP_INFO +#include "MipsGenInstrInfo.inc" + using namespace llvm; namespace { @@ -35,12 +38,13 @@ class MipsMCCodeEmitter : public MCCodeEmitter { void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION; const MCInstrInfo &MCII; MCContext &Ctx; + const MCSubtargetInfo &STI; bool IsLittleEndian; public: MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, const MCSubtargetInfo &sti, bool IsLittle) : - MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) {} + MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {} ~MipsMCCodeEmitter() {} @@ -144,6 +148,15 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary) llvm_unreachable("unimplemented opcode in EncodeInstruction()"); + if (STI.getFeatureBits() & Mips::FeatureMicroMips) { + int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); + if (NewOpcode != -1) { + Opcode = NewOpcode; + TmpInst.setOpcode (NewOpcode); + Binary = getBinaryCodeForInstr(TmpInst, Fixups); + } + } + const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); // Get byte count of instruction diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td new file mode 100644 index 00000000000..adbcef51654 --- /dev/null +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -0,0 +1,70 @@ +class MMArch { + string Arch = "micromips"; + list<dag> Pattern = []; +} + +class ADD_FM_MM<bits<6> op, bits<10> funct> : MMArch { + bits<5> rt; + bits<5> rs; + bits<5> rd; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = rd; + let Inst{10} = 0; + let Inst{9-0} = funct; +} + +class ADDI_FM_MM<bits<6> op> : MMArch { + bits<5> rs; + bits<5> rt; + bits<16> imm16; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = imm16; +} + +class SLTI_FM_MM<bits<6> op> : MMArch { + bits<5> rt; + bits<5> rs; + bits<16> imm16; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-0} = imm16; +} + +class LUI_FM_MM : MMArch { + bits<5> rt; + bits<16> imm16; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = 0xd; + let Inst{20-16} = rt; + let Inst{15-0} = imm16; +} + +class MULT_FM_MM<bits<10> funct> : MMArch { + bits<5> rs; + bits<5> rt; + + bits<32> Inst; + + let Inst{31-26} = 0x00; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-6} = funct; + let Inst{5-0} = 0x3c; +} diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td new file mode 100644 index 00000000000..2f70da7ccd0 --- /dev/null +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -0,0 +1,39 @@ +let isCodeGenOnly = 1 in { + /// Arithmetic Instructions (ALU Immediate) + def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd>, + ADDI_FM_MM<0xc>; + def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, + ADDI_FM_MM<0x4>; + def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, + SLTI_FM_MM<0x24>; + def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, + SLTI_FM_MM<0x2c>; + def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, + ADDI_FM_MM<0x34>; + def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, + ADDI_FM_MM<0x14>; + def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, + ADDI_FM_MM<0x1c>; + def LUi_MM : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM_MM; + + /// Arithmetic Instructions (3-Operand, R-Type) + def ADDu_MM : MMRel, ArithLogicR<"addu", CPURegsOpnd>, ADD_FM_MM<0, 0x150>; + def SUBu_MM : MMRel, ArithLogicR<"subu", CPURegsOpnd>, ADD_FM_MM<0, 0x1d0>; + def MUL_MM : MMRel, ArithLogicR<"mul", CPURegsOpnd>, ADD_FM_MM<0, 0x210>; + def ADD_MM : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM_MM<0, 0x110>; + def SUB_MM : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM_MM<0, 0x190>; + def SLT_MM : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM_MM<0, 0x350>; + def SLTu_MM : MMRel, SetCC_R<"sltu", setult, CPURegs>, + ADD_FM_MM<0, 0x390>; + def AND_MM : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, + ADD_FM_MM<0, 0x250>; + def OR_MM : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, + ADD_FM_MM<0, 0x290>; + def XOR_MM : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, + ADD_FM_MM<0, 0x310>; + def NOR_MM : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM_MM<0, 0x2d0>; + def MULT_MM : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, + MULT_FM_MM<0x22c>; + def MULTu_MM : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, + MULT_FM_MM<0x26c>; +} diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index ee432c87535..03375db68e0 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -36,6 +36,24 @@ def FrmFR : Format<4>; def FrmFI : Format<5>; def FrmOther : Format<6>; // Instruction w/ a custom format +class MMRel; + +def Std2MicroMips : InstrMapping { + let FilterClass = "MMRel"; + // Instructions with the same BaseOpcode and isNVStore values form a row. + let RowFields = ["BaseOpcode"]; + // Instructions with the same predicate sense form a column. + let ColFields = ["Arch"]; + // The key column is the unpredicated instructions. + let KeyCol = ["se"]; + // Value columns are PredSense=true and PredSense=false + let ValueCols = [["se"], ["micromips"]]; +} + +class StdArch { + string Arch = "se"; +} + // Generic Mips Format class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, InstrItinClass itin, Format f>: Instruction @@ -74,9 +92,11 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, // Mips32/64 Instruction Format class InstSE<dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin, Format f>: + InstrItinClass itin, Format f, string opstr = ""> : MipsInst<outs, ins, asmstr, pattern, itin, f> { let Predicates = [HasStdEnc]; + string BaseOpcode = opstr; + string Arch; } // Mips Pseudo Instructions Format @@ -192,7 +212,7 @@ class MFC3OP_FM<bits<6> op, bits<5> mfmt> let Inst{2-0} = sel; } -class ADD_FM<bits<6> op, bits<6> funct> { +class ADD_FM<bits<6> op, bits<6> funct> : StdArch { bits<5> rd; bits<5> rs; bits<5> rt; @@ -207,7 +227,7 @@ class ADD_FM<bits<6> op, bits<6> funct> { let Inst{5-0} = funct; } -class ADDI_FM<bits<6> op> { +class ADDI_FM<bits<6> op> : StdArch { bits<5> rs; bits<5> rt; bits<16> imm16; @@ -288,7 +308,7 @@ class B_FM { let Inst{15-0} = offset; } -class SLTI_FM<bits<6> op> { +class SLTI_FM<bits<6> op> : StdArch { bits<5> rt; bits<5> rs; bits<16> imm16; @@ -413,7 +433,7 @@ class SYNC_FM { let Inst{5-0} = 0xf; } -class MULT_FM<bits<6> op, bits<6> funct> { +class MULT_FM<bits<6> op, bits<6> funct> : StdArch { bits<5> rs; bits<5> rt; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 44f7ed95099..1be7792807c 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -375,11 +375,9 @@ class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0, SDPatternOperator OpNode = null_frag>: InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> { + [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> { let isCommutable = isComm; let isReMaterializable = 1; - string BaseOpcode; - string Arch; } // Arithmetic and logical instructions with 2 register operands. @@ -388,7 +386,8 @@ class ArithLogicI<string opstr, Operand Od, RegisterOperand RO, SDPatternOperator OpNode = null_frag> : InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], IIAlu, FrmI> { + [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], + IIAlu, FrmI, opstr> { let isReMaterializable = 1; } @@ -405,7 +404,7 @@ class MArithR<string opstr, bit isComm = 0> : class LogicNOR<string opstr, RegisterOperand RC>: InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR> { + [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR, opstr> { let isCommutable = 1; } @@ -543,14 +542,15 @@ class CBranchZero<string opstr, PatFrag cond_op, RegisterClass RC> : class SetCC_R<string opstr, PatFrag cond_op, RegisterClass RC> : InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], IIAlu, FrmR>; + [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], + IIAlu, FrmR, opstr>; class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type, RegisterClass RC>: InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), [(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))], - IIAlu, FrmI>; + IIAlu, FrmI, opstr>; // Jump class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator, @@ -637,7 +637,7 @@ class SYNC_FT : class Mult<string opstr, InstrItinClass itin, RegisterOperand RO, list<Register> DefRegs> : InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [], - itin, FrmR> { + itin, FrmR, opstr> { let isCommutable = 1; let Defs = DefRegs; let neverHasSideEffects = 1; @@ -849,31 +849,39 @@ def COPY_AC64 : PseudoSE<(outs ACRegs:$dst), (ins ACRegs:$src), []>; //===----------------------------------------------------------------------===// /// Arithmetic Instructions (ALU Immediate) -def ADDiu : ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>, +def ADDiu : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>, ADDI_FM<0x9>, IsAsCheapAsAMove; -def ADDi : ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>; -def SLTi : SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, SLTI_FM<0xa>; -def SLTiu : SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, SLTI_FM<0xb>; -def ANDi : ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, +def ADDi : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>; +def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, + SLTI_FM<0xa>; +def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, + SLTI_FM<0xb>; +def ANDi : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, ADDI_FM<0xc>; -def ORi : ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, +def ORi : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, ADDI_FM<0xd>; -def XORi : ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, +def XORi : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, ADDI_FM<0xe>; -def LUi : LoadUpper<"lui", CPURegs, uimm16>, LUI_FM; +def LUi : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, ADD_FM<0, 0x21>; -def SUBu : ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, ADD_FM<0, 0x23>; -def MUL : ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, ADD_FM<0x1c, 2>; -def ADD : ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>; -def SUB : ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>; -def SLT : SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>; -def SLTu : SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>; -def AND : ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, ADD_FM<0, 0x24>; -def OR : ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, ADD_FM<0, 0x25>; -def XOR : ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, ADD_FM<0, 0x26>; -def NOR : LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>; +def ADDu : MMRel, ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, + ADD_FM<0, 0x21>; +def SUBu : MMRel, ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, + ADD_FM<0, 0x23>; +def MUL : MMRel, ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, + ADD_FM<0x1c, 2>; +def ADD : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>; +def SUB : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>; +def SLT : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>; +def SLTu : MMRel, SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>; +def AND : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, + ADD_FM<0, 0x24>; +def OR : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, + ADD_FM<0, 0x25>; +def XOR : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, + ADD_FM<0, 0x26>; +def NOR : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>; /// Shift Instructions def SLL : shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>, @@ -969,8 +977,10 @@ let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in { } /// Multiply and Divide Instructions. -def MULT : Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x18>; -def MULTu : Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x19>; +def MULT : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, + MULT_FM<0, 0x18>; +def MULTu : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, + MULT_FM<0, 0x19>; def PseudoMULT : MultDivPseudo<MULT, ACRegs, CPURegsOpnd, MipsMult, IIImul>; def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, CPURegsOpnd, MipsMultu, IIImul>; def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>; @@ -1329,3 +1339,6 @@ include "Mips16InstrInfo.td" include "MipsDSPInstrFormats.td" include "MipsDSPInstrInfo.td" +// Micromips +include "MicroMipsInstrFormats.td" +include "MicroMipsInstrInfo.td" |