diff options
author | Reed Kotler <rkotler@mips.com> | 2012-10-23 01:35:48 +0000 |
---|---|---|
committer | Reed Kotler <rkotler@mips.com> | 2012-10-23 01:35:48 +0000 |
commit | 293e5d0e0a4abce2c79a6bde338325ca1df0edab (patch) | |
tree | e936dfe3496659c5fe5ae59c21937b89c256a2cf /lib/Target/Mips/Mips16InstrInfo.td | |
parent | 8245a17a14e44df02c4488563d3ab50bee91c349 (diff) |
implement setXX patterns
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166459 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/Mips16InstrInfo.td')
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 185 |
1 files changed, 181 insertions, 4 deletions
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 2694b09206..043b974232 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -21,6 +21,19 @@ def mem16 : Operand<i32> { } // +// Compare a register and immediate and place result in CC +// Implicit use of T8 +// +// EXT-CCRR Instruction format +// +class FEXT_CCRXI16_ins<bits<5> _op, string asmstr, + InstrItinClass itin>: + FEXT_RI16<_op, (outs CPU16Regs:$cc), (ins CPU16Regs:$rx, simm16:$imm), + !strconcat(asmstr, "\t$rx, $imm\n\tmove\t$cc, $$t8"), [], itin> { + let isCodeGenOnly=1; +} + +// // EXT-I instruction format // class FEXT_I16_ins<bits<5> eop, string asmstr, InstrItinClass itin> : @@ -44,6 +57,17 @@ class FEXT_I816_ins<bits<3> _func, string asmstr, // Assembler formats in alphabetical order. // Natural and pseudos are mixed together. // +// Compare two registers and place result in CC +// Implicit use of T8 +// +// CC-RR Instruction format +// +class FCCRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> : + FRR16<f, (outs CPU16Regs:$cc), (ins CPU16Regs:$rx, CPU16Regs:$ry), + !strconcat(asmstr, "\t$rx, $ry\n\tmove\t$cc, $$t8"), [], itin> { + let isCodeGenOnly=1; +} + // // EXT-RI instruction format // @@ -562,7 +586,36 @@ def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>; // def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>; +// +// Format: SLTI rx, immediate MIPS16e +// Purpose: Set on Less Than Immediate (Extended) +// To record the result of a less-than comparison with a constant. +// +def SltiCCRxImmX16: FEXT_CCRXI16_ins<0b01010, "slti", IIAlu>; + +// +// Format: SLTIU rx, immediate MIPS16e +// Purpose: Set on Less Than Immediate Unsigned (Extended) +// To record the result of a less-than comparison with a constant. +// +def SltiuCCRxImmX16: FEXT_CCRXI16_ins<0b01011, "sltiu", IIAlu>; + +// +// Format: SLT rx, ry MIPS16e +// Purpose: Set on Less Than +// To record the result of a less-than comparison. +// +def SltRxRy16: FRR16_ins<0b00010, "slt", IIAlu>; + +def SltCCRxRy16: FCCRR16_ins<0b00010, "slt", IIAlu>; + +// Format: SLTU rx, ry MIPS16e +// Purpose: Set on Less Than Unsigned +// To record the result of an unsigned less-than comparison. +// + +def SltuCCRxRy16: FCCRR16_ins<0b00011, "sltu", IIAlu>; // // Format: SRAV ry, rx MIPS16e // Purpose: Shift Word Right Arithmetic Variable @@ -705,6 +758,17 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; +// setcc patterns + +class SetCC_R16<PatFrag cond_op, Instruction I>: + Mips16Pat<(cond_op CPU16Regs:$rx, CPU16Regs:$ry), + (I CPU16Regs:$rx, CPU16Regs:$ry)>; + +class SetCC_I16<PatFrag cond_op, PatLeaf imm_type, Instruction I>: + Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16), + (I CPU16Regs:$rx, imm_type:$imm16)>; + + // // Some branch conditional patterns are not generated by llvm at this time. // Some are for seemingly arbitrary reasons not used: i.e. with signed number @@ -757,10 +821,10 @@ def: Mips16Pat // // never called because compiler transforms a >= k to a > (k-1) -//def: Mips16Pat -// <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16), -// (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16) -// >; +def: Mips16Pat + <(brcond (i32 (setge CPU16Regs:$rx, immSExt16:$imm)), bb:$imm16), + (BteqzT8SltiX16 CPU16Regs:$rx, immSExt16:$imm, bb:$imm16) + >; // // bcond-setlt @@ -859,5 +923,118 @@ def: Mips16Pat (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>; +// +// When writing C code to test setxx these patterns, +// some will be transformed into +// other things. So we test using C code but using -O3 and -O0 +// +// seteq +// +def : Mips16Pat + <(seteq CPU16Regs:$lhs,CPU16Regs:$rhs), + (SltiuCCRxImmX16 (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), 1)>; + +def : Mips16Pat + <(seteq CPU16Regs:$lhs, 0), + (SltiuCCRxImmX16 CPU16Regs:$lhs, 1)>; + + +// +// setge +// + +def: Mips16Pat + <(setge CPU16Regs:$lhs, CPU16Regs:$rhs), + (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), + (LiRxImmX16 1))>; + +// +// For constants, llvm transforms this to: +// x > (k -1) and then reverses the operands to use setlt. So this pattern +// is not used now by the compiler. (Presumably checking that k-1 does not +// overflow). The compiler never uses this at a the current time, due to +// other optimizations. +// +//def: Mips16Pat +// <(setge CPU16Regs:$lhs, immSExt16:$rhs), +// (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, immSExt16:$rhs), +// (LiRxImmX16 1))>; + +// This catches the x >= -32768 case by transforming it to x > -32769 +// +def: Mips16Pat + <(setgt CPU16Regs:$lhs, -32769), + (XorRxRxRy16 (SltiCCRxImmX16 CPU16Regs:$lhs, -32768), + (LiRxImmX16 1))>; + +// +// setgt +// +// + +def: Mips16Pat + <(setgt CPU16Regs:$lhs, CPU16Regs:$rhs), + (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>; + +// +// setle +// +def: Mips16Pat + <(setle CPU16Regs:$lhs, CPU16Regs:$rhs), + (XorRxRxRy16 (SltCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>; + +// +// setlt +// +def: SetCC_R16<setlt, SltCCRxRy16>; + +def: SetCC_I16<setlt, immSExt16, SltiCCRxImmX16>; + +// +// setne +// +def : Mips16Pat + <(setne CPU16Regs:$lhs,CPU16Regs:$rhs), + (SltuCCRxRy16 (LiRxImmX16 0), + (XorRxRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs))>; + + +// +// setuge +// +def: Mips16Pat + <(setuge CPU16Regs:$lhs, CPU16Regs:$rhs), + (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$lhs, CPU16Regs:$rhs), + (LiRxImmX16 1))>; + +// this pattern will never be used because the compiler will transform +// x >= k to x > (k - 1) and then use SLT +// +//def: Mips16Pat +// <(setuge CPU16Regs:$lhs, immZExt16:$rhs), +// (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), +// (LiRxImmX16 1))>; + +// +// setugt +// +def: Mips16Pat + <(setugt CPU16Regs:$lhs, CPU16Regs:$rhs), + (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs)>; + +// +// setule +// +def: Mips16Pat + <(setule CPU16Regs:$lhs, CPU16Regs:$rhs), + (XorRxRxRy16 (SltuCCRxRy16 CPU16Regs:$rhs, CPU16Regs:$lhs), (LiRxImmX16 1))>; + +// +// setult +// +def: SetCC_R16<setult, SltuCCRxRy16>; + +def: SetCC_I16<setult, immSExt16, SltiuCCRxImmX16>; + def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)), (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>; |