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;
53a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar    case TargetLowering::TypePromoteFloat:
54a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar      llvm_unreachable("Bitcast of a promotion-needing float should never need"
55a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar                       "expansion");
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetLowering::TypeSoftenFloat: {
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Expand the floating point operand only if it was converted to integers.
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Otherwise, it is a legal type like f128 that can be saved in a register.
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto SoftenedOp = GetSoftenedFloat(InOp);
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (SoftenedOp == InOp)
61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SplitInteger(SoftenedOp, Lo, Hi);
63bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
64bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
6578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
6796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeExpandInteger:
68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetLowering::TypeExpandFloat: {
69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto &DL = DAG.getDataLayout();
7078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      // Convert the expanded pieces of the input.
7178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      GetExpandedOp(InOp, Lo, Hi);
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (TLI.hasBigEndianPartOrdering(InVT, DL) !=
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          TLI.hasBigEndianPartOrdering(OutVT, DL))
74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        std::swap(Lo, Hi);
75bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
76bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
7778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
7996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeSplitVector:
8078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      GetSplitVector(InOp, Lo, Hi);
81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
82f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands        std::swap(Lo, Hi);
83bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
84bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
85f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands      return;
8696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeScalarizeVector:
8778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      // Convert the element instead.
8878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
89bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
90bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
9178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      return;
9296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem    case TargetLowering::TypeWidenVector: {
93bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST");
94aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang      InOp = GetWidenedVector(InOp);
95ee287ca22abcce9f769618c107ff3f46aa2d0cbaBill Wendling      EVT LoVT, HiVT;
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
99aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang        std::swap(Lo, Hi);
100bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
101bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
102aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang      return;
103aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang    }
10478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
10578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
106f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman  if (InVT.isVector() && OutVT.isInteger()) {
107bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // Handle cases like i64 = BITCAST v1i64 on x86, where the operand
108f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    // is legal but the result is not.
109092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    unsigned NumElems = 2;
110bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    EVT ElemVT = NOutVT;
111bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    EVT NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
112092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
113bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao    // If <ElemVT * N> is not a legal type, try <ElemVT/2 * (N*2)>.
114092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    while (!isTypeLegal(NVT)) {
115bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      unsigned NewSizeInBits = ElemVT.getSizeInBits() / 2;
116092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      // If the element size is smaller than byte, bail.
117092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      if (NewSizeInBits < 8)
118092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        break;
119092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      NumElems *= 2;
120bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      ElemVT = EVT::getIntegerVT(*DAG.getContext(), NewSizeInBits);
121bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao      NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems);
122092122f124b6589a3a432473c1047bf5834df3c1Michael Liao    }
123f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
124f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    if (isTypeLegal(NVT)) {
125bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck      SDValue CastInOp = DAG.getNode(ISD::BITCAST, dl, NVT, InOp);
126092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
127092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      SmallVector<SDValue, 8> Vals;
128092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      for (unsigned i = 0; i < NumElems; ++i)
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Vals.push_back(DAG.getNode(
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            ISD::EXTRACT_VECTOR_ELT, dl, ElemVT, CastInOp,
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))));
132092122f124b6589a3a432473c1047bf5834df3c1Michael Liao
133092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      // Build Lo, Hi pair by pairing extracted elements if needed.
134092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      unsigned Slot = 0;
135092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      for (unsigned e = Vals.size(); e - Slot > 2; Slot += 2, e += 1) {
136092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        // Each iteration will BUILD_PAIR two nodes and append the result until
137092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        // there are only two nodes left, i.e. Lo and Hi.
138092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        SDValue LHS = Vals[Slot];
139092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        SDValue RHS = Vals[Slot + 1];
1407bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand
141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (DAG.getDataLayout().isBigEndian())
1427bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand          std::swap(LHS, RHS);
1437bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand
144092122f124b6589a3a432473c1047bf5834df3c1Michael Liao        Vals.push_back(DAG.getNode(ISD::BUILD_PAIR, dl,
145092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                   EVT::getIntegerVT(
146092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                     *DAG.getContext(),
147092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                     LHS.getValueType().getSizeInBits() << 1),
148092122f124b6589a3a432473c1047bf5834df3c1Michael Liao                                   LHS, RHS));
149092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      }
150092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      Lo = Vals[Slot++];
151092122f124b6589a3a432473c1047bf5834df3c1Michael Liao      Hi = Vals[Slot++];
152f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (DAG.getDataLayout().isBigEndian())
154f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman        std::swap(Lo, Hi);
1558c899ee031481dbece5f111379a274c848cb5902Duncan Sands
156f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman      return;
157f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman    }
158f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman  }
159f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman
16047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Lower the bit-convert to a store/load from the stack.
16147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  assert(NOutVT.isByteSized() && "Expanded type not byte sized!");
16247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
16347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Create the stack frame object.  Make sure it is aligned for both
16447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // the source and expanded destination types.
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment(
166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      NOutVT.getTypeForEVT(*DAG.getContext()));
16747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  SDValue StackPtr = DAG.CreateStackTemporary(InVT, Alignment);
168ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng  int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachinePointerInfo PtrInfo =
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
17147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
17247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Emit a store to the stack slot.
173ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo,
1741e559443a17d1b335f697551c6263ba60d5dd827David Greene                               false, false, 0);
17547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
17647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Load the first half from the stack slot.
177155615d7dc4e4fbfd3b7273720a76356468edf46Stephen Lin  Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo,
178d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   false, false, false, 0);
17947d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
18047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Increment the pointer to the other half.
18147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  unsigned IncrementSize = NOutVT.getSizeInBits() / 8;
18235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
1836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                         DAG.getConstant(IncrementSize, dl,
184edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard                                         StackPtr.getValueType()));
18547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
18647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Load the second half from the stack slot.
187ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
188ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                   PtrInfo.getWithOffset(IncrementSize), false,
189d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   false, false, MinAlign(Alignment, IncrementSize));
19047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
19147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // Handle endianness of the load.
192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
19347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands    std::swap(Lo, Hi);
19478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
19578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
196475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo,
197475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Hi) {
19878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Return the operands.
19978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  Lo = N->getOperand(0);
20078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  Hi = N->getOperand(1);
20178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
20278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
203475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo,
204475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                 SDValue &Hi) {
2054a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  GetExpandedOp(N->getOperand(0), Lo, Hi);
206f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  SDValue Part = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ?
207f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman                   Hi : Lo;
2084a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
2094a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  assert(Part.getValueType() == N->getValueType(0) &&
2104a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands         "Type twice as big as expanded type not itself expanded!");
2114a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
2122bee0afb7d023e029975abf7d3157759fa797d37Dan Gohman  GetPairElements(Part, Lo, Hi);
2134a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands}
2144a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands
215475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo,
216475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                    SDValue &Hi) {
217475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue OldVec = N->getOperand(0);
21878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
2194e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  EVT OldEltVT = OldVec.getValueType().getVectorElementType();
220ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
22178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
22278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Convert to a vector of the expanded element type, for example
22378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // <3 x i64> -> <6 x i32>.
224e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldVT = N->getValueType(0);
22523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
22678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
2274e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  if (OldVT != OldEltVT) {
2284e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // The result of EXTRACT_VECTOR_ELT may be larger than the element type of
2294e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // the input vector.  If so, extend the elements of the input vector to the
2304e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    // same bitwidth as the result before expanding.
2314e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    assert(OldEltVT.bitsLT(OldVT) && "Result type smaller then element type!");
2324e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    EVT NVecVT = EVT::getVectorVT(*DAG.getContext(), OldVT, OldElts);
2334e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands    OldVec = DAG.getNode(ISD::ANY_EXTEND, dl, NVecVT, N->getOperand(0));
2344e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands  }
2354e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands
236bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
237adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               EVT::getVectorVT(*DAG.getContext(),
238adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                                NewVT, 2*OldElts),
239adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               OldVec);
24078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
24178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
242475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Idx = N->getOperand(1);
24378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
244de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
24535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
24678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
24735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
2486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    DAG.getConstant(1, dl, Idx.getValueType()));
24935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx);
25078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (DAG.getDataLayout().isBigEndian())
25278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
25378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
25478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
255475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo,
256475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Hi) {
257ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  assert(ISD::isNormalLoad(N) && "This routine only for normal loads!");
258ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
25978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
26078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  LoadSDNode *LD = cast<LoadSDNode>(N);
261c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EVT ValueVT = LD->getValueType(0);
262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
263475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = LD->getChain();
264475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = LD->getBasePtr();
26578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned Alignment = LD->getAlignment();
26678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  bool isVolatile = LD->isVolatile();
2671e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = LD->isNonTemporal();
268d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper  bool isInvariant = LD->isInvariant();
26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AAMDNodes AAInfo = LD->getAAInfo();
27078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
27178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
27278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
273ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(),
27466589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford                   isVolatile, isNonTemporal, isInvariant, Alignment,
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                   AAInfo);
27678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
27778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Increment the pointer to the other half.
27878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned IncrementSize = NVT.getSizeInBits() / 8;
27935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
2806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    DAG.getConstant(IncrementSize, dl, Ptr.getValueType()));
281ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner  Hi = DAG.getLoad(NVT, dl, Chain, Ptr,
282ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner                   LD->getPointerInfo().getWithOffset(IncrementSize),
283d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                   isVolatile, isNonTemporal, isInvariant,
28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                   MinAlign(Alignment, IncrementSize), AAInfo);
28578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
28678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Build a factor node to remember that this load is independent of the
28778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // other one.
288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
28978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                      Hi.getValue(1));
29078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
29178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Handle endianness of the load.
292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
29378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
29478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
29578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Modified the chain - switch anything that used the old chain to use
29678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // the new one.
297475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Chain);
29878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
29978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
30021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sandsvoid DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
30172d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  EVT OVT = N->getValueType(0);
30272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
30321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  SDValue Chain = N->getOperand(0);
30421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  SDValue Ptr = N->getOperand(1);
305ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
306cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola  const unsigned Align = N->getConstantOperandVal(3);
30721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
30872d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola  Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align);
309cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola  Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0);
31021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
31121c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // Handle endianness of the load.
312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
31321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands    std::swap(Lo, Hi);
31421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
31521c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // Modified the chain - switch anything that used the old chain to use
31621c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  // the new one.
31721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
31821c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands}
31921c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands
320ae099d54428f4113f8a71c53314975fb8a8e8bbcDuncan Sands
32178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
32278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Operand Expansion.
32378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
32478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
325f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendlingvoid DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements,
326f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                                       SmallVectorImpl<SDValue> &Ops,
327f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                                       EVT EltVT) {
328f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  assert(Op.getValueType().isInteger());
329f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  SDLoc DL(Op);
330f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  SDValue Parts[2];
331f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling
332f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  if (NumElements > 1) {
333f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    NumElements >>= 1;
334f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    SplitInteger(Op, Parts[0], Parts[1]);
335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (DAG.getDataLayout().isBigEndian())
336f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling        std::swap(Parts[0], Parts[1]);
337f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(Parts[0], NumElements, Ops, EltVT);
338f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(Parts[1], NumElements, Ops, EltVT);
339f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  } else {
340f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op));
341f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling  }
342f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling}
343f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling
344bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) {
345ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
34678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getValueType(0).isVector()) {
34778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // An illegal expanding type is being converted to a legal vector type.
34878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // Make a two element vector out of the expanded parts and convert that
34978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // instead, but only if the new vector type is legal (otherwise there
35078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    // is no point, and it might create expansion loops).  For example, on
351bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32.
352f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    //
353f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // FIXME: I'm not sure why we are first trying to split the input into
354f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // a 2 element vector, so I'm leaving it here to maintain the current
355f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    // behavior.
356f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    unsigned NumElts = 2;
357e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT OVT = N->getOperand(0).getValueType();
358adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng    EVT NVT = EVT::getVectorVT(*DAG.getContext(),
359adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
360f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling                               NumElts);
361f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    if (!isTypeLegal(NVT)) {
362f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      // If we can't find a legal type by splitting the integer in half,
363f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      // then we can use the node's value type.
364f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      NumElts = N->getValueType(0).getVectorNumElements();
365f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling      NVT = N->getValueType(0);
366f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    }
36778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
368f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    SmallVector<SDValue, 8> Ops;
369f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType());
37078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT,
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              makeArrayRef(Ops.data(), NumElts));
373f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling    return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec);
37478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
37578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
37678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Otherwise, store to a temporary and load out again as the new type.
37778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
37878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
37978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
380475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) {
38178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // The vector type is legal but the element type needs expansion.
382e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
38378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned NumElts = VecVT.getVectorNumElements();
384e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldVT = N->getOperand(0).getValueType();
38523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
386ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
38778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
388b1303d05a89972195de023fda432cc621375a27cBob Wilson  assert(OldVT == VecVT.getVectorElementType() &&
389b1303d05a89972195de023fda432cc621375a27cBob Wilson         "BUILD_VECTOR operand type doesn't match vector element type!");
390b1303d05a89972195de023fda432cc621375a27cBob Wilson
39178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Build a vector of twice the length out of the expanded elements.
39278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // For example <3 x i64> -> <6 x i32>.
393475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  std::vector<SDValue> NewElts;
39478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  NewElts.reserve(NumElts*2);
39578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
39678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  for (unsigned i = 0; i < NumElts; ++i) {
397475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
39878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    GetExpandedOp(N->getOperand(i), Lo, Hi);
399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (DAG.getDataLayout().isBigEndian())
40078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands      std::swap(Lo, Hi);
40178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    NewElts.push_back(Lo);
40278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    NewElts.push_back(Hi);
40378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
40478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
405a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng  SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
406adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                               EVT::getVectorVT(*DAG.getContext(),
407adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng                                                NewVT, NewElts.size()),
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               NewElts);
40978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
41078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  // Convert the new vector to the old vector type.
411bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
41278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
41378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
414475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
415475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
41678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetExpandedOp(N->getOperand(0), Lo, Hi);
417f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman  return cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ? Hi : Lo;
41878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
41978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
420d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
421d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // The vector type is legal but the element type needs expansion.
422e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VecVT = N->getValueType(0);
423d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  unsigned NumElts = VecVT.getVectorNumElements();
424ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
425d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
426d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Val = N->getOperand(1);
427e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OldEVT = Val.getValueType();
42823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
429d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
430d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  assert(OldEVT == VecVT.getVectorElementType() &&
431d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang         "Inserted element type doesn't match vector element type!");
432d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
433d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // Bitconvert to a vector of twice the length with elements of the expanded
434d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // type, insert the expanded vector elements, and then convert back.
43523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2);
436bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  SDValue NewVec = DAG.getNode(ISD::BITCAST, dl,
43735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen                               NewVecVT, N->getOperand(0));
438d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
439d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Lo, Hi;
440d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  GetExpandedOp(Val, Lo, Hi);
441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (DAG.getDataLayout().isBigEndian())
442d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang    std::swap(Lo, Hi);
443d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
444d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SDValue Idx = N->getOperand(2);
44535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx);
44635ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx);
44735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Idx = DAG.getNode(ISD::ADD, dl,
448425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard                    Idx.getValueType(), Idx,
4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    DAG.getConstant(1, dl, Idx.getValueType()));
45035ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  NewVec =  DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx);
451d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
452d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  // Convert the new vector to the old vector type.
453bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec);
454d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang}
455d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
456d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
457ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
458e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = N->getValueType(0);
459b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  assert(VT.getVectorElementType() == N->getOperand(0).getValueType() &&
460b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands         "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
461d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  unsigned NumElts = VT.getVectorNumElements();
462d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  SmallVector<SDValue, 16> Ops(NumElts);
463d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  Ops[0] = N->getOperand(0);
464e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType());
465d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang  for (unsigned i = 1; i < NumElts; ++i)
466d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang    Ops[i] = UndefVal;
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
468d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang}
469d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang
470475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
471ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
47278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(OpNo == 1 && "Can only expand the stored value so far");
473ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
47478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
47578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  StoreSDNode *St = cast<StoreSDNode>(N);
476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EVT ValueVT = St->getValue().getValueType();
477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = St->getChain();
479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = St->getBasePtr();
48078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned Alignment = St->getAlignment();
48178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  bool isVolatile = St->isVolatile();
4821e559443a17d1b335f697551c6263ba60d5dd827David Greene  bool isNonTemporal = St->isNonTemporal();
48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AAMDNodes AAInfo = St->getAAInfo();
48478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
48578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
48678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  unsigned IncrementSize = NVT.getSizeInBits() / 8;
48778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
488475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
48978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetExpandedOp(St->getValue(), Lo, Hi);
49078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
49278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    std::swap(Lo, Hi);
49378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
4946229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner  Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(),
49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    isVolatile, isNonTemporal, Alignment, AAInfo);
49678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
49735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
4986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    DAG.getConstant(IncrementSize, dl, Ptr.getValueType()));
4996229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner  Hi = DAG.getStore(Chain, dl, Hi, Ptr,
5006229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                    St->getPointerInfo().getWithOffset(IncrementSize),
5011e559443a17d1b335f697551c6263ba60d5dd827David Greene                    isVolatile, isNonTemporal,
50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    MinAlign(Alignment, IncrementSize), AAInfo);
50378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
504825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
50578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
50678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
50778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
50878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
50978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Result Splitting.
51078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===//
51178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
51278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Be careful to make no assumptions about which of Lo/Hi is stored first in
51378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// memory (for vectors it is always Lo first followed by Hi in the following
51478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// bytes; for integers and floats it is Lo first if and only if the machine is
51578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// little-endian).
51678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
5174c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sandsvoid DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
518475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
5194c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sands  SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
52062bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman  GetSplitOp(Op, Lo, Hi);
52178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
52278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
523475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
524475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                       SDValue &Hi) {
52528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  SDValue LL, LH, RL, RH, CL, CH;
526ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
52778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(1), LL, LH);
52878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(2), RL, RH);
52978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
530475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Cond = N->getOperand(0);
53128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  CL = CH = Cond;
53228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  if (Cond.getValueType().isVector()) {
533f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    // Check if there are already splitted versions of the vector available and
534f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    // use those instead of splitting the mask operand again.
535f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector)
536c7e77f91fecd662b198939a9a8ee0a0cc3828fc4Juergen Ributzka      GetSplitVector(Cond, CL, CH);
537f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling    else
53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
53928b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  }
54028b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands
54128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL);
54228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH);
54378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
54478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
545475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
546475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Hi) {
547475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LL, LH, RL, RH;
548ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
54978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(2), LL, LH);
55078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  GetSplitOp(N->getOperand(3), RL, RH);
55178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
55235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0),
55378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                   N->getOperand(1), LL, RL, N->getOperand(4));
55435ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen  Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0),
55578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands                   N->getOperand(1), LH, RH, N->getOperand(4));
55678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
55778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
558475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
559e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT LoVT, HiVT;
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
561e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  Lo = DAG.getUNDEF(LoVT);
562e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  Hi = DAG.getUNDEF(HiVT);
56378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands}
564