[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Wed Apr 6 15:03:27 PDT 2005



Changes in directory llvm/lib/Target/Alpha:

AlphaISelPattern.cpp updated: 1.82 -> 1.83
---
Log message:

added sdiv by 2^k and works for neg divisors also

---
Diffs of the changes:  (+59 -10)

 AlphaISelPattern.cpp |   69 +++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 59 insertions(+), 10 deletions(-)


Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp
diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.82 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.83
--- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.82	Wed Apr  6 15:59:59 2005
+++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp	Wed Apr  6 17:03:13 2005
@@ -533,6 +533,18 @@
   return Q;
 }
 
+//From PPC32
+/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N.  It
+/// returns zero when the input is not exactly a power of two.
+static unsigned ExactLog2(uint64_t Val) {
+  if (Val == 0 || (Val & (Val-1))) return 0;
+  unsigned Count = 0;
+  while (Val != 1) {
+    Val >>= 1;
+    ++Count;
+  }
+  return Count;
+}
 
 
 //These describe LDAx
@@ -1788,18 +1800,55 @@
     }
 
   case ISD::SDIV:
+    {
+      ConstantSDNode* CSD;
+      //check if we can convert into a shift!
+      if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1).Val)) &&
+          (int64_t)CSD->getSignExtended() != 0 &&
+          ExactLog2(abs((int64_t)CSD->getSignExtended())) != 0)
+      {
+        unsigned k = ExactLog2(abs(CSD->getSignExtended()));
+        Tmp1 = SelectExpr(N.getOperand(0));
+        Tmp2 = MakeReg(MVT::i64);
+        if (k == 1)
+          Tmp2 = Tmp1;
+        else
+        {
+          Tmp2 = MakeReg(MVT::i64);
+          BuildMI(BB, Alpha::SRAi, 2, Tmp2).addReg(Tmp1).addImm(k - 1);
+        }
+        Tmp3 = MakeReg(MVT::i64);
+        BuildMI(BB, Alpha::SRLi, 2, Tmp3).addReg(Tmp2).addImm(64-k);
+        unsigned Tmp4 = MakeReg(MVT::i64);
+        BuildMI(BB, Alpha::ADDQ, 2, Tmp4).addReg(Tmp3).addReg(Tmp1);
+        if ((int64_t)CSD->getSignExtended() > 0)
+          BuildMI(BB, Alpha::SRAi, 2, Result).addReg(Tmp4).addImm(k);
+        else
+        {
+          unsigned Tmp5 = MakeReg(MVT::i64);
+          BuildMI(BB, Alpha::SRAi, 2, Tmp5).addReg(Tmp4).addImm(k);
+          BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp5);
+        }
+        return Result;
+      }
+    }
+    //Else fall through
+
   case ISD::UDIV:
-    if (N.getOperand(1).getOpcode() == ISD::Constant &&
-        ((int64_t)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended() >= 2 ||
-         (int64_t)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended() <= -2))
     {
-      // If this is a divide by constant, we can emit code using some magic
-      // constants to implement it as a multiply instead.
-      ExprMap.erase(N);
-      if (opcode == ISD::SDIV) 
-        return SelectExpr(BuildSDIVSequence(N));
-      else
-        return SelectExpr(BuildUDIVSequence(N));
+      ConstantSDNode* CSD;
+      if ((CSD = dyn_cast<ConstantSDNode>(N.getOperand(1).Val)) &&
+          ((int64_t)CSD->getSignExtended() >= 2 ||
+           (int64_t)CSD->getSignExtended() <= -2))
+      {
+        // If this is a divide by constant, we can emit code using some magic
+        // constants to implement it as a multiply instead.
+        ExprMap.erase(N);
+        if (opcode == ISD::SDIV) 
+          return SelectExpr(BuildSDIVSequence(N));
+        else
+          return SelectExpr(BuildUDIVSequence(N));
+      }
     }
     //else fall though
   case ISD::UREM:






More information about the llvm-commits mailing list