diff options
Diffstat (limited to 'lib/Target/Mips/Mips16InstrInfo.td')
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 148 |
1 files changed, 122 insertions, 26 deletions
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index aef4e92..7441c78 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -32,6 +32,16 @@ def mem16_ea : Operand<i32> { } // +// I-type instruction format +// +// this is only used by bimm. the actual assembly value is a 12 bit signed +// number +// +class FI16_ins<bits<5> op, string asmstr, InstrItinClass itin>: + FI16<op, (outs), (ins brtarget:$imm16), + !strconcat(asmstr, "\t$imm16 # 16 bit inst"), [], itin>; + +// // // I8 instruction format // @@ -41,7 +51,10 @@ class FI816_ins_base<bits<3> _func, string asmstr, FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2), [], itin>; - +class FI816_ins<bits<3> _func, string asmstr, + InstrItinClass itin>: + FI816_ins_base<_func, asmstr, "\t$imm # 16 bit inst", itin>; + class FI816_SP_ins<bits<3> _func, string asmstr, InstrItinClass itin>: FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>; @@ -60,6 +73,11 @@ class FRI16_ins<bits<5> op, string asmstr, InstrItinClass itin>: FRI16_ins_base<op, asmstr, "\t$rx, $imm \t# 16 bit inst", itin>; +class FRI16_TCP_ins<bits<5> _op, string asmstr, + InstrItinClass itin>: + FRI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size), + !strconcat(asmstr, "\t$rx, $imm\t# 16 bit inst"), [], itin>; + class FRI16R_ins_base<bits<5> op, string asmstr, string asmstr2, InstrItinClass itin>: FRI16<op, (outs), (ins CPU16Regs:$rx, simm16:$imm), @@ -172,6 +190,11 @@ class FEXT_RI16_B_ins<bits<5> _op, string asmstr, FEXT_RI16<_op, (outs), (ins CPU16Regs:$rx, brtarget:$imm), !strconcat(asmstr, "\t$rx, $imm"), [], itin>; +class FEXT_RI16_TCP_ins<bits<5> _op, string asmstr, + InstrItinClass itin>: + FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins pcrel16:$imm, i32imm:$size), + !strconcat(asmstr, "\t$rx, $imm"), [], itin>; + class FEXT_2RI16_ins<bits<5> _op, string asmstr, InstrItinClass itin>: FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_, simm16:$imm), @@ -220,7 +243,7 @@ class FEXT_RRI_A16_mem_ins<bits<1> op, string asmstr, Operand MemOpnd, // EXT-SHIFT instruction format // class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>: - FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, shamt:$sa), + FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa), !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>; // @@ -343,6 +366,14 @@ class FRR16_JALRC_ins<bits<1> nd, bits<1> l, bits<1> ra, FRR16_JALRC<nd, l, ra, (outs), (ins CPU16Regs:$rx), !strconcat(asmstr, "\t $rx"), [], itin> ; +class FRR_SF16_ins + <bits<5> _funct, bits<3> _subfunc, + string asmstr, InstrItinClass itin>: + FRR_SF16<_funct, _subfunc, (outs CPU16Regs:$rx), (ins CPU16Regs:$rx_), + !strconcat(asmstr, "\t $rx"), + [], itin> { + let Constraints = "$rx_ = $rx"; + } // // RRR-type instruction format // @@ -447,7 +478,7 @@ def Constant32: MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>; def LwConstant32: - MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm), + MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm, imm32:$constid), "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>; @@ -559,6 +590,14 @@ def BeqzRxImm16: FRI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; // def BeqzRxImmX16: FEXT_RI16_B_ins<0b00100, "beqz", IIAlu>, cbranch16; +// +// Format: B offset MIPS16e +// Purpose: Unconditional Branch (Extended) +// To do an unconditional PC-relative branch. +// + +def Bimm16: FI16_ins<0b00010, "b", IIAlu>, branch16; + // Format: B offset MIPS16e // Purpose: Unconditional Branch // To do an unconditional PC-relative branch. @@ -591,6 +630,10 @@ def Break16: FRRBreakNull16_ins<"break 0", NoItinerary>; // Purpose: Branch on T Equal to Zero (Extended) // To test special register T then do a PC-relative conditional branch. // +def Bteqz16: FI816_ins<0b000, "bteqz", IIAlu>, cbranch16 { + let Uses = [T8]; +} + def BteqzX16: FEXT_I816_ins<0b000, "bteqz", IIAlu>, cbranch16 { let Uses = [T8]; } @@ -614,6 +657,11 @@ def BteqzT8SltiuX16: FEXT_T8I8I16_ins<"bteqz", "sltiu">, // Purpose: Branch on T Not Equal to Zero (Extended) // To test special register T then do a PC-relative conditional branch. // + +def Btnez16: FI816_ins<0b001, "btnez", IIAlu>, cbranch16 { + let Uses = [T8]; +} + def BtnezX16: FEXT_I816_ins<0b001, "btnez", IIAlu> ,cbranch16 { let Uses = [T8]; } @@ -665,7 +713,7 @@ def CmpiRxImmX16: FEXT_RI16R_ins<0b01110, "cmpi", IIAlu> { // To divide 32-bit signed integers. // def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> { - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } // @@ -674,7 +722,7 @@ def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> { // To divide 32-bit unsigned integers. // def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> { - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } // // Format: JAL target MIPS16e @@ -684,10 +732,7 @@ def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> { // def Jal16 : FJAL16_ins<0b0, "jal", IIAlu> { - let isBranch = 1; let hasDelaySlot = 0; // not true, but we add the nop for now - let isTerminator=1; - let isBarrier=1; let isCall=1; } @@ -771,6 +816,10 @@ def LiRxImm16: FRI16_ins<0b01101, "li", IIAlu>; // def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>; +def LiRxImmAlignX16: FEXT_RI16_ins<0b01101, ".align 2\n\tli", IIAlu> { + let isCodeGenOnly = 1; +} + // // Format: LW ry, offset(rx) MIPS16e // Purpose: Load Word (Extended) @@ -784,10 +833,13 @@ def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IILoad>, MayLoad{ // Purpose: Load Word (SP-Relative, Extended) // To load an SP-relative word from memory as a signed value. // -def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10110, "lw", IILoad>, MayLoad{ +def LwRxSpImmX16: FEXT_RI16_SP_explicit_ins<0b10010, "lw", IILoad>, MayLoad{ let Uses = [SP]; } +def LwRxPcTcp16: FRI16_TCP_ins<0b10110, "lw", IILoad>, MayLoad; + +def LwRxPcTcpX16: FEXT_RI16_TCP_ins<0b10110, "lw", IILoad>, MayLoad; // // Format: MOVE r32, rz MIPS16e // Purpose: Move @@ -808,7 +860,7 @@ def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>; // To copy the special purpose HI register to a GPR. // def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> { - let Uses = [HI]; + let Uses = [HI0]; let neverHasSideEffects = 1; } @@ -818,7 +870,7 @@ def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> { // To copy the special purpose LO register to a GPR. // def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> { - let Uses = [LO]; + let Uses = [LO0]; let neverHasSideEffects = 1; } @@ -828,13 +880,13 @@ def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> { def MultRxRy16: FMULT16_ins<"mult", IIAlu> { let isCommutable = 1; let neverHasSideEffects = 1; - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } def MultuRxRy16: FMULT16_ins<"multu", IIAlu> { let isCommutable = 1; let neverHasSideEffects = 1; - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } // @@ -845,7 +897,7 @@ def MultuRxRy16: FMULT16_ins<"multu", IIAlu> { def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> { let isCommutable = 1; let neverHasSideEffects = 1; - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } // @@ -856,7 +908,7 @@ def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> { def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> { let isCommutable = 1; let neverHasSideEffects = 1; - let Defs = [HI, LO]; + let Defs = [HI0, LO0]; } // @@ -951,6 +1003,22 @@ def SbRxRyOffMemX16: FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIStore>, MayStore; // +// Format: SEB rx MIPS16e +// Purpose: Sign-Extend Byte +// Sign-extend least significant byte in register rx. +// +def SebRx16 + : FRR_SF16_ins<0b10001, 0b100, "seb", IIAlu>; + +// +// Format: SEH rx MIPS16e +// Purpose: Sign-Extend Halfword +// Sign-extend least significant word in register rx. +// +def SehRx16 + : FRR_SF16_ins<0b10001, 0b101, "seh", IIAlu>; + +// // The Sel(T) instructions are pseudos // T means that they use T8 implicitly. // @@ -1075,7 +1143,7 @@ def ShRxRyOffMemX16: // // Format: SLL rx, ry, sa MIPS16e // Purpose: Shift Word Left Logical (Extended) -// To execute a left-shift of a word by a fixed number of bits—0 to 31 bits. +// To execute a left-shift of a word by a fixed number of bits-0 to 31 bits. // def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>; @@ -1171,7 +1239,7 @@ def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>; // Format: SRA rx, ry, sa MIPS16e // Purpose: Shift Word Right Arithmetic (Extended) // To execute an arithmetic right-shift of a word by a fixed -// number of bits—1 to 8 bits. +// number of bits-1 to 8 bits. // def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>; @@ -1189,7 +1257,7 @@ def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>; // Format: SRL rx, ry, sa MIPS16e // Purpose: Shift Word Right Logical (Extended) // To execute a logical right-shift of a word by a fixed -// number of bits—1 to 31 bits. +// number of bits-1 to 31 bits. // def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>; @@ -1330,9 +1398,7 @@ def: Mips16Pat<(i32 addr16:$addr), // Large (>16 bit) immediate loads -def : Mips16Pat<(i32 imm:$imm), - (OrRxRxRy16 (SllX16 (LiRxImmX16 (HI16 imm:$imm)), 16), - (LiRxImmX16 (LO16 imm:$imm)))>; +def : Mips16Pat<(i32 imm:$imm), (LwConstant32 imm:$imm, -1)>; // Carry MipsPatterns def : Mips16Pat<(subc CPU16Regs:$lhs, CPU16Regs:$rhs), @@ -1373,7 +1439,7 @@ def: Mips16Pat def: Mips16Pat <(brcond (i32 (seteq CPU16Regs:$rx, 0)), bb:$targ16), - (BeqzRxImmX16 CPU16Regs:$rx, bb:$targ16) + (BeqzRxImm16 CPU16Regs:$rx, bb:$targ16) >; // @@ -1435,7 +1501,7 @@ def: Mips16Pat def: Mips16Pat <(brcond (i32 (setne CPU16Regs:$rx, 0)), bb:$targ16), - (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16) + (BnezRxImm16 CPU16Regs:$rx, bb:$targ16) >; // @@ -1443,7 +1509,7 @@ def: Mips16Pat // def: Mips16Pat <(brcond CPU16Regs:$rx, bb:$targ16), - (BnezRxImmX16 CPU16Regs:$rx, bb:$targ16) + (BnezRxImm16 CPU16Regs:$rx, bb:$targ16) >; // @@ -1473,7 +1539,7 @@ def: Mips16Pat // (BtnezT8SltuX16 CPU16Regs:$rx, CPU16Regs:$ry, bb:$imm16) // >; -def: UncondBranch16_pat<br, BimmX16>; +def: UncondBranch16_pat<br, Bimm16>; // Small immediates def: Mips16Pat<(i32 immSExt16:$in), @@ -1787,7 +1853,8 @@ def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)), (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>; // hi/lo relocs - +def : Mips16Pat<(MipsHi tblockaddress:$in), + (SllX16 (LiRxImmX16 tblockaddress:$in), 16)>; def : Mips16Pat<(MipsHi tglobaladdr:$in), (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>; def : Mips16Pat<(MipsHi tjumptable:$in), @@ -1795,6 +1862,8 @@ def : Mips16Pat<(MipsHi tjumptable:$in), def : Mips16Pat<(MipsHi tglobaltlsaddr:$in), (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>; +def : Mips16Pat<(MipsLo tblockaddress:$in), (LiRxImmX16 tblockaddress:$in)>; + // wrapper_pic class Wrapper16Pat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: Mips16Pat<(MipsWrapper RC:$gp, node:$in), @@ -1811,3 +1880,30 @@ def : Mips16Pat<(i32 (extloadi16 addr16:$src)), def: Mips16Pat<(trap), (Break16)>; +def : Mips16Pat<(sext_inreg CPU16Regs:$val, i8), + (SebRx16 CPU16Regs:$val)>; + +def : Mips16Pat<(sext_inreg CPU16Regs:$val, i16), + (SehRx16 CPU16Regs:$val)>; + +def GotPrologue16: + MipsPseudo16< + (outs CPU16Regs:$rh, CPU16Regs:$rl), + (ins simm16:$immHi, simm16:$immLo), + ".align 2\n\tli\t$rh, $immHi\n\taddiu\t$rl, $$pc, $immLo\n ",[]> ; + +// An operand for the CONSTPOOL_ENTRY pseudo-instruction. +def cpinst_operand : Operand<i32> { + // let PrintMethod = "printCPInstOperand"; +} + +// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in +// the function. The first operand is the ID# for this instruction, the second +// is the index into the MachineConstantPool that this is, the third is the +// size in bytes of this constant pool entry. +// +let neverHasSideEffects = 1, isNotDuplicable = 1 in +def CONSTPOOL_ENTRY : +MipsPseudo16<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, + i32imm:$size), "foo", []>; + |