Add support for sdiv by 2^k and -2^k. Producing code like:
[oota-llvm.git] / lib / Target / PowerPC / PPCISelDAGToDAG.cpp
index 62fe16537e6e2e24eebbd0e418d89fdbe574109f..57dc1604f4a52da6c2c6fcf6302937424c822847 100644 (file)
@@ -557,6 +557,16 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
                          getI32Imm(0));
     break;
   }
+  case ISD::ConstantPool: {
+    unsigned CPIIdx = cast<ConstantPoolSDNode>(N)->getIndex();
+    SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(CPIIdx, MVT::i32);
+    if (PICEnabled)
+      Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI);
+    else
+      Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI);
+    CurDAG->SelectNodeTo(N, MVT::i32, PPC::LA, Tmp, CPI);
+    break;
+  }
   case ISD::GlobalAddress: {
     GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
     SDOperand Tmp;
@@ -685,10 +695,36 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
       case MVT::f32: Opc = PPC::FMULS; break;
       case MVT::f64: Opc = PPC::FMUL;  break;
     }
-    CurDAG->SelectNodeTo(N, N->getValueType(0), Opc, Select(N->getOperand(0)), 
+    CurDAG->SelectNodeTo(N, MVT::i32, Opc, Select(N->getOperand(0)), 
                          Select(N->getOperand(1)));
     break;
   }
+  case ISD::SDIV: {
+    unsigned Imm;
+    if (isIntImmediate(N->getOperand(1), Imm)) {
+      if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
+        SDOperand Op =
+          CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
+                                Select(N->getOperand(0)),
+                                getI32Imm(Log2_32(Imm)));
+        CurDAG->SelectNodeTo(N, MVT::i32, PPC::ADDZE,
+                             Op.getValue(0), Op.getValue(1));
+        break;
+      } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) {
+        SDOperand Op =
+          CurDAG->getTargetNode(PPC::SRAWI, MVT::Flag, MVT::i32,
+                                Select(N->getOperand(0)),
+                                getI32Imm(Log2_32(-Imm)));
+        SDOperand PT =
+          CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(1),
+                                Op.getValue(0));
+        CurDAG->SelectNodeTo(N, MVT::i32, PPC::NEG, PT);
+        break;
+      }
+    }
+    assert(0 && "SDIV not implemented yet!");
+    abort();
+  }    
   case ISD::MULHS:
     assert(N->getValueType(0) == MVT::i32);
     CurDAG->SelectNodeTo(N, MVT::i32, PPC::MULHW, Select(N->getOperand(0)),