diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index 9a1add9753b..03e6246c017 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -71,6 +71,18 @@ namespace { return build; } + static uint64_t getNearPower2(uint64_t x) { + if (!x) return 0; + unsigned at = CountLeadingZeros_64(x); + uint64_t complow = 1 << (63 - at); + uint64_t comphigh = 1 << (64 - at); + //std::cerr << x << ":" << complow << ":" << comphigh << "\n"; + if (abs(complow - x) < abs(comphigh - x)) + return complow; + else + return comphigh; + } + static bool isFPZ(SDOperand N) { ConstantFPSDNode *CN = dyn_cast(N); return (CN && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0))); diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index b1111a6a826..a87647ce70e 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -229,7 +229,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::UREM , MVT::i64, Custom); setOperationAction(ISD::SDIV , MVT::i64, Custom); setOperationAction(ISD::UDIV , MVT::i64, Custom); - + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::MEMSET , MVT::Other, Expand); setOperationAction(ISD::MEMCPY , MVT::Other, Expand); diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 01097d65abc..1422466e3f3 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -57,6 +57,9 @@ def LH16 : SDNodeXFormgetValue())); }]>; +def nearP2X : SDNodeXFormgetValue()))); +}]>; def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field return (uint64_t)N->getValue() == (uint8_t)N->getValue(); @@ -80,6 +83,31 @@ def immZAP : PatLeaf<(imm), [{ //imm is good for zapi def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0 return true; }]>; +def immRem1 : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - (int64_t)N->getValue() == -1; +}]>; +def immRem3 : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - (int64_t)N->getValue() == -3; +}]>; +def immRem5 : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - (int64_t)N->getValue() == -5; +}]>; +def immRem1n : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - N->getValue() == 1; +}]>; +def immRem3n : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - N->getValue() == 3; +}]>; +def immRem5n : PatLeaf<(imm), [{ + return (int64_t)getNearPower2((uint64_t)N->getValue()) - N->getValue() == 5; +}]>; +def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi + int64_t d = (int64_t)getNearPower2((uint64_t)N->getValue()) - N->getValue(); + switch (abs(d)) { + case 1: case 3: case 5: return false; + default: return (uint64_t)N->getValue() == (uint8_t)N->getValue(); + }; +}]>; def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>; def add4 : PatFrag<(ops node:$op1, node:$op2), @@ -252,7 +280,7 @@ def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC", 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, immUExt8:$L))], s_imul>; + [(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", @@ -876,3 +904,22 @@ def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)), def : Pat<(mulhs GPRC:$RA, GPRC:$RB), (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA), (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>; + +//Stupid crazy arithmetic stuff: +def : Pat<(mul GPRC:$RA, 5), (S4ADDQ GPRC:$RA, GPRC:$RA)>; +def : Pat<(mul GPRC:$RA, 3), (S4SUBQ GPRC:$RA, GPRC:$RA)>; + +def : Pat<(mul GPRC:$RA, immRem1:$imm), + (ADDQ (SL GPRC:$RA, (nearP2X immRem1:$imm)), 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, immRem1n:$imm), + (SUBQ (SL GPRC:$RA, (nearP2X immRem1n:$imm)), 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, immRem5n:$imm), + (SUBQ (SL GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>; +