def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
return true;
}]>;
-def immRem1 : PatLeaf<(imm), [{
- return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 1;
-}]>;
-def immRem3 : PatLeaf<(imm), [{
- return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 3;
-}]>;
-def immRem4 : PatLeaf<(imm), [{
- return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 4;
-}]>;
-def immRem5 : PatLeaf<(imm), [{
- return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 5;
-}]>;
-def immRem1n : PatLeaf<(imm), [{
- return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 1;
-}]>;
-def immRem3n : PatLeaf<(imm), [{
- return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 3;
-}]>;
-def immRem4n : PatLeaf<(imm), [{
- return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 4;
-}]>;
-def immRem5n : PatLeaf<(imm), [{
- return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 5;
-}]>;
+
+def immRem1 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 0);}]>;
+def immRem2 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 0);}]>;
+def immRem3 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 0);}]>;
+def immRem4 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 0);}]>;
+def immRem5 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 0);}]>;
+def immRem1n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 1);}]>;
+def immRem2n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 1);}]>;
+def immRem3n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 1);}]>;
+def immRem4n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 1);}]>;
+def immRem5n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 1);}]>;
+
def immRemP2n : PatLeaf<(imm), [{
return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
}]>;
(add (shl node:$op1, 3), node:$op2)>;
def sub8 : PatFrag<(ops node:$op1, node:$op2),
(sub (shl node:$op1, 3), node:$op2)>;
-
+class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
//Pseudo ops for selection
let isLoad = 1, hasCtrlDep = 1 in {
def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt",
- [(callseq_start imm:$amt)], s_pseudo>;
+ [(callseq_start imm:$amt)], s_pseudo>, Imp<[R30],[R30]>;
def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt",
- [(callseq_end imm:$amt)], s_pseudo>;
+ [(callseq_end imm:$amt)], s_pseudo>, Imp<[R30],[R30]>;
}
def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
def : Pat<(select (setle GPRC:$RCOND, 0), immUExt8:$RFALSE, GPRC:$RTRUE),
(CMOVLEi GPRC:$RTRUE, immUExt8:$RFALSE, GPRC:$RCOND)>;
+multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq,
+ string asmstr, PatFrag OpNode, InstrItinClass itin> {
+ def L : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
+ [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
+ def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"),
+ [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
+ def Q : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
+ [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
+ def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"),
+ [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
+}
+
+defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
+defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
+defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
+defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
+defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
+defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
+defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
+//Const cases since legalize does sub x, int -> add x, inv(int) + 1
+def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
+def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
+def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
+def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
+def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
+def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
+
-def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))], s_iadd>;
-def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
- [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))], s_iadd>;
-def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
- [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))], s_iadd>;
def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
[(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))], s_ilog>;
def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC",
//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
-def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))], s_imul>;
-def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
- [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))], s_imul>;
-def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
- [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))], s_imul>;
-def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
- [(set GPRC:$RC, (mul GPRC:$RA, immUExt8ME:$L))], s_imul>;
def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
[(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC",
[(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))], s_ilog>;
-def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
-def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC",
- [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))], s_iadd>;
-def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC",
- [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))], s_iadd>;
-def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
-def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC",
- [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))], s_iadd>;
-def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC",
- [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))], s_iadd>;
-def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))], s_iadd>;
-def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC",
- [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))], s_iadd>;
-def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC",
- [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))], s_iadd>;
-def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
-def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC",
- [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))], s_iadd>;
-def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC",
- [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))], s_iadd>;
def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
[(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
[(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))], s_ishf>;
def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
[(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))], s_ishf>;
-def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
- [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))], s_iadd>;
-def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
- [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
-def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
- [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))], s_iadd>;
-def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
- [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))], s_iadd>;
def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
[(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))], s_imul>;
def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC",
def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
[(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
- [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)], s_ist>;
+ [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
- [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)], s_ist>;
+ [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
- [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)], s_ist>;
+ [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
- [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)], s_ist>;
+ [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
- [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)], s_ist>;
+ [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
- [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)], s_ist>;
+ [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
[(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
(STT F8RC:$DATA, 0, GPRC:$addr)>;
def : Pat<(store F4RC:$DATA, GPRC:$addr),
(STS F4RC:$DATA, 0, GPRC:$addr)>;
-def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i32),
+def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
(STL GPRC:$DATA, 0, GPRC:$addr)>;
-def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i16),
+def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
(STW GPRC:$DATA, 0, GPRC:$addr)>;
-def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i8),
+def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
(STB GPRC:$DATA, 0, GPRC:$addr)>;
/////////////////////////////////////////////////////////
//Branching
/////////////////////////////////////////////////////////
+class br_icc<bits<6> opc, string asmstr>
+ : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
+ !strconcat(asmstr, " $R,$dst"), s_icbr>;
+class br_fcc<bits<6> opc, string asmstr>
+ : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
+ !strconcat(asmstr, " $R,$dst"), s_fbr>;
+
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
let Ra = 31 in
def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
+def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
+ "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
+ s_icbr>;
+def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
+ "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
+ s_fbr>;
//Branches, int
-def BEQ : BForm<0x39, "beq $RA,$DISP",
- [(brcond (seteq GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BGE : BForm<0x3E, "bge $RA,$DISP",
- [(brcond (setge GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BGT : BForm<0x3F, "bgt $RA,$DISP",
- [(brcond (setgt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BLBC : BForm<0x38, "blbc $RA,$DISP", [], s_icbr>; //TODO: Low bit clear
-def BLBS : BForm<0x3C, "blbs $RA,$DISP",
- [(brcond (and GPRC:$RA, 1), bb:$DISP)], s_icbr>;
-def BLE : BForm<0x3B, "ble $RA,$DISP",
- [(brcond (setle GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BLT : BForm<0x3A, "blt $RA,$DISP",
- [(brcond (setlt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
-def BNE : BForm<0x3D, "bne $RA,$DISP",
- [(brcond (setne GPRC:$RA, 0), bb:$DISP)], s_icbr>;
+def BEQ : br_icc<0x39, "beq">;
+def BGE : br_icc<0x3E, "bge">;
+def BGT : br_icc<0x3F, "bgt">;
+def BLBC : br_icc<0x38, "blbc">;
+def BLBS : br_icc<0x3C, "blbs">;
+def BLE : br_icc<0x3B, "ble">;
+def BLT : br_icc<0x3A, "blt">;
+def BNE : br_icc<0x3D, "bne">;
//Branches, float
-def FBEQ : FBForm<0x31, "fbeq $RA,$DISP",
- [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBGE : FBForm<0x36, "fbge $RA,$DISP",
- [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBGT : FBForm<0x37, "fbgt $RA,$DISP",
- [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBLE : FBForm<0x33, "fble $RA,$DISP",
- [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBLT : FBForm<0x32, "fblt $RA,$DISP",
- [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
-def FBNE : FBForm<0x35, "fbne $RA,$DISP",
- [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
+def FBEQ : br_fcc<0x31, "fbeq">;
+def FBGE : br_fcc<0x36, "fbge">;
+def FBGT : br_fcc<0x37, "fbgt">;
+def FBLE : br_fcc<0x33, "fble">;
+def FBLT : br_fcc<0x32, "fblt">;
+def FBNE : br_fcc<0x36, "fbne">;
}
-def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>;
-def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
- (BEQ (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
- (BEQ (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
-
-def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-
-def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
-
-def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
- (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
-
-
-def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
- (FBEQ F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
- (FBEQ F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
- (FBGE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
- (FBGE F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
- (FBGT F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
- (FBGT F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
- (FBLE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
- (FBLE F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
- (FBLT F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
- (FBLT F8RC:$RA,bb:$DISP)>;
-
-def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
- (FBNE F8RC:$RA,bb:$DISP)>;
-def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
- (FBNE F8RC:$RA,bb:$DISP)>;
+//An ugly trick to get the opcode as an imm I can use
+def immBRCond : SDNodeXForm<imm, [{
+ switch((uint64_t)N->getValue()) {
+ case 0: return getI64Imm(Alpha::BEQ);
+ case 1: return getI64Imm(Alpha::BNE);
+ case 2: return getI64Imm(Alpha::BGE);
+ case 3: return getI64Imm(Alpha::BGT);
+ case 4: return getI64Imm(Alpha::BLE);
+ case 5: return getI64Imm(Alpha::BLT);
+ case 6: return getI64Imm(Alpha::BLBS);
+ case 7: return getI64Imm(Alpha::BLBC);
+ case 20: return getI64Imm(Alpha::FBEQ);
+ case 21: return getI64Imm(Alpha::FBNE);
+ case 22: return getI64Imm(Alpha::FBGE);
+ case 23: return getI64Imm(Alpha::FBGT);
+ case 24: return getI64Imm(Alpha::FBLE);
+ case 25: return getI64Imm(Alpha::FBLT);
+ default: assert(0 && "Unknown branch type");
+ }
+}]>;
+
+//Int cond patterns
+def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
+
+def : Pat<(brcond GPRC:$RA, bb:$DISP),
+ (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
+ (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
+
+//FP cond patterns
+def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
+def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
+
+
+def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+
+def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
+
+def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
+
+
+def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
+
+def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
+def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
+ (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
//End Branches
(CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;
//Stupid crazy arithmetic stuff:
+let AddedComplexity = 1 in {
def : Pat<(mul GPRC:$RA, 5), (S4ADDQ GPRC:$RA, GPRC:$RA)>;
+def : Pat<(mul GPRC:$RA, 9), (S8ADDQ GPRC:$RA, GPRC:$RA)>;
def : Pat<(mul GPRC:$RA, 3), (S4SUBQ GPRC:$RA, GPRC:$RA)>;
+def : Pat<(mul GPRC:$RA, 7), (S8SUBQ GPRC:$RA, GPRC:$RA)>;
+//slight tree expansion if we are multiplying near to a power of 2
+//n is above a power of 2
def : Pat<(mul GPRC:$RA, immRem1:$imm),
(ADDQ (SL GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
+def : Pat<(mul GPRC:$RA, immRem2:$imm),
+ (ADDQ (SL GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQ GPRC:$RA, GPRC:$RA))>;
def : Pat<(mul GPRC:$RA, immRem3:$imm),
(ADDQ (SL GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQ GPRC:$RA, GPRC:$RA))>;
-def : Pat<(mul GPRC:$RA, immRem5:$imm),
- (ADDQ (SL GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>;
def : Pat<(mul GPRC:$RA, immRem4:$imm),
(S4ADDQ GPRC:$RA, (SL GPRC:$RA, (nearP2X immRem4:$imm)))>;
+def : Pat<(mul GPRC:$RA, immRem5:$imm),
+ (ADDQ (SL GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>;
def : Pat<(mul GPRC:$RA, immRemP2:$imm),
(ADDQ (SL GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
+//n is below a power of 2
def : Pat<(mul GPRC:$RA, immRem1n:$imm),
(SUBQ (SL GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
+def : Pat<(mul GPRC:$RA, immRem2n:$imm),
+ (SUBQ (SL GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQ GPRC:$RA, GPRC:$RA))>;
def : Pat<(mul GPRC:$RA, immRem3n:$imm),
(SUBQ (SL GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQ GPRC:$RA, GPRC:$RA))>;
+def : Pat<(mul GPRC:$RA, immRem4n:$imm),
+ (SUBQ (SL GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
def : Pat<(mul GPRC:$RA, immRem5n:$imm),
(SUBQ (SL GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>;
def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
(SUBQ (SL GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
+} //Added complexity