SPUISelDAGToDAG.cpp revision 602b0c8c17f458d2c80f2deb3c8e554d516ee316
14ee451de366474b9c228b4e5fa573795a715216dChris Lattner//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===//
2266bc8f7774b153401e54ed537db299159840981Scott Michel//
3266bc8f7774b153401e54ed537db299159840981Scott Michel//                     The LLVM Compiler Infrastructure
4266bc8f7774b153401e54ed537db299159840981Scott Michel//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7266bc8f7774b153401e54ed537db299159840981Scott Michel//
8266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
9266bc8f7774b153401e54ed537db299159840981Scott Michel//
10266bc8f7774b153401e54ed537db299159840981Scott Michel// This file defines a pattern matching instruction selector for the Cell SPU,
11266bc8f7774b153401e54ed537db299159840981Scott Michel// converting from a legalized dag to a SPU-target dag.
12266bc8f7774b153401e54ed537db299159840981Scott Michel//
13266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
14266bc8f7774b153401e54ed537db299159840981Scott Michel
15266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPU.h"
16266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUTargetMachine.h"
17266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUISelLowering.h"
18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h"
19266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h"
20203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h"
2194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h"
22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h"
23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h"
24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h"
25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h"
26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h"
2794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
33a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h"
34266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
35dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
37266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
38dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
39266bc8f7774b153401e54ed537db299159840981Scott Michel
40266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
41266bc8f7774b153401e54ed537db299159840981Scott Michel
42266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
43266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
44266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
45266bc8f7774b153401e54ed537db299159840981Scott Michel  isI64IntS10Immediate(ConstantSDNode *CN)
46266bc8f7774b153401e54ed537db299159840981Scott Michel  {
477810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
48266bc8f7774b153401e54ed537db299159840981Scott Michel  }
49266bc8f7774b153401e54ed537db299159840981Scott Michel
50266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
51266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
52266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
53266bc8f7774b153401e54ed537db299159840981Scott Michel  {
547810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
55266bc8f7774b153401e54ed537db299159840981Scott Michel  }
56266bc8f7774b153401e54ed537db299159840981Scott Michel
57504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
58504c369213efb263136bb048e79af3516511c040Scott Michel  bool
59504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
60504c369213efb263136bb048e79af3516511c040Scott Michel  {
617810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isU10Constant(CN->getSExtValue());
62504c369213efb263136bb048e79af3516511c040Scott Michel  }
63504c369213efb263136bb048e79af3516511c040Scott Michel
64266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
65266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
66266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
67266bc8f7774b153401e54ed537db299159840981Scott Michel  {
687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
69266bc8f7774b153401e54ed537db299159840981Scott Michel  }
70266bc8f7774b153401e54ed537db299159840981Scott Michel
71266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
72266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
73266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(SDNode *N)
74266bc8f7774b153401e54ed537db299159840981Scott Michel  {
759de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
769de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    return (CN != 0 && isI16IntS10Immediate(CN));
77266bc8f7774b153401e54ed537db299159840981Scott Michel  }
78266bc8f7774b153401e54ed537db299159840981Scott Michel
79ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
80ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
81ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
82ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return isU10Constant((short) CN->getZExtValue());
84ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
85ec2a08ff061af36b46160e475362959f21663e76Scott Michel
86ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
87ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
88ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(SDNode *N)
89ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
90ec2a08ff061af36b46160e475362959f21663e76Scott Michel    return (N->getOpcode() == ISD::Constant
91ec2a08ff061af36b46160e475362959f21663e76Scott Michel            && isI16IntU10Immediate(cast<ConstantSDNode>(N)));
92ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
93ec2a08ff061af36b46160e475362959f21663e76Scott Michel
94266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
95266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
96266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
97266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
98266bc8f7774b153401e54ed537db299159840981Scott Michel
99266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
100266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
101266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
102266bc8f7774b153401e54ed537db299159840981Scott Michel   */
103266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
104266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
105266bc8f7774b153401e54ed537db299159840981Scott Michel  {
106e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = CN->getValueType(0);
107f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
109266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (vt == MVT::i32) {
111f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
112266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
113266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
114266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
115f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
116266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
117266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
118266bc8f7774b153401e54ed537db299159840981Scott Michel    }
119266bc8f7774b153401e54ed537db299159840981Scott Michel
120266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
121266bc8f7774b153401e54ed537db299159840981Scott Michel  }
122266bc8f7774b153401e54ed537db299159840981Scott Michel
123266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for signed 16-bit values.
124266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
125266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(SDNode *N, short &Imm)
126266bc8f7774b153401e54ed537db299159840981Scott Michel  {
127266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
128266bc8f7774b153401e54ed537db299159840981Scott Michel            && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
129266bc8f7774b153401e54ed537db299159840981Scott Michel  }
130266bc8f7774b153401e54ed537db299159840981Scott Michel
131266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
132266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
133266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
134266bc8f7774b153401e54ed537db299159840981Scott Michel  {
135e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = FPN->getValueType(0);
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt == MVT::f32) {
137d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
138266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
139266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
140266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
141266bc8f7774b153401e54ed537db299159840981Scott Michel    }
142266bc8f7774b153401e54ed537db299159840981Scott Michel
143266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
144266bc8f7774b153401e54ed537db299159840981Scott Michel  }
145266bc8f7774b153401e54ed537db299159840981Scott Michel
146053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  bool
14702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  isHighLow(const SDValue &Op)
148053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  {
149053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    return (Op.getOpcode() == SPUISD::IndirectAddr
150053c1da8d956a794d158ac906b3927c923f97c4dScott Michel            && ((Op.getOperand(0).getOpcode() == SPUISD::Hi
151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 && Op.getOperand(1).getOpcode() == SPUISD::Lo)
152053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                || (Op.getOperand(0).getOpcode() == SPUISD::Lo
153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                    && Op.getOperand(1).getOpcode() == SPUISD::Hi)));
154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
156266bc8f7774b153401e54ed537db299159840981Scott Michel  //===------------------------------------------------------------------===//
157e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  //! EVT to "useful stuff" mapping structure:
158266bc8f7774b153401e54ed537db299159840981Scott Michel
159266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
160e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT;
1617f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    unsigned ldresult_ins;      /// LDRESULT instruction (0 = undefined)
162a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    bool ldresult_imm;          /// LDRESULT instruction requires immediate?
163f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    unsigned lrinst;            /// LR instruction
164266bc8f7774b153401e54ed537db299159840981Scott Michel  };
165266bc8f7774b153401e54ed537db299159840981Scott Michel
166266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i8,    SPU::ORBIr8,  true,  SPU::LRr8 },
168825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i16,   SPU::ORHIr16, true,  SPU::LRr16 },
169825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i32,   SPU::ORIr32,  true,  SPU::LRr32 },
170825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i64,   SPU::ORr64,   false, SPU::LRr64 },
171825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::f32,   SPU::ORf32,   false, SPU::LRf32 },
172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::f64,   SPU::ORf64,   false, SPU::LRf64 },
17358c5818c01e375a84dc601140470fa68638004cfScott Michel    // vector types... (sigh!)
174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v16i8, 0,            false, SPU::LRv16i8 },
175825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v8i16, 0,            false, SPU::LRv8i16 },
176825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v4i32, 0,            false, SPU::LRv4i32 },
177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v2i64, 0,            false, SPU::LRv2i64 },
178825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v4f32, 0,            false, SPU::LRv4f32 },
179825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v2f64, 0,            false, SPU::LRv2f64 }
180266bc8f7774b153401e54ed537db299159840981Scott Michel  };
181266bc8f7774b153401e54ed537db299159840981Scott Michel
182266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
183266bc8f7774b153401e54ed537db299159840981Scott Michel
184e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  const valtype_map_s *getValueTypeMapEntry(EVT VT)
185266bc8f7774b153401e54ed537db299159840981Scott Michel  {
186266bc8f7774b153401e54ed537db299159840981Scott Michel    const valtype_map_s *retval = 0;
187266bc8f7774b153401e54ed537db299159840981Scott Michel    for (size_t i = 0; i < n_valtype_map; ++i) {
188266bc8f7774b153401e54ed537db299159840981Scott Michel      if (valtype_map[i].VT == VT) {
1897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        retval = valtype_map + i;
1907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        break;
191266bc8f7774b153401e54ed537db299159840981Scott Michel      }
192266bc8f7774b153401e54ed537db299159840981Scott Michel    }
193266bc8f7774b153401e54ed537db299159840981Scott Michel
194266bc8f7774b153401e54ed537db299159840981Scott Michel
195266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG
196266bc8f7774b153401e54ed537db299159840981Scott Michel    if (retval == 0) {
197dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      std::string msg;
198dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      raw_string_ostream Msg(msg);
199dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      Msg << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
200e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson           << VT.getEVTString();
201dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      llvm_report_error(Msg.str());
202266bc8f7774b153401e54ed537db299159840981Scott Michel    }
203266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
204266bc8f7774b153401e54ed537db299159840981Scott Michel
205266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
206266bc8f7774b153401e54ed537db299159840981Scott Michel  }
207266bc8f7774b153401e54ed537db299159840981Scott Michel
2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the carry-generate shuffle mask.
2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
211844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
214825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
215825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
216825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
217825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
21802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
219825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
221266bc8f7774b153401e54ed537db299159840981Scott Michel  }
222266bc8f7774b153401e54ed537db299159840981Scott Michel
2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the borrow-generate shuffle mask
2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
229825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
230825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
231825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
232825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
234825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
2357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
236266bc8f7774b153401e54ed537db299159840981Scott Michel  }
23702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //===------------------------------------------------------------------===//
2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// instructions for SelectionDAG operations.
2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  ///
2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  class SPUDAGToDAGISel :
2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    public SelectionDAGISel
2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  {
2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SPUTargetMachine &TM;
2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SPUTargetLowering &SPUtli;
2477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    unsigned GlobalBaseReg;
2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  public:
2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SelectionDAGISel(tm),
2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      TM(tm),
2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SPUtli(*tm.getTargetLowering())
2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    { }
2557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
256ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman    virtual bool runOnMachineFunction(MachineFunction &MF) {
2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Make sure we re-emit a set of the global base reg if necessary
2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      GlobalBaseReg = 0;
259ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman      SelectionDAGISel::runOnMachineFunction(MF);
2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return true;
261c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
262266bc8f7774b153401e54ed537db299159840981Scott Michel
2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI32Imm - Return a target constant with the specified value, of type
2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i32.
2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI32Imm(uint32_t Imm) {
266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i32);
26794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    }
26894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI64Imm - Return a target constant with the specified value, of type
2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i64.
2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI64Imm(uint64_t Imm) {
272825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i64);
2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
27494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getSmallIPtrImm - Return a target constant of pointer type.
2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getSmallIPtrImm(unsigned Imm) {
2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
278266bc8f7774b153401e54ed537db299159840981Scott Michel      }
2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *emitBuildVector(SDValue build_vec) {
281e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT vecVT = build_vec.getValueType();
282e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT eltVT = vecVT.getVectorElementType();
2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDNode *bvNode = build_vec.getNode();
2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      DebugLoc dl = bvNode->getDebugLoc();
2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Check to see if this vector can be represented as a CellSPU immediate
2877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // constant by invoking all of the instruction selection predicates:
288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (((vecVT == MVT::v8i16) &&
289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
290825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v4i32) &&
291825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
292825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
293825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
295825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v2i64) &&
296825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
297825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
298825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0))))
2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        return Select(build_vec);
3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // No, need to emit a constant pool spill:
3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      std::vector<Constant*> CV;
3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      for (size_t i = 0; i < build_vec.getNumOperands(); ++i) {
3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i));
3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue()));
3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
309af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson      Constant *CP = ConstantVector::get(CV);
3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
3127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CGPoolOffset =
3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel              SPU::LowerConstantPool(CPIdx, *CurDAG,
3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                     SPUtli.getSPUTargetMachine());
3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl,
3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                        CurDAG->getEntryNode(), CGPoolOffset,
3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                        PseudoSourceValue::getConstantPool(), 0,
3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                        false, Alignment));
3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Select - Convert the specified operand from a target-independent to a
3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// target-specific node if it hasn't already been changed.
3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *Select(SDValue Op);
3247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 shl
326e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectSHLi64(SDValue &Op, EVT OpVT);
3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 srl
329e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectSRLi64(SDValue &Op, EVT OpVT);
3307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 sra
332e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectSRAi64(SDValue &Op, EVT OpVT);
3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the necessary sequence for loading i64 constants:
335e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(SDValue &Op, EVT OpVT, DebugLoc dl);
3367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Alternate instruction emit sequence for loading i64 constants
338e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Returns true if the address N is an A-form (local store) address
3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
3437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! D-form address predicate
3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Alternate D-form address using i7 offset predicate
3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                          SDValue &Base);
3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// D-form address selection workhorse
3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp,
3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                               SDValue &Base, int minOffset, int maxOffset);
3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Address predicate if N can be expressed as an indexed [r+r] operation.
3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// inline asm expressions.
3627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
3637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              char ConstraintCode,
3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              std::vector<SDValue> &OutOps) {
3657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op0, Op1;
3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      switch (ConstraintCode) {
3677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      default: return true;
3687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'm':   // memory
3697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        if (!SelectDFormAddr(Op, Op, Op0, Op1)
3707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            && !SelectAFormAddr(Op, Op, Op0, Op1))
3717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SelectXFormAddr(Op, Op, Op0, Op1);
3727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'o':   // offsetable
3747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        if (!SelectDFormAddr(Op, Op, Op0, Op1)
3757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            && !SelectAFormAddr(Op, Op, Op0, Op1)) {
3767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op0 = Op;
3777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op1 = getSmallIPtrImm(0);
3787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        }
3797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'v':   // not offsetable
381266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
382c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
383266bc8f7774b153401e54ed537db299159840981Scott Michel#else
3847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        SelectAddrIdxOnly(Op, Op, Op0, Op1);
385266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
3867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
38802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
3897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op0);
3907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op1);
3917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return false;
3927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
393266bc8f7774b153401e54ed537db299159840981Scott Michel
3947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// InstructionSelect - This callback is invoked by
3957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
3967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual void InstructionSelect();
397266bc8f7774b153401e54ed537db299159840981Scott Michel
3987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual const char *getPassName() const {
3997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return "Cell SPU DAG->DAG Pattern Instruction Selection";
4007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
40102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
4027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
4037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// this target when scheduling the DAG.
4047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
4057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      const TargetInstrInfo *II = TM.getInstrInfo();
4067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      assert(II && "No InstrInfo?");
4077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return new SPUHazardRecognizer(*II);
4087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
409266bc8f7774b153401e54ed537db299159840981Scott Michel
4107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Include the pieces autogenerated from the target description.
411266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
4127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  };
413844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
414844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
415db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by
416266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
417266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
418f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect()
419266bc8f7774b153401e54ed537db299159840981Scott Michel{
420266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
421266bc8f7774b153401e54ed537db299159840981Scott Michel
422266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
4238ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene  SelectRoot(*CurDAG);
424f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman  CurDAG->RemoveDeadNodes();
425266bc8f7774b153401e54ed537db299159840981Scott Michel}
426266bc8f7774b153401e54ed537db299159840981Scott Michel
427266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
4289de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand
429266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
430266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
431266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
432266bc8f7774b153401e54ed537db299159840981Scott Michel */
433266bc8f7774b153401e54ed537db299159840981Scott Michelbool
434475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
435475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
436266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
437825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT OffsVT = MVT::i16;
438475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
439266bc8f7774b153401e54ed537db299159840981Scott Michel
440266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
441266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
4429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
444dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin    llvm_report_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered.");
4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
4469de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
450dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin    llvm_report_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
451dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "not wrapped as A-form address.");
452053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
453266bc8f7774b153401e54ed537db299159840981Scott Michel
45402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  case SPUISD::AFormAddr:
455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
456053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
457053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
458475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalValue *GV = GSDN->getGlobal();
469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
474053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
479053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
480266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
481266bc8f7774b153401e54ed537db299159840981Scott Michel}
482266bc8f7774b153401e54ed537db299159840981Scott Michel
48302d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool
484475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
485475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
486203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
487203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
488203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
489203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4917f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
492266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
493266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
494266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
495266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
496266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
497266bc8f7774b153401e54ed537db299159840981Scott Michel
498266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
499266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
500266bc8f7774b153401e54ed537db299159840981Scott Michel
501266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
502475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
503266bc8f7774b153401e54ed537db299159840981Scott Michel*/
504266bc8f7774b153401e54ed537db299159840981Scott Michelbool
505475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
506475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
5077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
5089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::minFrameOffset(),
5099c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::maxFrameOffset());
5107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
5117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
513475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
514475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
5157f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
516266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
517e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT PtrTy = SPUtli.getPointerTy();
518266bc8f7774b153401e54ed537db299159840981Scott Michel
519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
521203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
522203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
5234437ae213d5435390f0750213b53ec807c047f22Chris Lattner    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
524203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
525203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
526266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
527203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
528266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
529266bc8f7774b153401e54ed537db299159840981Scott Michel    }
530266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
531266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
532475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
533475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
534266bc8f7774b153401e54ed537db299159840981Scott Michel
535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
5429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
5437810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
544266bc8f7774b153401e54ed537db299159840981Scott Michel
545053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
546203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
547203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
5484437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
549203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
5509de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
551203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
5529de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
553203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5549de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5559de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5567f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
5579de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
562053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
563053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
5647810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
565053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
566053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
567203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
568203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
5694437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
570203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
571053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
572203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
573053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
574203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5777f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
578053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
579053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
580053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
581266bc8f7774b153401e54ed537db299159840981Scott Michel      }
582497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
583053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
584053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
585475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
586475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
587053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
5887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
5897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
590053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5919de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
592053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
5957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
596475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
5977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
5997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
6007810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
6017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
6027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
6037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
6047810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
6057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
60602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      }
6077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
6087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
6097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
6107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
6117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
6127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
6139de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
614053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
615053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
616053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
61758c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
6187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
6197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
6207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
6217f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) {
6239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    unsigned OpOpc = Op.getOpcode();
6249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
6259c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
6269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
6279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      SDValue Addr, Offs;
6289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
6299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Get the register from CopyFromReg
6309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Opc == ISD::CopyFromReg)
6319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Addr = N.getOperand(1);
6329c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      else
6339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Addr = N;                       // Register
6349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
635aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2));
6369c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
6379c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
6389c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
6399c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
6409c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
6419c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
6429c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Index = Addr;
6439c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
6449c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
645aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
646aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
647aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
64819c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N.getOperand(1);
649aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
65019c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N;
651aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
652aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
653aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
654aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
6559c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
656266bc8f7774b153401e54ed537db299159840981Scott Michel  }
6579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
658266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
659266bc8f7774b153401e54ed537db299159840981Scott Michel}
660266bc8f7774b153401e54ed537db299159840981Scott Michel
661266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
662266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
663266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
664266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
665266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
666266bc8f7774b153401e54ed537db299159840981Scott Michel
6679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
6689c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
6699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
670266bc8f7774b153401e54ed537db299159840981Scott Michel*/
671266bc8f7774b153401e54ed537db299159840981Scott Michelbool
672475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
673475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
6749c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
6759c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
67618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
67718fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
6781a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
6791a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
68050843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
6819c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
682266bc8f7774b153401e54ed537db299159840981Scott Michel
6839c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
68458c5818c01e375a84dc601140470fa68638004cfScott Michel}
68558c5818c01e375a84dc601140470fa68638004cfScott Michel
686266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
687266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
688266bc8f7774b153401e54ed537db299159840981Scott Michel */
689266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
690475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) {
691ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  SDNode *N = Op.getNode();
692266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
69358c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
69458c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
695e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT OpVT = Op.getValueType();
696475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
697ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = N->getDebugLoc();
698266bc8f7774b153401e54ed537db299159840981Scott Michel
699e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman  if (N->isMachineOpcode()) {
700266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
701c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
702c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
703c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (Opc == ISD::FrameIndex) {
70402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
70502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
70602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType());
70702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
70802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (FI < 128) {
709203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
71002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = TFI;
71102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[1] = Imm0;
712203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
713203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
714203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
71502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType());
716602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
717602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                              Op.getValueType(), TFI, Imm0),
718602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                       0);
719203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
720203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
721825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
722c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // Catch the i64 constants that end up here. Note: The backend doesn't
723c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // attempt to legalize the constant (it's useless because DAGCombiner
724c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // will insert 64-bit constants and we can't stop it).
7257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    return SelectI64Constant(Op, OpVT, Op.getDebugLoc());
72694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
727825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && OpVT == MVT::i64) {
72894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue Op0 = Op.getOperand(0);
729e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT Op0VT = Op0.getValueType();
73023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
73123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                    Op0VT, (128 / Op0VT.getSizeInBits()));
73223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
73323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                   OpVT, (128 / OpVT.getSizeInBits()));
73494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue shufMask;
73594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
736825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    switch (Op0VT.getSimpleVT().SimpleTy) {
73794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    default:
738e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      llvm_report_error("CellSPU Select: Unhandled zero/any extend EVT");
73994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      /*NOTREACHED*/
740825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i32:
741825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
742825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
743825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x00010203, MVT::i32),
744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
745825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
74694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
74794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
748825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i16:
749825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
750825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
751825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800203, MVT::i32),
752825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
753825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
75494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
75594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
756825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i8:
757825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
758825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
759825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808003, MVT::i32),
760825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
761825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x8080800b, MVT::i32));
76294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
76358c5818c01e375a84dc601140470fa68638004cfScott Michel    }
76494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
76594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *shufMaskLoad = emitBuildVector(shufMask);
76694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *PromoteScalar =
767ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0));
76894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
76994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue zextShuffle =
770ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
771d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(PromoteScalar, 0),
772d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(PromoteScalar, 0),
773d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(shufMaskLoad, 0));
77494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
77594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we
77694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    // re-use it in the VEC2PREFSLOT selection without needing to explicitly
77794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    // call SelectCode (it's already done for us.)
778046928077645f6ddad839e85dd03ab11e5b22cbcDale Johannesen    SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle));
779ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen    return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
78094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel                                      zextShuffle));
781825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
78294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *CGLoad =
7837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl));
784d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
785ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen    return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
786d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      Op.getOperand(0), Op.getOperand(1),
787d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      SDValue(CGLoad, 0)));
788825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
789d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
7907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl));
791d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
792ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen    return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
793d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      Op.getOperand(0), Op.getOperand(1),
794d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      SDValue(CGLoad, 0)));
795825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
796d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
7977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl));
798d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
799ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen    return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
800d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      Op.getOperand(0), Op.getOperand(1),
801d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                                      SDValue(CGLoad, 0)));
802c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (Opc == ISD::TRUNCATE) {
803c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = Op.getOperand(0);
804c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
805825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && OpVT == MVT::i32
806825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && Op0.getValueType() == MVT::i64) {
8079de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
8089de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      //
8099de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Take advantage of the fact that the upper 32 bits are in the
8109de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // i32 preferred slot and avoid shuffle gymnastics:
811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      if (CN != 0) {
813c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        unsigned shift_amt = unsigned(CN->getZExtValue());
814c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
815c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        if (shift_amt >= 32) {
816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          SDNode *hi32 =
817602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                  CurDAG->getMachineNode(SPU::ORr32_r64, dl, OpVT,
818602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                         Op0.getOperand(0));
819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          shift_amt -= 32;
821c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          if (shift_amt > 0) {
822c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            // Take care of the additional shift, if present:
823825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
824c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            unsigned Opc = SPU::ROTMAIr32_i32;
8259de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
826c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            if (Op0.getOpcode() == ISD::SRL)
827c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel              Opc = SPU::ROTMr32;
828c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
829602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
830602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                          shift);
831c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          }
832c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
833c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          return hi32;
834c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        }
835c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      }
836c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
83702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SHL) {
838825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::i64) {
83902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      return SelectSHLi64(Op, OpVT);
84002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
84102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRL) {
842825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::i64) {
84302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      return SelectSRLi64(Op, OpVT);
84402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
84502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRA) {
846825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::i64) {
84702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      return SelectSRAi64(Op, OpVT);
84802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FNEG
850825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
8517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    DebugLoc dl = Op.getDebugLoc();
8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Check if the pattern is a special form of DFNMS:
8537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDValue Op0 = Op.getOperand(0);
8557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    if (Op0.getOpcode() == ISD::FSUB) {
8567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op00 = Op0.getOperand(0);
8577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      if (Op00.getOpcode() == ISD::FMUL) {
8587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        unsigned Opc = SPU::DFNMSf64;
859825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        if (OpVT == MVT::v2f64)
8607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Opc = SPU::DFNMSv2f64;
8617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
862602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        return CurDAG->getMachineNode(Opc, dl, OpVT,
863602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(0),
864602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(1),
865602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op0.getOperand(1));
8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
8677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
869825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
8707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *signMask = 0;
871a82d3f7c57f03457c385add1687319d5c290f867Scott Michel    unsigned Opc = SPU::XORfneg64;
8727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
873825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
874825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      signMask = SelectI64Constant(negConst, MVT::i64, dl);
875825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
876a82d3f7c57f03457c385add1687319d5c290f867Scott Michel      Opc = SPU::XORfnegvec;
8777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
878825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                                 MVT::v2i64,
8797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                                 negConst, negConst));
8807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
882602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(Opc, dl, OpVT,
883602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  Op.getOperand(0), SDValue(signMask, 0));
8847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FABS) {
885825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
886825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
887602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
888602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    Op.getOperand(0), SDValue(signMask, 0));
889825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
890825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
891825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
8927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                       absConst, absConst);
8937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDNode *signMask = emitBuildVector(absVec);
894602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
895602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    Op.getOperand(0), SDValue(signMask, 0));
8967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
897266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
898266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
899e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = N->getValueType(0);
900475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
901475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
902266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
903a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
904a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel
905a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_ins == 0) {
906dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      std::string msg;
907dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      raw_string_ostream Msg(msg);
908dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      Msg << "LDRESULT for unsupported type: "
909e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson           << VT.getEVTString();
910dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      llvm_report_error(Msg.str());
911a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    }
912266bc8f7774b153401e54ed537db299159840981Scott Michel
913a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    Opc = vtm->ldresult_ins;
914a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_imm) {
915475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Zero = CurDAG->getTargetConstant(0, VT);
91686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
917602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain);
91886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
919602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain);
92086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
92186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
922266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
923053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
924f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // Look at the operands: SelectCode() will catch the cases that aren't
925f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // specifically handled here.
926f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    //
927f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // SPUInstrInfo catches the following patterns:
928f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect (SPUhi ...), (SPUlo ...))
929f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect $sp, imm)
930e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = Op.getValueType();
931f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op0 = N->getOperand(0);
932f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op1 = N->getOperand(1);
933f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    RegisterSDNode *RN;
934f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel
935f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
936f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        || (Op0.getOpcode() == ISD::Register
937f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
938f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel                && RN->getReg() != SPU::R1))) {
939f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      NewOpc = SPU::Ar32;
94058c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
94158c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
942f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
9437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32);
94458c5818c01e375a84dc601140470fa68638004cfScott Michel      }
945f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[0] = Op0;
946f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[1] = Op1;
947f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      n_ops = 2;
94858c5818c01e375a84dc601140470fa68638004cfScott Michel    }
949266bc8f7774b153401e54ed537db299159840981Scott Michel  }
95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
95158c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
95258c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
95358c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
95458c5818c01e375a84dc601140470fa68638004cfScott Michel    else
955602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
95658c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
95758c5818c01e375a84dc601140470fa68638004cfScott Michel    return SelectCode(Op);
958266bc8f7774b153401e54ed537db299159840981Scott Michel}
959266bc8f7774b153401e54ed537db299159840981Scott Michel
96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
96102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm
96202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted
96302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left.
96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
96502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl.
96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
96802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
96902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
97002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
97102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
97202d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
973e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) {
97402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue Op0 = Op.getOperand(0);
97523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
97623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue ShiftAmt = Op.getOperand(1);
978e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SelMaskVal;
981ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = Op.getDebugLoc();
98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
983602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0);
984825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
985602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
986602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
987602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    CurDAG->getTargetConstant(0, OpVT));
988602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(ZeroFill, 0),
990602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(VecOp0, 0),
991602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(SelMask, 0));
99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
99402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
99502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
99602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
999602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
1000602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
1001602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
100202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
100302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
100402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
100502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
1007602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
1008602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
101102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1013602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1014602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
101502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1017602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1018602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
1021602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
102202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1023602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
1024602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1027602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0));
102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
102902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
103002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
103102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts.
103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
103502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
103702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
103802d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1039e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) {
104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue Op0 = Op.getOperand(0);
104123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
104223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue ShiftAmt = Op.getOperand(1);
1044e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *Shift = 0;
1046ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = Op.getDebugLoc();
104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1048602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0);
104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
105302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1056602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
1057602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
1058602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
105902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
106002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
1064602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
1065602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
106802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1070602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1071602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
107202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1073602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1074602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1075602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    // Ensure that the shift amounts are negated!
1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1079602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   SDValue(Bytes, 0),
1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
108102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1082602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1083602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(Bits, 0),
1084602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1087602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1088602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1090602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1091602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0));
109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
109602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts.
109902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
110002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
110102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
110202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
110302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
110502d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1106e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) {
110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  // Promote Op0 to vector
110823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
110923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue ShiftAmt = Op.getOperand(1);
1111e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
1112ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = Op.getDebugLoc();
111302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
111402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0 =
1115602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op.getOperand(0));
111602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
111802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *SignRot =
1119602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1120602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0), SignRotAmt);
112102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSign =
1122602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ORi32_v4i32, dl, MVT::i32, SDValue(SignRot, 0));
112302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
112402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSignMask =
1125602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
112602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerMask =
1127602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1128602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
112902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerSelect =
1130602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1131602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperHalfSignMask, 0),
1132602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0),
1133602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperLowerMask, 0));
113402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
113502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *Shift = 0;
113602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
113702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
113802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
113902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
114002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
114102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
114202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bytes = 31 - bytes;
114302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1144602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1145602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(UpperLowerSelect, 0),
1146602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
114702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
114802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
114902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
115002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bits = 8 - bits;
115102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1152602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1153602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1154602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
115502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
115602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
115702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *NegShift =
1158602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1159602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
116002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
116102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1162602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1163602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
116402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1165602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1166602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(NegShift, 0));
116702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
116802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1169602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0));
117002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
117102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1172c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*!
1173c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant
1174c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */
1175e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, EVT OpVT,
11767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
1177c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
11787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
11797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel}
11807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1181e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
11827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
118323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  SDValue i64vec =
11857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // Here's where it gets interesting, because we have to parse out the
1188c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // subtree handed back in i64vec:
1189c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1190c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (i64vec.getOpcode() == ISD::BIT_CONVERT) {
1191c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // The degenerate case where the upper and lower bits in the splat are
1192c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // identical:
1193c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = i64vec.getOperand(0);
1194c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
11959de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ReplaceUses(i64vec, Op0);
1196602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
1197602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(emitBuildVector(Op0), 0));
1198c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue lhs = i64vec.getOperand(0);
1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue rhs = i64vec.getOperand(1);
1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue shufmask = i64vec.getOperand(2);
1202c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1203c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (lhs.getOpcode() == ISD::BIT_CONVERT) {
1204c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(lhs, lhs.getOperand(0));
1205c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      lhs = lhs.getOperand(0);
1206c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1207c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1208c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1209c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? lhs.getNode()
1210c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       : emitBuildVector(lhs));
1211c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1212c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (rhs.getOpcode() == ISD::BIT_CONVERT) {
1213c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(rhs, rhs.getOperand(0));
1214c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      rhs = rhs.getOperand(0);
1215c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1217c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1218c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? rhs.getNode()
1219c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       : emitBuildVector(rhs));
12209de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
1221c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (shufmask.getOpcode() == ISD::BIT_CONVERT) {
1222c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(shufmask, shufmask.getOperand(0));
1223c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      shufmask = shufmask.getOperand(0);
1224c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1225c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1226c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1227c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            ? shufmask.getNode()
1228c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            : emitBuildVector(shufmask));
1229c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1230c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufNode =
1231ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1232c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1233c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(shufMaskNode, 0)));
1234c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1235602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
1236602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(shufNode, 0));
12377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
1238602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
1239602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(emitBuildVector(i64vec), 0));
1240c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else {
1241dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin    llvm_report_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1242dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "condition");
1243c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
1244c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel}
1245c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
124602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a
1247266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
1248266bc8f7774b153401e54ed537db299159840981Scott Michel///
1249266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1250266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
1251266bc8f7774b153401e54ed537db299159840981Scott Michel}
1252