implement setXX patterns

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166459 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reed Kotler
2012-10-23 01:35:48 +00:00
parent 8245a17a14
commit 293e5d0e0a
14 changed files with 472 additions and 4 deletions

View File

@@ -20,6 +20,19 @@ def mem16 : Operand<i32> {
let EncoderMethod = "getMemEncoding";
}
//
// 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
//
@@ -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)>;