178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===-------- LegalizeTypesGeneric.cpp - Generic type legalization --------===//
278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//
378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//                     The LLVM Compiler Infrastructure
478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//
578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// This file is distributed under the University of Illinois Open Source
678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// License. See LICENSE.TXT for details.
778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//
878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===//
978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//
1078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// This file implements generic type expansion and splitting for LegalizeTypes.
1178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// The routines here perform legalization when the details of the type (such as
1278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// whether it is an integer or a float) do not matter.
1378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Expansion is the act of changing a computation in an illegal type to be a
14f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// computation in two identical registers of a smaller type.  The Lo/Hi part
15f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// is required to be stored first in memory on little/big-endian machines.
1678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Splitting is the act of changing a computation in an illegal type to be a
1778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// computation in two not necessarily identical registers of a smaller type.
18f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// There are no requirements on how the type is represented in memory.
1978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//
2078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===//
2178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
2278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands#include "LegalizeTypes.h"
230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
2478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sandsusing namespace llvm;
2578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "legalize-types"
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===//
2978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Result Expansion.
3078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===//
3178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
3278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// These routines assume that the Lo/Hi part is stored first in memory on
3378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// little/big-endian machines, followed by the Hi/Lo part.  This means that
3478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// they cannot be used as is on vectors, for which Lo is always stored first.
354c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sandsvoid DAGTypeLegalizer::ExpandRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
3662bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman                                              SDValue &Lo, SDValue &Hi) {
374c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sands  SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
3862bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  GetExpandedOp(Op, Lo, Hi);
3962bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman}
4078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
41bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peckvoid DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
42e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OutVT = N->getValueType(0);
4323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
44475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InOp = N->getOperand(0);
45e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT InVT = InOp.getValueType();
46ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
4778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
4878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Handle some special cases efficiently.
4978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  switch (getTypeAction(InVT)) {
5096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeLegal:
5196e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypePromoteInteger:
5278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      break;
5396e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeSoftenFloat:
5478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      // Convert the integer operand instead.
5578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
56bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
57bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
5878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
5996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeExpandInteger:
6096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeExpandFloat:
6178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      // Convert the expanded pieces of the input.
6278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      GetExpandedOp(InOp, Lo, Hi);
63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (TLI.hasBigEndianPartOrdering(InVT) !=
64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          TLI.hasBigEndianPartOrdering(OutVT))
65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        std::swap(Lo, Hi);
66bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
67bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
6878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
6996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeSplitVector:
7078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      GetSplitVector(InOp, Lo, Hi);
71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (TLI.hasBigEndianPartOrdering(OutVT))
72f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands        std::swap(Lo, Hi);
73bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
74bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
75f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands      return;
7696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeScalarizeVector:
7778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      // Convert the element instead.
7878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
79bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
80bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
8178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
8296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeWidenVector: {
83bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST");
84aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang      InOp = GetWidenedVector(InOp);
85ee287ca22abcce9f769618c107ff3f46aa2d0cbaBill Wendling      EVT LoVT, HiVT;
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (TLI.hasBigEndianPartOrdering(OutVT))
89aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang        std::swap(Lo, Hi);
90bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
91bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
92aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang      return;
93aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang    }
9478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
9578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
96f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman  if (InVT.isVector() && OutVT.isInteger()) {
97bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // Handle cases like i64 = BITCAST v1i64 on x86, where the operand
98f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    // is legal but the result is not.
99092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    unsigned NumElems = 2;
100bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    EVT ElemVT = NOutVT;
101bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    EVT NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
102092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
103bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    // If <ElemVT * N> is not a legal type, try <ElemVT/2 * (N*2)>.
104092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    while (!isTypeLegal(NVT)) {
105bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      unsigned NewSizeInBits = ElemVT.getSizeInBits() / 2;
106092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      // If the element size is smaller than byte, bail.
107092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      if (NewSizeInBits < 8)
108092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        break;
109092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      NumElems *= 2;
110bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      ElemVT = EVT::getIntegerVT(*DAG.getContext(), NewSizeInBits);
111bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
112092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    }
113f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
114f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    if (isTypeLegal(NVT)) {
115bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      SDValue CastInOp = DAG.getNode(ISD::BITCAST, dl, NVT, InOp);
116092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
117092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      SmallVector<SDValue, 8> Vals;
118092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      for (unsigned i = 0; i < NumElems; ++i)
119bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao        Vals.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ElemVT,
120425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard                                   CastInOp, DAG.getConstant(i,
121425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard                                             TLI.getVectorIdxTy())));
122092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
123092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      // Build Lo, Hi pair by pairing extracted elements if needed.
124092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      unsigned Slot = 0;
125092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      for (unsigned e = Vals.size(); e - Slot > 2; Slot += 2, e += 1) {
126092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        // Each iteration will BUILD_PAIR two nodes and append the result until
127092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        // there are only two nodes left, i.e. Lo and Hi.
128092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        SDValue LHS = Vals[Slot];
129092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        SDValue RHS = Vals[Slot + 1];
1307bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand
1317bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand        if (TLI.isBigEndian())
1327bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand          std::swap(LHS, RHS);
1337bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand
134092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        Vals.push_back(DAG.getNode(ISD::BUILD_PAIR, dl,
135092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                   EVT::getIntegerVT(
136092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                     *DAG.getContext(),
137092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                     LHS.getValueType().getSizeInBits() << 1),
138092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                   LHS, RHS));
139092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      }
140092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      Lo = Vals[Slot++];
141092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      Hi = Vals[Slot++];
142f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
143f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman      if (TLI.isBigEndian())
144f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman        std::swap(Lo, Hi);
1458c899ee031481dbece5f111379a274c848cb5902Duncan Sands
146f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman      return;
147f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    }
148f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman  }
149f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
15047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Lower the bit-convert to a store/load from the stack.
15147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  assert(NOutVT.isByteSized() && "Expanded type not byte sized!");
15247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
15347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Create the stack frame object.  Make sure it is aligned for both
15447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // the source and expanded destination types.
15547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  unsigned Alignment =
1563574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow    TLI.getDataLayout()->getPrefTypeAlignment(NOutVT.
157cac25a9452c75b24e33fffe3390de8b2b8983e92Evan Cheng                                              getTypeForEVT(*DAG.getContext()));
15847d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  SDValue StackPtr = DAG.CreateStackTemporary(InVT, Alignment);
159ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng  int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
160ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(SPFI);
16147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
16247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Emit a store to the stack slot.
163ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo,
1641e559443a17d1b335f697551c6263ba60d5dd827David Greene                               false, false, 0);
16547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
16647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Load the first half from the stack slot.
167155615d7dc4e4fbfd3b7273720a76356468edf46Stephen Lin  Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo,
168d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   false, false, false, 0);
16947d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
17047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Increment the pointer to the other half.
17147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
17235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
173edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard                         DAG.getConstant(IncrementSize,
174edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard                                         StackPtr.getValueType()));
17547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
17647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Load the second half from the stack slot.
177ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
178ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                   PtrInfo.getWithOffset(IncrementSize), false,
179d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   false, false, MinAlign(Alignment, IncrementSize));
18047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
18147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Handle endianness of the load.
182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (TLI.hasBigEndianPartOrdering(OutVT))
18347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands    std::swap(Lo, Hi);
18478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
18578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
186475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo,
187475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Hi) {
18878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Return the operands.
18978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  Lo = N->getOperand(0);
19078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  Hi = N->getOperand(1);
19178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
19278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
193475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo,
194475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                 SDValue &Hi) {
1954a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  GetExpandedOp(N->getOperand(0), Lo, Hi);
196f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  SDValue Part = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ?
197f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman                   Hi : Lo;
1984a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
1994a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  assert(Part.getValueType() == N->getValueType(0) &&
2004a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands         "Type twice as big as expanded type not itself expanded!");
2014a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
2022bee0afb7d023e029975abf7d3157759fa797d37Dan Gohman  GetPairElements(Part, Lo, Hi);
2034a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands}
2044a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
205475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
206475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                    SDValue &Hi) {
207475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue OldVec = N->getOperand(0);
20878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
2094e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  EVT OldEltVT = OldVec.getValueType().getVectorElementType();
210ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
21178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
21278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Convert to a vector of the expanded element type, for example
21378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // <3 x i64> -> <6 x i32>.
214e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldVT = N->getValueType(0);
21523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
21678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
2174e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  if (OldVT != OldEltVT) {
2184e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // The result of EXTRACT_VECTOR_ELT may be larger than the element type of
2194e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // the input vector.  If so, extend the elements of the input vector to the
2204e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // same bitwidth as the result before expanding.
2214e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    assert(OldEltVT.bitsLT(OldVT) && "Result type smaller then element type!");
2224e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    EVT NVecVT = EVT::getVectorVT(*DAG.getContext(), OldVT, OldElts);
2234e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    OldVec = DAG.getNode(ISD::ANY_EXTEND, dl, NVecVT, N->getOperand(0));
2244e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  }
2254e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands
226bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
227adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               EVT::getVectorVT(*DAG.getContext(),
228adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                                NewVT, 2*OldElts),
229adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               OldVec);
23078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
23178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
232475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Idx = N->getOperand(1);
23378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
234de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
23535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
23678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
23735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
23878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                    DAG.getConstant(1, Idx.getValueType()));
23935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
24078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
24178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (TLI.isBigEndian())
24278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
24378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
24478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
245475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
246475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Hi) {
247ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  assert(ISD::isNormalLoad(N) && "This routine only for normal loads!");
248ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
24978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
25078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  LoadSDNode *LD = cast<LoadSDNode>(N);
251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  EVT ValueVT = LD->getValueType(0);
252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
253475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = LD->getChain();
254475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = LD->getBasePtr();
25578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned Alignment = LD->getAlignment();
25678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  bool isVolatile = LD->isVolatile();
2571e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = LD->isNonTemporal();
258d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper  bool isInvariant = LD->isInvariant();
25966589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford  const MDNode *TBAAInfo = LD->getTBAAInfo();
26078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
26178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
26278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
263ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(),
26466589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                   isVolatile, isNonTemporal, isInvariant, Alignment,
26566589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                   TBAAInfo);
26678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
26778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Increment the pointer to the other half.
26878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned IncrementSize = NVT.getSizeInBits() / 8;
26935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
270edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard                    DAG.getConstant(IncrementSize, Ptr.getValueType()));
271ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getLoad(NVT, dl, Chain, Ptr,
272ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                   LD->getPointerInfo().getWithOffset(IncrementSize),
273d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   isVolatile, isNonTemporal, isInvariant,
27466589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                   MinAlign(Alignment, IncrementSize), TBAAInfo);
27578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
27678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Build a factor node to remember that this load is independent of the
27778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // other one.
278825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
27978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                      Hi.getValue(1));
28078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
28178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Handle endianness of the load.
282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (TLI.hasBigEndianPartOrdering(ValueVT))
28378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
28478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
28578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Modified the chain - switch anything that used the old chain to use
28678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // the new one.
287475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Chain);
28878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
28978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
29021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sandsvoid DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
29172d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  EVT OVT = N->getValueType(0);
29272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
29321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  SDValue Chain = N->getOperand(0);
29421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  SDValue Ptr = N->getOperand(1);
295ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
296cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola  const unsigned Align = N->getConstantOperandVal(3);
29721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
29872d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
299cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola  Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
30021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
30121c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // Handle endianness of the load.
302cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (TLI.hasBigEndianPartOrdering(OVT))
30321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands    std::swap(Lo, Hi);
30421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
30521c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // Modified the chain - switch anything that used the old chain to use
30621c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // the new one.
30721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
30821c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands}
30921c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
310ae099d54428f4113f8a71c53314975fb8a8e8bbcDuncan Sands
31178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
31278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Operand Expansion.
31378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
31478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
315f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendlingvoid DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements,
316f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                                       SmallVectorImpl<SDValue> &Ops,
317f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                                       EVT EltVT) {
318f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  assert(Op.getValueType().isInteger());
319f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  SDLoc DL(Op);
320f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  SDValue Parts[2];
321f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling
322f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  if (NumElements > 1) {
323f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    NumElements >>= 1;
324f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    SplitInteger(Op, Parts[0], Parts[1]);
325f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      if (TLI.isBigEndian())
326f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling        std::swap(Parts[0], Parts[1]);
327f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(Parts[0], NumElements, Ops, EltVT);
328f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(Parts[1], NumElements, Ops, EltVT);
329f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  } else {
330f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op));
331f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  }
332f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling}
333f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling
334bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
335ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
33678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getValueType(0).isVector()) {
33778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // An illegal expanding type is being converted to a legal vector type.
33878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // Make a two element vector out of the expanded parts and convert that
33978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // instead, but only if the new vector type is legal (otherwise there
34078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // is no point, and it might create expansion loops).  For example, on
341bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32.
342f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    //
343f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // FIXME: I'm not sure why we are first trying to split the input into
344f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // a 2 element vector, so I'm leaving it here to maintain the current
345f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // behavior.
346f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    unsigned NumElts = 2;
347e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT OVT = N->getOperand(0).getValueType();
348adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng    EVT NVT = EVT::getVectorVT(*DAG.getContext(),
349adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
350f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                               NumElts);
351f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    if (!isTypeLegal(NVT)) {
352f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      // If we can't find a legal type by splitting the integer in half,
353f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      // then we can use the node's value type.
354f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      NumElts = N->getValueType(0).getVectorNumElements();
355f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      NVT = N->getValueType(0);
356f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    }
35778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
358f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    SmallVector<SDValue, 8> Ops;
359f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
36078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT,
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              makeArrayRef(Ops.data(), NumElts));
363f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
36478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
36578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
36678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Otherwise, store to a temporary and load out again as the new type.
36778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
36878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
36978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
370475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
37178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // The vector type is legal but the element type needs expansion.
372e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
37378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned NumElts = VecVT.getVectorNumElements();
374e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldVT = N->getOperand(0).getValueType();
37523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
376ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
37778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
378b1303d05a89972195de023fda432cc621375a27cBob Wilson  assert(OldVT == VecVT.getVectorElementType() &&
379b1303d05a89972195de023fda432cc621375a27cBob Wilson         "BUILD_VECTOR operand type doesn't match vector element type!");
380b1303d05a89972195de023fda432cc621375a27cBob Wilson
38178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Build a vector of twice the length out of the expanded elements.
38278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // For example <3 x i64> -> <6 x i32>.
383475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  std::vector<SDValue> NewElts;
38478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  NewElts.reserve(NumElts*2);
38578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
38678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  for (unsigned i = 0; i < NumElts; ++i) {
387475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
38878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    GetExpandedOp(N->getOperand(i), Lo, Hi);
38978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    if (TLI.isBigEndian())
39078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      std::swap(Lo, Hi);
39178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    NewElts.push_back(Lo);
39278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    NewElts.push_back(Hi);
39378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
39478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
395a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng  SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
396adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               EVT::getVectorVT(*DAG.getContext(),
397adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                                NewVT, NewElts.size()),
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               NewElts);
39978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
40078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Convert the new vector to the old vector type.
401bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
40278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
40378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
404475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
405475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
40678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetExpandedOp(N->getOperand(0), Lo, Hi);
407f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  return cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ? Hi : Lo;
40878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
40978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
410d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
411d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // The vector type is legal but the element type needs expansion.
412e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
413d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  unsigned NumElts = VecVT.getVectorNumElements();
414ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
415d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
416d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Val = N->getOperand(1);
417e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldEVT = Val.getValueType();
41823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
419d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
420d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  assert(OldEVT == VecVT.getVectorElementType() &&
421d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang         "Inserted element type doesn't match vector element type!");
422d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
423d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // Bitconvert to a vector of twice the length with elements of the expanded
424d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // type, insert the expanded vector elements, and then convert back.
42523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2);
426bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
42735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen                               NewVecVT, N->getOperand(0));
428d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
429d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Lo, Hi;
430d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  GetExpandedOp(Val, Lo, Hi);
431d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  if (TLI.isBigEndian())
432d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang    std::swap(Lo, Hi);
433d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
434d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Idx = N->getOperand(2);
43535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
43635ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
43735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl,
438425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard                    Idx.getValueType(), Idx,
439425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard                    DAG.getConstant(1, Idx.getValueType()));
44035ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  NewVec =  DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
441d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
442d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // Convert the new vector to the old vector type.
443bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
444d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang}
445d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
446d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
447ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
448e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
449b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  assert(VT.getVectorElementType() == N->getOperand(0).getValueType() &&
450b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands         "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
451d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  unsigned NumElts = VT.getVectorNumElements();
452d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SmallVector<SDValue, 16> Ops(NumElts);
453d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  Ops[0] = N->getOperand(0);
454e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
455d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  for (unsigned i = 1; i < NumElts; ++i)
456d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang    Ops[i] = UndefVal;
457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
458d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang}
459d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
460475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
461ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
46278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(OpNo == 1 && "Can only expand the stored value so far");
463ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
46478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
46578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  StoreSDNode *St = cast<StoreSDNode>(N);
466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  EVT ValueVT = St->getValue().getValueType();
467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
468475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = St->getChain();
469475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = St->getBasePtr();
47078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned Alignment = St->getAlignment();
47178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  bool isVolatile = St->isVolatile();
4721e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = St->isNonTemporal();
47366589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford  const MDNode *TBAAInfo = St->getTBAAInfo();
47478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
47578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
47678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned IncrementSize = NVT.getSizeInBits() / 8;
47778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
47978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetExpandedOp(St->getValue(), Lo, Hi);
48078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
481cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (TLI.hasBigEndianPartOrdering(ValueVT))
48278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
48378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
4846229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner  Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(),
48566589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                    isVolatile, isNonTemporal, Alignment, TBAAInfo);
48678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
48735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
488edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard                    DAG.getConstant(IncrementSize, Ptr.getValueType()));
4896229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner  Hi = DAG.getStore(Chain, dl, Hi, Ptr,
4906229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                    St->getPointerInfo().getWithOffset(IncrementSize),
4911e559443a17d1b335f697551c6263ba60d5dd827David Greene                    isVolatile, isNonTemporal,
49266589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                    MinAlign(Alignment, IncrementSize), TBAAInfo);
49378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
494825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
49578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
49678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
49778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
49878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
49978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Result Splitting.
50078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
50178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
50278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Be careful to make no assumptions about which of Lo/Hi is stored first in
50378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// memory (for vectors it is always Lo first followed by Hi in the following
50478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// bytes; for integers and floats it is Lo first if and only if the machine is
50578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// little-endian).
50678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
5074c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sandsvoid DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
508475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
5094c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sands  SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
51062bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  GetSplitOp(Op, Lo, Hi);
51178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
51278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
513475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
514475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                       SDValue &Hi) {
51528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  SDValue LL, LH, RL, RH, CL, CH;
516ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
51778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(1), LL, LH);
51878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(2), RL, RH);
51978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
520475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Cond = N->getOperand(0);
52128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  CL = CH = Cond;
52228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  if (Cond.getValueType().isVector()) {
523f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    // Check if there are already splitted versions of the vector available and
524f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    // use those instead of splitting the mask operand again.
525f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector)
526c7e77f91fecd662b198939a9a8ee0a0cc3828fc4Juergen Ributzka      GetSplitVector(Cond, CL, CH);
527f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    else
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
52928b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  }
53028b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands
53128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL);
53228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH);
53378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
53478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
535475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
536475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Hi) {
537475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LL, LH, RL, RH;
538ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
53978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(2), LL, LH);
54078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(3), RL, RH);
54178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
54235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
54378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                   N->getOperand(1), LL, RL, N->getOperand(4));
54435ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
54578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                   N->getOperand(1), LH, RH, N->getOperand(4));
54678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
54778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
548475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
549e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT LoVT, HiVT;
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
551e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  Lo = DAG.getUNDEF(LoVT);
552e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  Hi = DAG.getUNDEF(HiVT);
55378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
554