Add support for 128 bit shifts and 32 bit shifts
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAG.cpp
index c6de86251447e72b1f3d1bd11b46f620b630432c..4b4c02bd8d82ae48ce89ae8d16502e7bd1e605b9 100644 (file)
@@ -115,15 +115,14 @@ class VISIBILITY_HIDDEN SelectionDAGLegalize {
       LegalizedNodes.insert(std::make_pair(To, To));
   }
   void AddPromotedOperand(SDOperand From, SDOperand To) {
-    bool isNew = PromotedNodes.insert(std::make_pair(From, To));
+    bool isNew = PromotedNodes.insert(std::make_pair(From, To)).second;
     assert(isNew && "Got into the map somehow?");
     // If someone requests legalization of the new node, return itself.
     LegalizedNodes.insert(std::make_pair(To, To));
   }
 
 public:
-
-  SelectionDAGLegalize(SelectionDAG &DAG);
+  explicit SelectionDAGLegalize(SelectionDAG &DAG);
 
   /// getTypeAction - Return how we should legalize values of this type, either
   /// it is already legal or we need to expand it into multiple registers of
@@ -548,8 +547,11 @@ SDOperand ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT,
     SignBit = DAG.getNode(ISD::SRL, SrcNVT, SignBit,
                           DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
     SignBit = DAG.getNode(ISD::TRUNCATE, NVT, SignBit);
-  } else if (SizeDiff < 0)
-    SignBit = DAG.getNode(ISD::SIGN_EXTEND, NVT, SignBit);
+  } else if (SizeDiff < 0) {
+    SignBit = DAG.getNode(ISD::ZERO_EXTEND, NVT, SignBit);
+    SignBit = DAG.getNode(ISD::SHL, NVT, SignBit,
+                          DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
+  }
 
   // Clear the sign bit of first operand.
   SDOperand Mask2 = (VT == MVT::f64)
@@ -1095,12 +1097,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         unsigned Col = DSP->getColumn();
         
         if (useDEBUG_LOC) {
-          SmallVector<SDOperand, 8> Ops;
-          Ops.push_back(Tmp1);  // chain
-          Ops.push_back(DAG.getConstant(Line, MVT::i32));  // line #
-          Ops.push_back(DAG.getConstant(Col, MVT::i32));   // col #
-          Ops.push_back(DAG.getConstant(SrcFile, MVT::i32));  // source file id
-          Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, &Ops[0], Ops.size());
+          SDOperand Ops[] = { Tmp1, DAG.getConstant(Line, MVT::i32),
+                              DAG.getConstant(Col, MVT::i32),
+                              DAG.getConstant(SrcFile, MVT::i32) };
+          Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops, 4);
         } else {
           unsigned ID = MMI->RecordSourceLine(Line, Col, SrcFile);
           Result = DAG.getLabel(ISD::DBG_LABEL, Tmp1, ID);
@@ -1110,25 +1110,27 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
       break;
     }
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) ||
-          getTypeAction(Node->getOperand(1).getValueType()) == Promote) {
-        SmallVector<SDOperand, 8> Ops;
-        Ops.push_back(Tmp1);
-        if (getTypeAction(Node->getOperand(1).getValueType()) == Legal) {
-          Ops.push_back(Node->getOperand(1));  // line # must be legal.
-          Ops.push_back(Node->getOperand(2));  // col # must be legal.
-        } else {
-          // Otherwise promote them.
-          Ops.push_back(PromoteOp(Node->getOperand(1)));
-          Ops.push_back(PromoteOp(Node->getOperand(2)));
-        }
-        Ops.push_back(Node->getOperand(3));  // filename must be legal.
-        Ops.push_back(Node->getOperand(4));  // working dir # must be legal.
-        Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
+    case TargetLowering::Legal: {
+      LegalizeAction Action = getTypeAction(Node->getOperand(1).getValueType());
+      if (Action == Legal && Tmp1 == Node->getOperand(0))
+        break;
+
+      SmallVector<SDOperand, 8> Ops;
+      Ops.push_back(Tmp1);
+      if (Action == Legal) {
+        Ops.push_back(Node->getOperand(1));  // line # must be legal.
+        Ops.push_back(Node->getOperand(2));  // col # must be legal.
+      } else {
+        // Otherwise promote them.
+        Ops.push_back(PromoteOp(Node->getOperand(1)));
+        Ops.push_back(PromoteOp(Node->getOperand(2)));
       }
+      Ops.push_back(Node->getOperand(3));  // filename must be legal.
+      Ops.push_back(Node->getOperand(4));  // working dir # must be legal.
+      Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
       break;
     }
+    }
     break;
 
   case ISD::DECLARE:
@@ -1151,14 +1153,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!");
     switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) {
     default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
+    case TargetLowering::Legal: {
+      LegalizeAction Action = getTypeAction(Node->getOperand(1).getValueType());
       Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the line #.
-      Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the col #.
-      Tmp4 = LegalizeOp(Node->getOperand(3));  // Legalize the source file id.
+      if (Action == Legal && Tmp1 == Node->getOperand(0))
+        break;
+      if (Action == Legal) {
+        Tmp2 = Node->getOperand(1);
+        Tmp3 = Node->getOperand(2);
+        Tmp4 = Node->getOperand(3);
+      } else {
+        Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the line #.
+        Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the col #.
+        Tmp4 = LegalizeOp(Node->getOperand(3));  // Legalize the source file id.
+      }
       Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4);
       break;
     }
