SPUISelDAGToDAG.cpp revision 1cd1b0b283079b5a8c54759983e9e70845971b2c
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 "SPUHazardRecognizers.h"
18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h"
19203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h"
2094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h"
21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h"
22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h"
23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h"
24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h"
25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h"
2694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h"
27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
32a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h"
33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
35266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
37dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
38266bc8f7774b153401e54ed537db299159840981Scott Michel
39266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
40266bc8f7774b153401e54ed537db299159840981Scott Michel
41266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
42266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
43266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
44266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
45266bc8f7774b153401e54ed537db299159840981Scott Michel  {
467e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
47266bc8f7774b153401e54ed537db299159840981Scott Michel  }
48266bc8f7774b153401e54ed537db299159840981Scott Michel
49504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
50504c369213efb263136bb048e79af3516511c040Scott Michel  bool
51504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
52504c369213efb263136bb048e79af3516511c040Scott Michel  {
5334247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>(CN->getSExtValue());
54504c369213efb263136bb048e79af3516511c040Scott Michel  }
55504c369213efb263136bb048e79af3516511c040Scott Michel
56266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
57266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
58266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
59266bc8f7774b153401e54ed537db299159840981Scott Michel  {
607e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
61266bc8f7774b153401e54ed537db299159840981Scott Michel  }
62266bc8f7774b153401e54ed537db299159840981Scott Michel
63ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
64ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
65ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
66ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
6734247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>((short) CN->getZExtValue());
68ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
69ec2a08ff061af36b46160e475362959f21663e76Scott Michel
70266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
71266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
72266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
73266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
74266bc8f7774b153401e54ed537db299159840981Scott Michel
75266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
76266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
77266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
78266bc8f7774b153401e54ed537db299159840981Scott Michel   */
79266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
80266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
81266bc8f7774b153401e54ed537db299159840981Scott Michel  {
82e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = CN->getValueType(0);
83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
85266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
86825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (vt == MVT::i32) {
87f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
88266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
89266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
90266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
91f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
92266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
93266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
94266bc8f7774b153401e54ed537db299159840981Scott Michel    }
95266bc8f7774b153401e54ed537db299159840981Scott Michel
96266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
97266bc8f7774b153401e54ed537db299159840981Scott Michel  }
98266bc8f7774b153401e54ed537db299159840981Scott Michel
99266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
100266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
101266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
102266bc8f7774b153401e54ed537db299159840981Scott Michel  {
103e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = FPN->getValueType(0);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt == MVT::f32) {
105d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
106266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
107266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
108266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
109266bc8f7774b153401e54ed537db299159840981Scott Michel    }
110266bc8f7774b153401e54ed537db299159840981Scott Michel
111266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
112266bc8f7774b153401e54ed537db299159840981Scott Michel  }
113266bc8f7774b153401e54ed537db299159840981Scott Michel
114266bc8f7774b153401e54ed537db299159840981Scott Michel  //===------------------------------------------------------------------===//
115e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  //! EVT to "useful stuff" mapping structure:
116266bc8f7774b153401e54ed537db299159840981Scott Michel
117266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
118e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT;
1197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    unsigned ldresult_ins;      /// LDRESULT instruction (0 = undefined)
120a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    bool ldresult_imm;          /// LDRESULT instruction requires immediate?
121f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    unsigned lrinst;            /// LR instruction
122266bc8f7774b153401e54ed537db299159840981Scott Michel  };
123266bc8f7774b153401e54ed537db299159840981Scott Michel
124266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i8,    SPU::ORBIr8,  true,  SPU::LRr8 },
126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i16,   SPU::ORHIr16, true,  SPU::LRr16 },
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i32,   SPU::ORIr32,  true,  SPU::LRr32 },
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::i64,   SPU::ORr64,   false, SPU::LRr64 },
129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::f32,   SPU::ORf32,   false, SPU::LRf32 },
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::f64,   SPU::ORf64,   false, SPU::LRf64 },
13158c5818c01e375a84dc601140470fa68638004cfScott Michel    // vector types... (sigh!)
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v16i8, 0,            false, SPU::LRv16i8 },
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v8i16, 0,            false, SPU::LRv8i16 },
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v4i32, 0,            false, SPU::LRv4i32 },
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v2i64, 0,            false, SPU::LRv2i64 },
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v4f32, 0,            false, SPU::LRv4f32 },
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    { MVT::v2f64, 0,            false, SPU::LRv2f64 }
138266bc8f7774b153401e54ed537db299159840981Scott Michel  };
139266bc8f7774b153401e54ed537db299159840981Scott Michel
140266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
141266bc8f7774b153401e54ed537db299159840981Scott Michel
142e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  const valtype_map_s *getValueTypeMapEntry(EVT VT)
143266bc8f7774b153401e54ed537db299159840981Scott Michel  {
144266bc8f7774b153401e54ed537db299159840981Scott Michel    const valtype_map_s *retval = 0;
145266bc8f7774b153401e54ed537db299159840981Scott Michel    for (size_t i = 0; i < n_valtype_map; ++i) {
146266bc8f7774b153401e54ed537db299159840981Scott Michel      if (valtype_map[i].VT == VT) {
1477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        retval = valtype_map + i;
1487f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        break;
149266bc8f7774b153401e54ed537db299159840981Scott Michel      }
150266bc8f7774b153401e54ed537db299159840981Scott Michel    }
151266bc8f7774b153401e54ed537db299159840981Scott Michel
152266bc8f7774b153401e54ed537db299159840981Scott Michel
153266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG
154266bc8f7774b153401e54ed537db299159840981Scott Michel    if (retval == 0) {
1551bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer      report_fatal_error("SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns"
1561bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer                         "NULL for " + Twine(VT.getEVTString()));
157266bc8f7774b153401e54ed537db299159840981Scott Michel    }
158266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
159266bc8f7774b153401e54ed537db299159840981Scott Michel
160266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
161266bc8f7774b153401e54ed537db299159840981Scott Michel  }
162266bc8f7774b153401e54ed537db299159840981Scott Michel
1637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the carry-generate shuffle mask.
1647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
166844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
1677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
169825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
170825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
171825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
17302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
176266bc8f7774b153401e54ed537db299159840981Scott Michel  }
177266bc8f7774b153401e54ed537db299159840981Scott Michel
1787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the borrow-generate shuffle mask
1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
1817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
1887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
191266bc8f7774b153401e54ed537db299159840981Scott Michel  }
19202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //===------------------------------------------------------------------===//
1947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
1957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// instructions for SelectionDAG operations.
1967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  ///
1977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  class SPUDAGToDAGISel :
1987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    public SelectionDAGISel
1997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  {
200d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetMachine &TM;
201d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetLowering &SPUtli;
2027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    unsigned GlobalBaseReg;
2037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  public:
2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
2067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SelectionDAGISel(tm),
2077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      TM(tm),
2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SPUtli(*tm.getTargetLowering())
2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    { }
2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
211ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman    virtual bool runOnMachineFunction(MachineFunction &MF) {
2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Make sure we re-emit a set of the global base reg if necessary
2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      GlobalBaseReg = 0;
214ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman      SelectionDAGISel::runOnMachineFunction(MF);
2157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return true;
216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
217266bc8f7774b153401e54ed537db299159840981Scott Michel
2187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI32Imm - Return a target constant with the specified value, of type
2197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i32.
2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI32Imm(uint32_t Imm) {
221825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i32);
22294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    }
22394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getSmallIPtrImm - Return a target constant of pointer type.
2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getSmallIPtrImm(unsigned Imm) {
2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
22717aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner    }
2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
229eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *emitBuildVector(SDNode *bvNode) {
230eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      EVT vecVT = bvNode->getValueType(0);
2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      DebugLoc dl = bvNode->getDebugLoc();
2327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Check to see if this vector can be represented as a CellSPU immediate
2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // constant by invoking all of the instruction selection predicates:
235825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (((vecVT == MVT::v8i16) &&
236825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
237825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v4i32) &&
238825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
239825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
240825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
242825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v2i64) &&
243825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
244825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
245a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
246a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        HandleSDNode Dummy(SDValue(bvNode, 0));
247a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        if (SDNode *N = Select(bvNode))
248a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner          return N;
249a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return Dummy.getValue().getNode();
250a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      }
2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // No, need to emit a constant pool spill:
2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      std::vector<Constant*> CV;
2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
255eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
256b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i));
257a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
2597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
26046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman      const Constant *CP = ConstantVector::get(CV);
2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CGPoolOffset =
264d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman              SPU::LowerConstantPool(CPIdx, *CurDAG, TM);
265a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
266a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
267a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         CurDAG->getEntryNode(), CGPoolOffset,
268a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         PseudoSourceValue::getConstantPool(),0,
269a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         false, false, Alignment));
270a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
271a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
272a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return N;
273a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return Dummy.getValue().getNode();
2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Select - Convert the specified operand from a target-independent to a
2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// target-specific node if it hasn't already been changed.
278eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *Select(SDNode *N);
2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 shl
281eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 srl
284eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 sra
287eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
2887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the necessary sequence for loading i64 constants:
290eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Alternate instruction emit sequence for loading i64 constants
293e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Returns true if the address N is an A-form (local store) address
296eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! D-form address predicate
300eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Alternate D-form address using i7 offset predicate
304eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                          SDValue &Base);
3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// D-form address selection workhorse
308eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                               SDValue &Base, int minOffset, int maxOffset);
3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Address predicate if N can be expressed as an indexed [r+r] operation.
312eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// inline asm expressions.
3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              char ConstraintCode,
3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              std::vector<SDValue> &OutOps) {
3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op0, Op1;
3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      switch (ConstraintCode) {
3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      default: return true;
3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'm':   // memory
324eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
325eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
326eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman          SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'o':   // offsetable
329eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
330eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op0 = Op;
3327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op1 = getSmallIPtrImm(0);
3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        }
3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'v':   // not offsetable
336266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
337c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
338266bc8f7774b153401e54ed537db299159840981Scott Michel#else
3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        SelectAddrIdxOnly(Op, Op, Op0, Op1);
340266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
34302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op0);
3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op1);
3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return false;
3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
348266bc8f7774b153401e54ed537db299159840981Scott Michel
3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual const char *getPassName() const {
3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return "Cell SPU DAG->DAG Pattern Instruction Selection";
3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
35202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// this target when scheduling the DAG.
3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      const TargetInstrInfo *II = TM.getInstrInfo();
3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      assert(II && "No InstrInfo?");
3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return new SPUHazardRecognizer(*II);
3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
3601cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila
3611cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  private:
3621cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    SDValue getRC( MVT );
363266bc8f7774b153401e54ed537db299159840981Scott Michel
3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Include the pieces autogenerated from the target description.
365266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  };
367844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
368844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
369266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
3709de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand
371266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
372266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
373266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
374266bc8f7774b153401e54ed537db299159840981Scott Michel */
375266bc8f7774b153401e54ed537db299159840981Scott Michelbool
376eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
377475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
378266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
379825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT OffsVT = MVT::i16;
380475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
381266bc8f7774b153401e54ed537db299159840981Scott Michel
382266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
383266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
38675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered.");
3879de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3909de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
39275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
393dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "not wrapped as A-form address.");
394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
395266bc8f7774b153401e54ed537db299159840981Scott Michel
39602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  case SPUISD::AFormAddr:
397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
400475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
407053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
408053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
409053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
41046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = GSDN->getGlobal();
411053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
412053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
413053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
414053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
415053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
416053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
417053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
418053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
419053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
420053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
422266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
423266bc8f7774b153401e54ed537db299159840981Scott Michel}
424266bc8f7774b153401e54ed537db299159840981Scott Michel
42502d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool
426eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
427475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
428203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
429203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
430203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
431203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
4327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
434266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
435266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
436266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
437266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
438266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
439266bc8f7774b153401e54ed537db299159840981Scott Michel
440266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
441266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
442266bc8f7774b153401e54ed537db299159840981Scott Michel
443266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
444475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
445266bc8f7774b153401e54ed537db299159840981Scott Michel*/
446266bc8f7774b153401e54ed537db299159840981Scott Michelbool
447eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
448475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
4497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
4509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::minFrameOffset(),
4519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::maxFrameOffset());
4527f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4537f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4547f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
455eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
456475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4577f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
458266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
459e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT PtrTy = SPUtli.getPointerTy();
460266bc8f7774b153401e54ed537db299159840981Scott Michel
461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
463b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman    FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N);
464203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
4654437ae213d5435390f0750213b53ec807c047f22Chris Lattner    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
466203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
467203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
468266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
469203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
470266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
471266bc8f7774b153401e54ed537db299159840981Scott Michel    }
472266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
473266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
474475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
475475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
476266bc8f7774b153401e54ed537db299159840981Scott Michel
477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
479053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
480053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
481053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
482053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
484b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4857810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
486266bc8f7774b153401e54ed537db299159840981Scott Michel
487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
488b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0);
489203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4904437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
491203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
493203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
4949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4999de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
500053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
502053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
503053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
504053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
505b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
5067810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
509b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1);
510203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
5114437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
512203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
513053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
514203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
516203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
521053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
522053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
523266bc8f7774b153401e54ed537db299159840981Scott Michel      }
524497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
525053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
526053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
527475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
528475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
529053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
532053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5339de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5359de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
538475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
5397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
5417f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
5427810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
5447f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
5457f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
5467810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
54802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      }
5497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5507f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
5517f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
5527f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
5537f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
5547f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5559de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
556053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
55958c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5607f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5617f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5627f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5637f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
564c6166c6bcaf41acab5f14aa267acec3214b75127Kalle Raiskila  } else if (Opc == ISD::Register
565c6166c6bcaf41acab5f14aa267acec3214b75127Kalle Raiskila           ||Opc == ISD::CopyFromReg
566bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::UNDEF
567bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::Constant) {
568eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    unsigned OpOpc = Op->getOpcode();
5699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5709c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
5719c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
57211fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila      SDValue Offs;
5739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
574eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
5759c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5769c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
5779c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
5789c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
5799c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5809c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
58111fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila        Index = N;
5829c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
5839c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
584aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
585aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
586aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
58719c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N.getOperand(1);
588aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
58919c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N;
590aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
591aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
592aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
593aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
5949c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
595266bc8f7774b153401e54ed537db299159840981Scott Michel  }
5969c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
597266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
598266bc8f7774b153401e54ed537db299159840981Scott Michel}
599266bc8f7774b153401e54ed537db299159840981Scott Michel
600266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
601266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
602266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
603266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
604266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
605266bc8f7774b153401e54ed537db299159840981Scott Michel
6069c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
6079c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
6089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
609266bc8f7774b153401e54ed537db299159840981Scott Michel*/
610266bc8f7774b153401e54ed537db299159840981Scott Michelbool
611eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
612475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
6139c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
6149c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
61518fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
61618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
6171a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
6181a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
61950843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
6209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
621266bc8f7774b153401e54ed537db299159840981Scott Michel
6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
62358c5818c01e375a84dc601140470fa68638004cfScott Michel}
62458c5818c01e375a84dc601140470fa68638004cfScott Michel
6251cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*!
6261cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue
6271cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a
6281cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call
6291cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class
6301cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/
6311cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) {
6321cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  switch( VT.SimpleTy ) {
6331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i32:
6341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32);
6351cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    break;
6361cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i64:
6371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32);
6381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    break;
6391cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::v2i64:
6401cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32);
6411cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    break;
6421cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  default:
6431cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    assert( false && "add a new case here" );
6441cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  }
6451cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  return SDValue();
6461cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila}
6471cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila
648266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
649266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
650266bc8f7774b153401e54ed537db299159840981Scott Michel */
651266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
652eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) {
653266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
65458c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
65558c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
656eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  EVT OpVT = N->getValueType(0);
657475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
658ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = N->getDebugLoc();
659266bc8f7774b153401e54ed537db299159840981Scott Michel
660a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner  if (N->isMachineOpcode())
661266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
662c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
663c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (Opc == ISD::FrameIndex) {
66402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
665eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
666eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
66702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
66802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (FI < 128) {
669203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
67002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = TFI;
67102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[1] = Imm0;
672203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
673203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
674203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
675eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
676602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
677eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                              N->getValueType(0), TFI, Imm0),
678602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                       0);
679203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
680203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
682c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // Catch the i64 constants that end up here. Note: The backend doesn't
683c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // attempt to legalize the constant (it's useless because DAGCombiner
684c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // will insert 64-bit constants and we can't stop it).
685eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectI64Constant(N, OpVT, N->getDebugLoc());
68694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
687825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && OpVT == MVT::i64) {
688eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
689e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT Op0VT = Op0.getValueType();
69023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
69123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                    Op0VT, (128 / Op0VT.getSizeInBits()));
69223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
69323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                   OpVT, (128 / OpVT.getSizeInBits()));
69494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue shufMask;
69594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
696825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    switch (Op0VT.getSimpleVT().SimpleTy) {
69794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    default:
69875361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner      report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT");
69994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      /*NOTREACHED*/
700825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i32:
701825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
702825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
703825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x00010203, MVT::i32),
704825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
705825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
70694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
70794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
708825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i16:
709825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
710825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
711825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800203, MVT::i32),
712825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
713825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
71494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
71594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
716825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i8:
717825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
718825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
719825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808003, MVT::i32),
720825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
721825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x8080800b, MVT::i32));
72294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
72358c5818c01e375a84dc601140470fa68638004cfScott Michel    }
72494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
725eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
727a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                               Op0VecVT, Op0));
729a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
730a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDValue PromScalar;
731a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
732a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = SDValue(N, 0);
733a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
734a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = PromoteScalar.getValue();
735a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
73694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue zextShuffle =
737ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                            PromScalar, PromScalar,
739d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(shufMaskLoad, 0));
74094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
741a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy2(zextShuffle);
742a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
743a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = SDValue(N, 0);
744a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
745a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = Dummy2.getValue();
746a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
747a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       zextShuffle));
748a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
749a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
750a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SelectCode(Dummy.getValue().getNode());
751a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
752825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
75394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *CGLoad =
754eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
755d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
756a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
757a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
758a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
759a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
760a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
761a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
762a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
763a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
764825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
765d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
766eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
767d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
768a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
769a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
770a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
771a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
772a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
773a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
774a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
775a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
776825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
777d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
778eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
779d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
780a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
781a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
782a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
783a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
784a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
785a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
786a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
787c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (Opc == ISD::TRUNCATE) {
788eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
789c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
790825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && OpVT == MVT::i32
791825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && Op0.getValueType() == MVT::i64) {
7929de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
7939de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      //
7949de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Take advantage of the fact that the upper 32 bits are in the
7959de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // i32 preferred slot and avoid shuffle gymnastics:
796c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
797c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      if (CN != 0) {
798c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        unsigned shift_amt = unsigned(CN->getZExtValue());
799c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
800c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        if (shift_amt >= 32) {
801c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          SDNode *hi32 =
8021cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                  CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
8031cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                         Op0.getOperand(0), getRC(MVT::i32));
804c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
805c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          shift_amt -= 32;
806c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          if (shift_amt > 0) {
807c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            // Take care of the additional shift, if present:
808825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
809c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            unsigned Opc = SPU::ROTMAIr32_i32;
8109de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            if (Op0.getOpcode() == ISD::SRL)
812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel              Opc = SPU::ROTMr32;
813c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
814602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
815602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                          shift);
816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          }
817c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
818c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          return hi32;
819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        }
820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      }
821c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
82202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SHL) {
823a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
824eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSHLi64(N, OpVT);
82502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRL) {
826a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
827eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRLi64(N, OpVT);
82802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRA) {
829a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
830eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRAi64(N, OpVT);
8317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FNEG
832825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
833eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    DebugLoc dl = N->getDebugLoc();
8347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Check if the pattern is a special form of DFNMS:
8357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
836eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
8377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    if (Op0.getOpcode() == ISD::FSUB) {
8387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op00 = Op0.getOperand(0);
8397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      if (Op00.getOpcode() == ISD::FMUL) {
8407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        unsigned Opc = SPU::DFNMSf64;
841825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        if (OpVT == MVT::v2f64)
8427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Opc = SPU::DFNMSv2f64;
8437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
844602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        return CurDAG->getMachineNode(Opc, dl, OpVT,
845602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(0),
846602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(1),
847602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op0.getOperand(1));
8487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
851825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *signMask = 0;
853a82d3f7c57f03457c385add1687319d5c290f867Scott Michel    unsigned Opc = SPU::XORfneg64;
8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
855825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
856eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
857825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
858a82d3f7c57f03457c385add1687319d5c290f867Scott Michel      Opc = SPU::XORfnegvec;
8597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
860825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                                 MVT::v2i64,
861eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                                 negConst, negConst).getNode());
8627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
864602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(Opc, dl, OpVT,
865eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                  N->getOperand(0), SDValue(signMask, 0));
8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FABS) {
867825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
868825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
869602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
870eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
871825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
872825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
873825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
8747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                       absConst, absConst);
875eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      SDNode *signMask = emitBuildVector(absVec.getNode());
876602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
877eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
8787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
879266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
880266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
881e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = N->getValueType(0);
882475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
883475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
884266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
885a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
886a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel
887a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_ins == 0) {
8881bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer      report_fatal_error("LDRESULT for unsupported type: " +
8891bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer                         Twine(VT.getEVTString()));
890a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    }
891266bc8f7774b153401e54ed537db299159840981Scott Michel
892a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    Opc = vtm->ldresult_ins;
893a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_imm) {
894475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Zero = CurDAG->getTargetConstant(0, VT);
89586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
896602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain);
89786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
898602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain);
89986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
90086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
901266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
902053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
903f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // Look at the operands: SelectCode() will catch the cases that aren't
904f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // specifically handled here.
905f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    //
906f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // SPUInstrInfo catches the following patterns:
907f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect (SPUhi ...), (SPUlo ...))
908f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect $sp, imm)
909eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    EVT VT = N->getValueType(0);
910f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op0 = N->getOperand(0);
911f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op1 = N->getOperand(1);
912f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    RegisterSDNode *RN;
913f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel
914f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
915f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        || (Op0.getOpcode() == ISD::Register
916f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
917f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel                && RN->getReg() != SPU::R1))) {
918f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      NewOpc = SPU::Ar32;
919d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner      Ops[1] = Op1;
92058c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
92158c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
922f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
923d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        if (isInt<10>(CN->getSExtValue())) {
924d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          NewOpc = SPU::AIr32;
925d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          Ops[1] = Op1;
926d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        } else {
927d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl,
928d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                                                  N->getValueType(0),
929d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                                                  Op1),
930d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                           0);
931d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        }
93258c5818c01e375a84dc601140470fa68638004cfScott Michel      }
933f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[0] = Op0;
934f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      n_ops = 2;
93558c5818c01e375a84dc601140470fa68638004cfScott Michel    }
936266bc8f7774b153401e54ed537db299159840981Scott Michel  }
93702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
93858c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
93958c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
94058c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
94158c5818c01e375a84dc601140470fa68638004cfScott Michel    else
942602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
94358c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
944eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectCode(N);
945266bc8f7774b153401e54ed537db299159840981Scott Michel}
946266bc8f7774b153401e54ed537db299159840981Scott Michel
94702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
94802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm
94902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted
95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left.
95102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
95202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl.
95302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
95402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
95502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
95702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
95802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
95902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
960eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
961eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
96223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
96323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
964eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
965e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SelMaskVal;
968eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
96902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9701cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9711cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
972825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
973602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
974602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
975602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    CurDAG->getTargetConstant(0, OpVT));
976602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
977602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(ZeroFill, 0),
978602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(VecOp0, 0),
979602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(SelMask, 0));
98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
98402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
98602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
987602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
988602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
99002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
994602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
995602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
996602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1000602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1001602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1002602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
100302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1004602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1005602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
100702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1008602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
1009602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
10151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10161cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
101702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
101802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
102002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts.
102102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
102202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
102302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
102702d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1028eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
1029eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
103023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
103123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
1032eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
1033e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *Shift = 0;
1035eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
10371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
10381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
103902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
104102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
104202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
104402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1046602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
1047602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
1048602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1053602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
1054602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
1055602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
105602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
105702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
105802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1059602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1060602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1061602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1064602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1065602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    // Ensure that the shift amounts are negated!
1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   SDValue(Bytes, 0),
1070602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
107102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1072602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1073602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(Bits, 0),
1074602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
107502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1077602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
108202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
108302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
10841cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10851cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts.
109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
109402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
109602d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1097eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  // Promote Op0 to vector
109923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
110023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
1101eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
1102e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
1103eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
110502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0 =
11061cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11071cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           VecVT, N->getOperand(0), getRC(MVT::v2i64));
110802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
110902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *SignRot =
1111602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1112602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0), SignRotAmt);
111302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSign =
11141cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32));
111602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSignMask =
1118602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
111902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerMask =
1120602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1121602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
112202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerSelect =
1123602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1124602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperHalfSignMask, 0),
1125602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0),
1126602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperLowerMask, 0));
112702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
112802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *Shift = 0;
112902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
113002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
113102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
113202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
113302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
113402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
113502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bytes = 31 - bytes;
113602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1137602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1138602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(UpperLowerSelect, 0),
1139602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
114002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
114102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
114202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
114302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bits = 8 - bits;
114402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1145602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1146602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1147602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
114802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
114902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
115002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *NegShift =
1151602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1152602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
115302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
115402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1155602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1156602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
115702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1158602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1159602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(NegShift, 0));
116002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
116102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
11621cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11631cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
116402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
116502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*!
1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant
1168c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */
1169eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
11707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
1171eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  ConstantSDNode *CN = cast<ConstantSDNode>(N);
11727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
11737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel}
11747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1175e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
11767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
117723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1178c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  SDValue i64vec =
11797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1180c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // Here's where it gets interesting, because we have to parse out the
1182c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // subtree handed back in i64vec:
1183c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (i64vec.getOpcode() == ISD::BIT_CONVERT) {
1185c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // The degenerate case where the upper and lower bits in the splat are
1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // identical:
1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = i64vec.getOperand(0);
1188c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
11899de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ReplaceUses(i64vec, Op0);
11901cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11911cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(Op0.getNode()), 0),
11921cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1193c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1194c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue lhs = i64vec.getOperand(0);
1195c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue rhs = i64vec.getOperand(1);
1196c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue shufmask = i64vec.getOperand(2);
1197c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1198c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (lhs.getOpcode() == ISD::BIT_CONVERT) {
1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(lhs, lhs.getOperand(0));
1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      lhs = lhs.getOperand(0);
1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1202c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1203c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1204c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? lhs.getNode()
1205eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(lhs.getNode()));
1206c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1207c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (rhs.getOpcode() == ISD::BIT_CONVERT) {
1208c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(rhs, rhs.getOperand(0));
1209c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      rhs = rhs.getOperand(0);
1210c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1211c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1212c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1213c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? rhs.getNode()
1214eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(rhs.getNode()));
12159de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
1216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if (shufmask.getOpcode() == ISD::BIT_CONVERT) {
1217c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(shufmask, shufmask.getOperand(0));
1218c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      shufmask = shufmask.getOperand(0);
1219c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1220c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1221c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1222c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            ? shufmask.getNode()
1223eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                            : emitBuildVector(shufmask.getNode()));
1224c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1225a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner   SDValue shufNode =
1226a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1227c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1228a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                   SDValue(shufMaskNode, 0));
1229a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(shufNode);
1230a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDNode *SN = SelectCode(Dummy.getValue().getNode());
1231a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SN == 0) SN = Dummy.getValue().getNode();
1232a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner
12331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
12341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  OpVT, SDValue(SN, 0), getRC(MVT::i64));
12357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
12361cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
12371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(i64vec.getNode()), 0),
12381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1239c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else {
124075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1241dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "condition");
1242c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
1243c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel}
1244c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
124502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a
1246266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
1247266bc8f7774b153401e54ed537db299159840981Scott Michel///
1248266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1249266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
1250266bc8f7774b153401e54ed537db299159840981Scott Michel}
1251