Typo.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAGTypes.cpp
index e10a427ffedb4f4c146255bd69dc73dfd2250384..5ecda4851810d35787968e660bcf31626cfc6144 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 using namespace llvm;
@@ -98,7 +99,7 @@ class VISIBILITY_HIDDEN DAGTypeLegalizer {
   SmallVector<SDNode*, 128> Worklist;
   
 public:
-  DAGTypeLegalizer(SelectionDAG &dag)
+  explicit DAGTypeLegalizer(SelectionDAG &dag)
     : TLI(dag.getTargetLoweringInfo()), DAG(dag),
     ValueTypeActions(TLI.getValueTypeActions()) {
     assert(MVT::LAST_VALUETYPE <= 32 &&
@@ -454,7 +455,6 @@ SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
   return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
 }
 
-
 /// HandleMemIntrinsic - This handles memcpy/memset/memmove with invalid
 /// operands.  This promotes or expands the operands as required.
 SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
@@ -664,7 +664,6 @@ SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) {
   return DAG.getNode(NewOpc, NVT, Op);
 }
 
-
 SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
   assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??");
   return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0),
@@ -730,6 +729,7 @@ SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) {
                      N->getOperand(1), LHS, RHS, N->getOperand(4));
 }
 
+
 //===----------------------------------------------------------------------===//
 //  Result Expansion
 //===----------------------------------------------------------------------===//
@@ -947,7 +947,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
                       getIntPtrConstant(IncrementSize));
     Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
-                     isVolatile, std::max(Alignment, IncrementSize));
+                     isVolatile, MinAlign(Alignment, IncrementSize));
 
     // Build a factor node to remember that this load is independent of the
     // other one.
@@ -995,7 +995,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
                       getIntPtrConstant(IncrementSize));
     Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
                         SVOffset+IncrementSize, NEVT,
-                        isVolatile, std::max(Alignment, IncrementSize));
+                        isVolatile, MinAlign(Alignment, IncrementSize));
 
     // Build a factor node to remember that this load is independent of the
     // other one.
@@ -1020,7 +1020,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
     // Load the rest of the low bits.
     Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
                         SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits),
-                        isVolatile, std::max(Alignment, IncrementSize));
+                        isVolatile, MinAlign(Alignment, IncrementSize));
 
     // Build a factor node to remember that this load is independent of the
     // other one.
@@ -1061,7 +1061,6 @@ void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N,
   Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
 }
 
-
 void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N,
                                            SDOperand &Lo, SDOperand &Hi) {
   SDOperand LL, LH, RL, RH;
@@ -1166,7 +1165,7 @@ void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
     SDOperand LL, LH, RL, RH;
     GetExpandedOp(N->getOperand(0), LL, LH);
     GetExpandedOp(N->getOperand(1), RL, RH);
-    unsigned BitSize = MVT::getSizeInBits(RH.getValueType());
+    unsigned BitSize = MVT::getSizeInBits(NVT);
     unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
     unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
     
@@ -1364,6 +1363,8 @@ bool DAGTypeLegalizer::
 ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
   MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
   unsigned NVTBits = MVT::getSizeInBits(NVT);
+  assert(!(NVTBits & (NVTBits - 1)) &&
+         "Expanded integer type size not a power of two!");
 
   uint64_t HighBitMask = NVTBits, KnownZero, KnownOne;
   DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
@@ -1425,6 +1426,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
   return true;
 }
 
+
 //===----------------------------------------------------------------------===//
 //  Operand Promotion
 //===----------------------------------------------------------------------===//
@@ -1530,7 +1532,6 @@ SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) {
   return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
 }
 
-
 SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
   assert(OpNo == 0 && "Only know how to promote condition");
   SDOperand Cond = GetPromotedOp(N->getOperand(0));  // Promote the condition.
@@ -1548,7 +1549,6 @@ SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
                                 N->getOperand(2));
 }
 
-
 SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
   assert(OpNo == 1 && "only know how to promote condition");
   SDOperand Cond = GetPromotedOp(N->getOperand(1));  // Promote the condition.
@@ -1633,7 +1633,6 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
     return;
   }
 }
-  
 
 SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
   SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
@@ -1799,7 +1798,6 @@ SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source,
   return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
 }
 
-
 SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) {
   SDOperand Lo, Hi;
   GetExpandedOp(N->getOperand(0), Lo, Hi);
@@ -1936,80 +1934,144 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
   NewRHS = SDOperand();
 }
 
-
 SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
   assert(OpNo == 1 && "Can only expand the stored value so far");
-  assert(!N->isTruncatingStore() && "Can't expand truncstore!");
 
-  unsigned IncrementSize = 0;
+  MVT::ValueType VT = N->getOperand(1).getValueType();
+  MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
+  SDOperand Ch  = N->getChain();
+  SDOperand Ptr = N->getBasePtr();
+  int SVOffset = N->getSrcValueOffset();
+  unsigned Alignment = N->getAlignment();
+  bool isVolatile = N->isVolatile();
   SDOperand Lo, Hi;