+    }
     break;    
 
   case ISD::DBG_LABEL:
@@ -1236,7 +1248,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
     AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
     return Result.getValue(Op.ResNo);
-  }      
+  }
   case ISD::ATOMIC_LOAD_ADD:
   case ISD::ATOMIC_LOAD_SUB:
   case ISD::ATOMIC_LOAD_AND:
@@ -1254,14 +1266,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     for (unsigned int x = 0; x < num_operands; ++x)
       Ops[x] = LegalizeOp(Node->getOperand(x));
     Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands);
-    
+
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Custom:
       Result = TLI.LowerOperation(Result, DAG);
       break;
     case TargetLowering::Expand:
-      Result = SDOperand(TLI.ExpandOperationResult(Op.Val, DAG),0);
+      Result = SDOperand(TLI.ReplaceNodeResults(Op.Val, DAG),0);
       break;
     case TargetLowering::Legal:
       break;
@@ -1269,7 +1281,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
     AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
     return Result.getValue(Op.ResNo);
-  }      
+  }
   case ISD::Constant: {
     ConstantSDNode *CN = cast<ConstantSDNode>(Node);
     unsigned opAction =
@@ -3761,6 +3773,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
             LC = RTLIB::FPTOSINT_F32_I32;
           else if (OVT == MVT::f64)
             LC = RTLIB::FPTOSINT_F64_I32;
+          else if (OVT == MVT::f80)
+            LC = RTLIB::FPTOSINT_F80_I32;
+          else if (OVT == MVT::ppcf128)
+            LC = RTLIB::FPTOSINT_PPCF128_I32;
           else
             assert(0 && "Unexpected i32-to-fp conversion!");
         } else if (VT == MVT::i64) {
@@ -4399,7 +4415,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     Tmp2 = Node->getOperand(1);   // Get the pointer.
     if (TLI.getOperationAction(ISD::VAARG, VT) == TargetLowering::Custom) {
       Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2));
-      Result = TLI.CustomPromoteOperation(Tmp3, DAG);
+      Result = TLI.LowerOperation(Tmp3, DAG);
     } else {
       const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
       SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0);
@@ -4743,7 +4759,7 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDOperand &LHS,
         Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
         Tmp2 = SDOperand();
       }
-      LHS = Tmp1;
+      LHS = LegalizeOp(Tmp1);
       RHS = Tmp2;
       return;
     }
@@ -4871,35 +4887,41 @@ SDOperand SelectionDAGLegalize::EmitStackConvert(SDOperand SrcOp,
                                                  MVT SlotVT,
                                                  MVT DestVT) {
   // Create the stack frame object.
-  SDOperand FIPtr = DAG.CreateStackTemporary(SlotVT);
-
+  unsigned SrcAlign = TLI.getTargetData()->getPrefTypeAlignment(
+                                          SrcOp.getValueType().getTypeForMVT());
+  SDOperand FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign);
+  
   FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr);
   int SPFI = StackPtrFI->getIndex();
-
+  
   unsigned SrcSize = SrcOp.getValueType().getSizeInBits();
   unsigned SlotSize = SlotVT.getSizeInBits();
   unsigned DestSize = DestVT.getSizeInBits();
+  unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(
+                                                        DestVT.getTypeForMVT());
   
   // Emit a store to the stack slot.  Use a truncstore if the input value is
   // later than DestVT.
   SDOperand Store;
+  
   if (SrcSize > SlotSize)
     Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr,
-                              PseudoSourceValue::getFixedStack(),
-                              SPFI, SlotVT);
+                              PseudoSourceValue::getFixedStack(), SPFI, SlotVT, 
+                              false, SrcAlign);
   else {
     assert(SrcSize == SlotSize && "Invalid store");
     Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr,
-                         PseudoSourceValue::getFixedStack(),
-                         SPFI);
+                         PseudoSourceValue::getFixedStack(), SPFI,
+                         false, SrcAlign);
   }
   
   // Result is a load from the stack slot.
   if (SlotSize == DestSize)
-    return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
+    return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0, false, DestAlign);
   
   assert(SlotSize < DestSize && "Unknown extension!");
-  return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT);
+  return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT,
+                        false, DestAlign);
 }
 
 SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
@@ -5640,15 +5662,15 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
   
   // Okay, we found the operation and type to use.
   SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp);
-  
+
   // If the operation produces an invalid type, it must be custom lowered.  Use
   // the target lowering hooks to expand it.  Just keep the low part of the
   // expanded operation, we know that we're truncating anyway.
   if (getTypeAction(NewOutTy) == Expand) {
-    Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0);
+    Operation = SDOperand(TLI.ReplaceNodeResults(Operation.Val, DAG), 0);
     assert(Operation.Val && "Didn't return anything");
   }
-  
+
   // Truncate the result of the extended FP_TO_*INT operation to the desired
   // size.
   return DAG.getNode(ISD::TRUNCATE, DestVT, Operation);
@@ -6728,7 +6750,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
   }
 
   // Remember in a map if the values will be reused later.
-  bool isNew = ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi)));
+  bool isNew =
+    ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second;
   assert(isNew && "Value already expanded?!?");
 }