-  
-  // If this is a vector type, then we have to calculate the increment as
-  // the product of the element size in bytes, and the number of elements
-  // in the high half of the vector.
-  if (MVT::isVector(N->getValue().getValueType())) {
-    assert(0 && "Vectors not supported yet");
-#if 0
-    SDNode *InVal = ST->getValue().Val;
-    unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
-    MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
-    
-    // Figure out if there is a simple type corresponding to this Vector
-    // type.  If so, convert to the vector type.
-    MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
-    if (TLI.isTypeLegal(TVT)) {
-      // Turn this into a normal store of the vector type.
-      Tmp3 = LegalizeOp(Node->getOperand(1));
-      Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
-                            SVOffset, isVolatile, Alignment);
-      Result = LegalizeOp(Result);
-      break;
-    } else if (NumElems == 1) {
-      // Turn this into a normal store of the scalar type.
-      Tmp3 = ScalarizeVectorOp(Node->getOperand(1));
-      Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
-                            SVOffset, isVolatile, Alignment);
-      // The scalarized value type may not be legal, e.g. it might require
-      // promotion or expansion.  Relegalize the scalar store.
-      return LegalizeOp(Result);
+
+  assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!");
+
+  if (!N->isTruncatingStore()) {
+    unsigned IncrementSize = 0;
+
+    // If this is a vector type, then we have to calculate the increment as
+    // the product of the element size in bytes, and the number of elements
+    // in the high half of the vector.
+    if (MVT::isVector(N->getValue().getValueType())) {
+      assert(0 && "Vectors not supported yet");
+  #if 0
+      SDNode *InVal = ST->getValue().Val;
+      unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
+      MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+
+      // Figure out if there is a simple type corresponding to this Vector
+      // type.  If so, convert to the vector type.
+      MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
+      if (TLI.isTypeLegal(TVT)) {
+        // Turn this into a normal store of the vector type.
+        Tmp3 = LegalizeOp(Node->getOperand(1));
+        Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                              SVOffset, isVolatile, Alignment);
+        Result = LegalizeOp(Result);
+        break;
+      } else if (NumElems == 1) {
+        // Turn this into a normal store of the scalar type.
+        Tmp3 = ScalarizeVectorOp(Node->getOperand(1));
+        Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                              SVOffset, isVolatile, Alignment);
+        // The scalarized value type may not be legal, e.g. it might require
+        // promotion or expansion.  Relegalize the scalar store.
+        return LegalizeOp(Result);
+      } else {
+        SplitVectorOp(Node->getOperand(1), Lo, Hi);
+        IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+      }
+  #endif
     } else {
-      SplitVectorOp(Node->getOperand(1), Lo, Hi);
-      IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+      GetExpandedOp(N->getValue(), Lo, Hi);
+      IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0;
+
+      if (!TLI.isLittleEndian())
+        std::swap(Lo, Hi);
     }
-#endif
+
+    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
+                      SVOffset, isVolatile, Alignment);
+
+    assert(Hi.Val && "FIXME: int <-> float should be handled with promote!");
+  #if 0
+    if (Hi.Val == NULL) {
+      // Must be int <-> float one-to-one expansion.
+      return Lo;
+    }
+  #endif
+
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
+    Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+                      isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+  } else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) {
+    GetExpandedOp(N->getValue(), Lo, Hi);
+    return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+                             N->getStoredVT(), isVolatile, Alignment);
+  } else if (TLI.isLittleEndian()) {
+    // Little-endian - low bits are at low addresses.
+    GetExpandedOp(N->getValue(), Lo, Hi);
+
+    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+                      isVolatile, Alignment);
+
+    unsigned ExcessBits =
+      MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT);
+    MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits);
+
+    // Increment the pointer to the other half.
+    unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+                           SVOffset+IncrementSize, NEVT,
+                           isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
   } else {
+    // Big-endian - high bits are at low addresses.  Favor aligned stores at
+    // the cost of some bit-fiddling.
     GetExpandedOp(N->getValue(), Lo, Hi);
-    IncrementSize = Hi.Val ? MVT::getSizeInBits(Hi.getValueType())/8 : 0;
-    
-    if (!TLI.isLittleEndian())
-      std::swap(Lo, Hi);
-  }
-  
-  SDOperand Chain    = N->getChain();
-  SDOperand Ptr      = N->getBasePtr();
-  int SVOffset       = N->getSrcValueOffset();
-  unsigned Alignment = N->getAlignment();
-  bool isVolatile    = N->isVolatile();
-  
-  Lo = DAG.getStore(Chain, Lo, Ptr, N->getSrcValue(),
-                    SVOffset, isVolatile, Alignment);
-  
-  assert(Hi.Val && "FIXME: int <-> float should be handled with promote!");
-#if 0
-  if (Hi.Val == NULL) {
-    // Must be int <-> float one-to-one expansion.
-    return Lo;
+
+    MVT::ValueType EVT = N->getStoredVT();
+    unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8;
+    unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
+    unsigned ExcessBits = (EBytes - IncrementSize)*8;
+    MVT::ValueType HiVT =
+      MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits);
+
+    if (ExcessBits < MVT::getSizeInBits(NVT)) {
+      // Transfer high bits from the top of Lo to the bottom of Hi.
+      Hi = DAG.getNode(ISD::SHL, NVT, Hi,
+                       DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits,
+                                       TLI.getShiftAmountTy()));
+      Hi = DAG.getNode(ISD::OR, NVT, Hi,
+                       DAG.getNode(ISD::SRL, NVT, Lo,
+                                   DAG.getConstant(ExcessBits,
+                                                   TLI.getShiftAmountTy())));
+    }
+
+    // Store both the high bits and maybe some of the low bits.
+    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+                           SVOffset, HiVT, isVolatile, Alignment);
+
+    // Increment the pointer to the other half.
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    // Store the lowest ExcessBits bits in the second half.
+    Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
+                           SVOffset+IncrementSize,
+                           MVT::getIntegerType(ExcessBits),
+                           isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
   }
-#endif
-  
-  Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                    getIntPtrConstant(IncrementSize));
-  assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
-  Hi = DAG.getStore(Chain, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
-                    isVolatile, std::max(Alignment, IncrementSize));
-  return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
 }
 
+
 //===----------------------------------------------------------------------===//
 //  Entry Point
 //===----------------------------------------------------------------------===//
@@ -2022,4 +2084,3 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
 void SelectionDAG::LegalizeTypes() {
   DAGTypeLegalizer(*this).run();
 }
-