SPUISelDAGToDAG.cpp revision 7810bfed5570c192e0714a8fd0e5130a0c38dd2e
14ee451de366474b9c228b4e5fa573795a715216dChris Lattner//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===//
2266bc8f7774b153401e54ed537db299159840981Scott Michel//
3266bc8f7774b153401e54ed537db299159840981Scott Michel//                     The LLVM Compiler Infrastructure
4266bc8f7774b153401e54ed537db299159840981Scott Michel//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7266bc8f7774b153401e54ed537db299159840981Scott Michel//
8266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
9266bc8f7774b153401e54ed537db299159840981Scott Michel//
10266bc8f7774b153401e54ed537db299159840981Scott Michel// This file defines a pattern matching instruction selector for the Cell SPU,
11266bc8f7774b153401e54ed537db299159840981Scott Michel// converting from a legalized dag to a SPU-target dag.
12266bc8f7774b153401e54ed537db299159840981Scott Michel//
13266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
14266bc8f7774b153401e54ed537db299159840981Scott Michel
15266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPU.h"
16266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUTargetMachine.h"
17266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUISelLowering.h"
18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h"
19266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h"
20203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h"
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"
26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
34266bc8f7774b153401e54ed537db299159840981Scott Michel#include <queue>
35266bc8f7774b153401e54ed537db299159840981Scott Michel#include <set>
36266bc8f7774b153401e54ed537db299159840981Scott Michel
37266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
38266bc8f7774b153401e54ed537db299159840981Scott Michel
39266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
40266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
41266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
42266bc8f7774b153401e54ed537db299159840981Scott Michel  isI64IntS10Immediate(ConstantSDNode *CN)
43266bc8f7774b153401e54ed537db299159840981Scott Michel  {
447810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
45266bc8f7774b153401e54ed537db299159840981Scott Michel  }
46266bc8f7774b153401e54ed537db299159840981Scott Michel
47266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
48266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
49266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
50266bc8f7774b153401e54ed537db299159840981Scott Michel  {
517810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
52266bc8f7774b153401e54ed537db299159840981Scott Michel  }
53266bc8f7774b153401e54ed537db299159840981Scott Michel
54266bc8f7774b153401e54ed537db299159840981Scott Michel#if 0
55266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for sign-extended, 10-bit immediate values
56266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
57266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(SDNode *N)
58266bc8f7774b153401e54ed537db299159840981Scott Michel  {
59266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
60266bc8f7774b153401e54ed537db299159840981Scott Michel            && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
61266bc8f7774b153401e54ed537db299159840981Scott Michel  }
62266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
63266bc8f7774b153401e54ed537db299159840981Scott Michel
64504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
65504c369213efb263136bb048e79af3516511c040Scott Michel  bool
66504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
67504c369213efb263136bb048e79af3516511c040Scott Michel  {
687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isU10Constant(CN->getSExtValue());
69504c369213efb263136bb048e79af3516511c040Scott Michel  }
70504c369213efb263136bb048e79af3516511c040Scott Michel
71266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
72266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
73266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
74266bc8f7774b153401e54ed537db299159840981Scott Michel  {
757810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
76266bc8f7774b153401e54ed537db299159840981Scott Michel  }
77266bc8f7774b153401e54ed537db299159840981Scott Michel
78266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
79266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
80266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(SDNode *N)
81266bc8f7774b153401e54ed537db299159840981Scott Michel  {
82266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
83266bc8f7774b153401e54ed537db299159840981Scott Michel            && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
84266bc8f7774b153401e54ed537db299159840981Scott Michel  }
85266bc8f7774b153401e54ed537db299159840981Scott Michel
86ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
87ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
88ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
89ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
90f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return isU10Constant((short) CN->getZExtValue());
91ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
92ec2a08ff061af36b46160e475362959f21663e76Scott Michel
93ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
94ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
95ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(SDNode *N)
96ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
97ec2a08ff061af36b46160e475362959f21663e76Scott Michel    return (N->getOpcode() == ISD::Constant
98ec2a08ff061af36b46160e475362959f21663e76Scott Michel            && isI16IntU10Immediate(cast<ConstantSDNode>(N)));
99ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
100ec2a08ff061af36b46160e475362959f21663e76Scott Michel
101266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
102266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
103266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
104266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
105266bc8f7774b153401e54ed537db299159840981Scott Michel
106266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
107266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
108266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
109266bc8f7774b153401e54ed537db299159840981Scott Michel   */
110266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
111266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
112266bc8f7774b153401e54ed537db299159840981Scott Michel  {
11383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT vt = CN->getValueType(0);
114f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
1158e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
116266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
117266bc8f7774b153401e54ed537db299159840981Scott Michel    } else if (vt == MVT::i32) {
118f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
119266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
120266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
121266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
122f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
123266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
124266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
125266bc8f7774b153401e54ed537db299159840981Scott Michel    }
126266bc8f7774b153401e54ed537db299159840981Scott Michel
127266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
128266bc8f7774b153401e54ed537db299159840981Scott Michel  }
129266bc8f7774b153401e54ed537db299159840981Scott Michel
130266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for signed 16-bit values.
131266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
132266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(SDNode *N, short &Imm)
133266bc8f7774b153401e54ed537db299159840981Scott Michel  {
134266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
135266bc8f7774b153401e54ed537db299159840981Scott Michel            && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
136266bc8f7774b153401e54ed537db299159840981Scott Michel  }
137266bc8f7774b153401e54ed537db299159840981Scott Michel
138266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
139266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
140266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
141266bc8f7774b153401e54ed537db299159840981Scott Michel  {
14283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT vt = FPN->getValueType(0);
143266bc8f7774b153401e54ed537db299159840981Scott Michel    if (vt == MVT::f32) {
144d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
145266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
146266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
147266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
148266bc8f7774b153401e54ed537db299159840981Scott Michel    }
149266bc8f7774b153401e54ed537db299159840981Scott Michel
150266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
151266bc8f7774b153401e54ed537db299159840981Scott Michel  }
152266bc8f7774b153401e54ed537db299159840981Scott Michel
153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  bool
154475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  isHighLow(const SDValue &Op)
155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  {
156053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    return (Op.getOpcode() == SPUISD::IndirectAddr
157053c1da8d956a794d158ac906b3927c923f97c4dScott Michel            && ((Op.getOperand(0).getOpcode() == SPUISD::Hi
158053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 && Op.getOperand(1).getOpcode() == SPUISD::Lo)
159053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                || (Op.getOperand(0).getOpcode() == SPUISD::Lo
160053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                    && Op.getOperand(1).getOpcode() == SPUISD::Hi)));
161053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
162053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
163266bc8f7774b153401e54ed537db299159840981Scott Michel  //===------------------------------------------------------------------===//
16483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  //! MVT to "useful stuff" mapping structure:
165266bc8f7774b153401e54ed537db299159840981Scott Michel
166266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
16783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT;
1687f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    unsigned ldresult_ins;      /// LDRESULT instruction (0 = undefined)
169a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    bool ldresult_imm;          /// LDRESULT instruction requires immediate?
1707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    int prefslot_byte;          /// Byte offset of the "preferred" slot
171266bc8f7774b153401e54ed537db299159840981Scott Michel  };
172266bc8f7774b153401e54ed537db299159840981Scott Michel
173266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
174a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i1,    0,            false, 3 },
175a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i8,    SPU::ORBIr8,  true,  3 },
176a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i16,   SPU::ORHIr16, true,  2 },
177a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i32,   SPU::ORIr32,  true,  0 },
178a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i64,   SPU::ORr64,   false, 0 },
179a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::f32,   SPU::ORf32,   false, 0 },
180a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::f64,   SPU::ORf64,   false, 0 },
18158c5818c01e375a84dc601140470fa68638004cfScott Michel    // vector types... (sigh!)
182a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v16i8, 0,            false, 0 },
183a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v8i16, 0,            false, 0 },
184a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v4i32, 0,            false, 0 },
185a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v2i64, 0,            false, 0 },
186a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v4f32, 0,            false, 0 },
187a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v2f64, 0,            false, 0 }
188266bc8f7774b153401e54ed537db299159840981Scott Michel  };
189266bc8f7774b153401e54ed537db299159840981Scott Michel
190266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
191266bc8f7774b153401e54ed537db299159840981Scott Michel
19283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  const valtype_map_s *getValueTypeMapEntry(MVT VT)
193266bc8f7774b153401e54ed537db299159840981Scott Michel  {
194266bc8f7774b153401e54ed537db299159840981Scott Michel    const valtype_map_s *retval = 0;
195266bc8f7774b153401e54ed537db299159840981Scott Michel    for (size_t i = 0; i < n_valtype_map; ++i) {
196266bc8f7774b153401e54ed537db299159840981Scott Michel      if (valtype_map[i].VT == VT) {
1977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        retval = valtype_map + i;
1987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        break;
199266bc8f7774b153401e54ed537db299159840981Scott Michel      }
200266bc8f7774b153401e54ed537db299159840981Scott Michel    }
201266bc8f7774b153401e54ed537db299159840981Scott Michel
202266bc8f7774b153401e54ed537db299159840981Scott Michel
203266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG
204266bc8f7774b153401e54ed537db299159840981Scott Michel    if (retval == 0) {
205266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
20683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands           << VT.getMVTString()
2077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel           << "\n";
208266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
209266bc8f7774b153401e54ed537db299159840981Scott Michel    }
210266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
211266bc8f7774b153401e54ed537db299159840981Scott Michel
212266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
213266bc8f7774b153401e54ed537db299159840981Scott Michel  }
214266bc8f7774b153401e54ed537db299159840981Scott Michel}
215266bc8f7774b153401e54ed537db299159840981Scott Michel
216844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace {
217844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
218266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===//
219266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
220266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations.
221266bc8f7774b153401e54ed537db299159840981Scott Michel///
222266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel :
223266bc8f7774b153401e54ed537db299159840981Scott Michel  public SelectionDAGISel
224266bc8f7774b153401e54ed537db299159840981Scott Michel{
225266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetMachine &TM;
226266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetLowering &SPUtli;
227266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned GlobalBaseReg;
228266bc8f7774b153401e54ed537db299159840981Scott Michel
229266bc8f7774b153401e54ed537db299159840981Scott Michelpublic:
2301002c0203450620594a85454c6a095ca94b87cb2Dan Gohman  explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
231266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel(*tm.getTargetLowering()),
232266bc8f7774b153401e54ed537db299159840981Scott Michel    TM(tm),
233266bc8f7774b153401e54ed537db299159840981Scott Michel    SPUtli(*tm.getTargetLowering())
234266bc8f7774b153401e54ed537db299159840981Scott Michel  {}
235266bc8f7774b153401e54ed537db299159840981Scott Michel
236266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool runOnFunction(Function &Fn) {
237266bc8f7774b153401e54ed537db299159840981Scott Michel    // Make sure we re-emit a set of the global base reg if necessary
238266bc8f7774b153401e54ed537db299159840981Scott Michel    GlobalBaseReg = 0;
239266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel::runOnFunction(Fn);
240266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
241266bc8f7774b153401e54ed537db299159840981Scott Michel  }
242266bc8f7774b153401e54ed537db299159840981Scott Michel
243266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI32Imm - Return a target constant with the specified value, of type
244266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i32.
245475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getI32Imm(uint32_t Imm) {
246266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i32);
247266bc8f7774b153401e54ed537db299159840981Scott Michel  }
248266bc8f7774b153401e54ed537db299159840981Scott Michel
249266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI64Imm - Return a target constant with the specified value, of type
250266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i64.
251475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getI64Imm(uint64_t Imm) {
252266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i64);
253266bc8f7774b153401e54ed537db299159840981Scott Michel  }
254266bc8f7774b153401e54ed537db299159840981Scott Michel
255266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getSmallIPtrImm - Return a target constant of pointer type.
256475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getSmallIPtrImm(unsigned Imm) {
257266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
258266bc8f7774b153401e54ed537db299159840981Scott Michel  }
259266bc8f7774b153401e54ed537db299159840981Scott Michel
260266bc8f7774b153401e54ed537db299159840981Scott Michel  /// Select - Convert the specified operand from a target-independent to a
261266bc8f7774b153401e54ed537db299159840981Scott Michel  /// target-specific node if it hasn't already been changed.
262475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDNode *Select(SDValue Op);
263266bc8f7774b153401e54ed537db299159840981Scott Michel
264266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Returns true if the address N is an A-form (local store) address
265475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
266475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
267266bc8f7774b153401e54ed537db299159840981Scott Michel
268266bc8f7774b153401e54ed537db299159840981Scott Michel  //! D-form address predicate
269475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
270475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
2717f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2727f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// Alternate D-form address using i7 offset predicate
273475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
274475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                        SDValue &Base);
2757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// D-form address selection workhorse
277475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp,
278475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                             SDValue &Base, int minOffset, int maxOffset);
279266bc8f7774b153401e54ed537db299159840981Scott Michel
280266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Address predicate if N can be expressed as an indexed [r+r] operation.
281475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
282475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
283266bc8f7774b153401e54ed537db299159840981Scott Michel
284266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
285266bc8f7774b153401e54ed537db299159840981Scott Michel  /// inline asm expressions.
286475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
2877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                            char ConstraintCode,
288f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman                                            std::vector<SDValue> &OutOps) {
289475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Op0, Op1;
290266bc8f7774b153401e54ed537db299159840981Scott Michel    switch (ConstraintCode) {
291266bc8f7774b153401e54ed537db299159840981Scott Michel    default: return true;
292266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'm':   // memory
293266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
2947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1))
2957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        SelectXFormAddr(Op, Op, Op0, Op1);
296266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
297266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'o':   // offsetable
298266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
2997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1)) {
3007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op0 = Op;
3017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op0);     // r+0.
3027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op1 = getSmallIPtrImm(0);
303266bc8f7774b153401e54ed537db299159840981Scott Michel      }
304266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
305266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'v':   // not offsetable
306266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
307266bc8f7774b153401e54ed537db299159840981Scott Michel      assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
308266bc8f7774b153401e54ed537db299159840981Scott Michel#else
309266bc8f7774b153401e54ed537db299159840981Scott Michel      SelectAddrIdxOnly(Op, Op, Op0, Op1);
310266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
311266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
312266bc8f7774b153401e54ed537db299159840981Scott Michel    }
313266bc8f7774b153401e54ed537db299159840981Scott Michel
314266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op0);
315266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op1);
316266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
317266bc8f7774b153401e54ed537db299159840981Scott Michel  }
318266bc8f7774b153401e54ed537db299159840981Scott Michel
319db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng  /// InstructionSelect - This callback is invoked by
320266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
321f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman  virtual void InstructionSelect();
322266bc8f7774b153401e54ed537db299159840981Scott Michel
323266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual const char *getPassName() const {
324266bc8f7774b153401e54ed537db299159840981Scott Michel    return "Cell SPU DAG->DAG Pattern Instruction Selection";
325266bc8f7774b153401e54ed537db299159840981Scott Michel  }
326266bc8f7774b153401e54ed537db299159840981Scott Michel
327266bc8f7774b153401e54ed537db299159840981Scott Michel  /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
328266bc8f7774b153401e54ed537db299159840981Scott Michel  /// this target when scheduling the DAG.
329266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual HazardRecognizer *CreateTargetHazardRecognizer() {
3306448d91ad1e5497fe2f7015d61b57cb5f3040879Dan Gohman    const TargetInstrInfo *II = TM.getInstrInfo();
331266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(II && "No InstrInfo?");
332266bc8f7774b153401e54ed537db299159840981Scott Michel    return new SPUHazardRecognizer(*II);
333266bc8f7774b153401e54ed537db299159840981Scott Michel  }
334266bc8f7774b153401e54ed537db299159840981Scott Michel
335266bc8f7774b153401e54ed537db299159840981Scott Michel  // Include the pieces autogenerated from the target description.
336266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
337266bc8f7774b153401e54ed537db299159840981Scott Michel};
338266bc8f7774b153401e54ed537db299159840981Scott Michel
339844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
340844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
341db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by
342266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
343266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
344f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect()
345266bc8f7774b153401e54ed537db299159840981Scott Michel{
346266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
347266bc8f7774b153401e54ed537db299159840981Scott Michel
348266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
349ad3460c3c968e33c5b9a07104b9fe5a5c27ff55bDan Gohman  SelectRoot();
350f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman  CurDAG->RemoveDeadNodes();
351266bc8f7774b153401e54ed537db299159840981Scott Michel}
352266bc8f7774b153401e54ed537db299159840981Scott Michel
353266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
354266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand
355266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
356266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
357266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
358266bc8f7774b153401e54ed537db299159840981Scott Michel */
359266bc8f7774b153401e54ed537db299159840981Scott Michelbool
360475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
361475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
362266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
36383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OffsVT = MVT::i16;
364475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
365266bc8f7774b153401e54ed537db299159840981Scott Michel
366266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
367266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
3719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    abort();
3729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
374053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
376053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
377053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as "
378053c1da8d956a794d158ac906b3927c923f97c4dScott Michel         << "A-form address.\n";
379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    abort();
380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
381266bc8f7774b153401e54ed537db299159840981Scott Michel
382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case SPUISD::AFormAddr:
383053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
386475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
390053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
392053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
393053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
395053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
396053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalValue *GV = GSDN->getGlobal();
397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
400053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
407053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
408266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
409266bc8f7774b153401e54ed537db299159840981Scott Michel}
410266bc8f7774b153401e54ed537db299159840981Scott Michel
4117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
412475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
413475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
414203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
415203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
416203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
417203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
4187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
420266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
421266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
422266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
423266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
424266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
425266bc8f7774b153401e54ed537db299159840981Scott Michel
426266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
427266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
428266bc8f7774b153401e54ed537db299159840981Scott Michel
429266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
430475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
431266bc8f7774b153401e54ed537db299159840981Scott Michel*/
432266bc8f7774b153401e54ed537db299159840981Scott Michelbool
433475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
434475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
4357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
4367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                              SPUFrameInfo::minFrameOffset(),
4377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                              SPUFrameInfo::maxFrameOffset());
4387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
441475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
442475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
444266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
44583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT PtrTy = SPUtli.getPointerTy();
446266bc8f7774b153401e54ed537db299159840981Scott Michel
447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
449203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
450203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
451266bc8f7774b153401e54ed537db299159840981Scott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
452203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
453203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
454266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
455203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
456266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
457266bc8f7774b153401e54ed537db299159840981Scott Michel    }
458266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
459266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
460475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
461475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
462266bc8f7774b153401e54ed537db299159840981Scott Michel
463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
4709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
4717810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
472266bc8f7774b153401e54ed537db299159840981Scott Michel
473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
474203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
475203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
477203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4789de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
479203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
481203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4839de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
489053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
4927810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
493053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
496203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
497053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
498203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
499053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
500203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
502203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5039de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5049de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
506053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
509266bc8f7774b153401e54ed537db299159840981Scott Michel      }
510497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
511053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
513475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
514475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
5167f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
5177f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5199de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5219de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5227f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
5237f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
524475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
5257f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5267f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
5277f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
5287810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5297f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
5327810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
5347f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
5387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
5397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
5407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
542053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
54558c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5467f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5487f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
550266bc8f7774b153401e54ed537db299159840981Scott Michel  }
551266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
552266bc8f7774b153401e54ed537db299159840981Scott Michel}
553266bc8f7774b153401e54ed537db299159840981Scott Michel
554266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
555266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
556266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
557266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
558266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
559266bc8f7774b153401e54ed537db299159840981Scott Michel
560266bc8f7774b153401e54ed537db299159840981Scott Michel  If the address \a N can be expressed as a [r + s10imm] address, returns false.
561266bc8f7774b153401e54ed537db299159840981Scott Michel  Otherwise, creates two operands, Base and Index that will become the [r+r]
562266bc8f7774b153401e54ed537db299159840981Scott Michel  address.
563266bc8f7774b153401e54ed537db299159840981Scott Michel*/
564266bc8f7774b153401e54ed537db299159840981Scott Michelbool
565475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
566475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
567266bc8f7774b153401e54ed537db299159840981Scott Michel  if (SelectAFormAddr(Op, N, Base, Index)
568266bc8f7774b153401e54ed537db299159840981Scott Michel      || SelectDFormAddr(Op, N, Base, Index))
569266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
570266bc8f7774b153401e54ed537db299159840981Scott Michel
571053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  // All else fails, punt and use an X-form address:
572053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Base = N.getOperand(0);
573053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Index = N.getOperand(1);
574053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  return true;
57558c5818c01e375a84dc601140470fa68638004cfScott Michel}
57658c5818c01e375a84dc601140470fa68638004cfScott Michel
577266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
578266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
579266bc8f7774b153401e54ed537db299159840981Scott Michel */
580266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
581475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) {
582ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  SDNode *N = Op.getNode();
583266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
58458c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
58558c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
58683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OpVT = Op.getValueType();
587475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
588266bc8f7774b153401e54ed537db299159840981Scott Michel
589e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman  if (N->isMachineOpcode()) {
590266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
591266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
592203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Selects to (add $sp, FI * stackSlotSize)
593203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI =
594203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex());
59583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT PtrVT = SPUtli.getPointerTy();
596203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel
597203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Adjust stack slot to actual offset in frame:
598203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (isS10Constant(FI)) {
599203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, "
600203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
601203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
602203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
603203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
604203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getTargetConstant(FI, PtrVT);
605203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
606203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
607203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, "
608203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
609203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
610203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
611203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
612203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getConstant(FI, PtrVT);
613203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
614203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel
615203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      AddToISelQueue(Ops[1]);
616203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
61758c5818c01e375a84dc601140470fa68638004cfScott Michel  } else if (Opc == ISD::ZERO_EXTEND) {
61858c5818c01e375a84dc601140470fa68638004cfScott Michel    // (zero_extend:i16 (and:i8 <arg>, <const>))
619475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue &Op1 = N->getOperand(0);
62058c5818c01e375a84dc601140470fa68638004cfScott Michel
62158c5818c01e375a84dc601140470fa68638004cfScott Michel    if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) {
62258c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::AND) {
62358c5818c01e375a84dc601140470fa68638004cfScott Michel        // Fold this into a single ANDHI. This is often seen in expansions of i1
62458c5818c01e375a84dc601140470fa68638004cfScott Michel        // to i8, then i8 to i16 in logical/branching operations.
62558c5818c01e375a84dc601140470fa68638004cfScott Michel        DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
62658c5818c01e375a84dc601140470fa68638004cfScott Michel                      "<arg>, <const>))\n");
627a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel        NewOpc = SPU::ANDHIi8i16;
62858c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[0] = Op1.getOperand(0);
62958c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[1] = Op1.getOperand(1);
63058c5818c01e375a84dc601140470fa68638004cfScott Michel        n_ops = 2;
63158c5818c01e375a84dc601140470fa68638004cfScott Michel      }
63258c5818c01e375a84dc601140470fa68638004cfScott Michel    }
633266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
634266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
63583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT = N->getValueType(0);
636475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
637475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
638266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
639a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
640a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel
641a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_ins == 0) {
642a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      cerr << "LDRESULT for unsupported type: "
64383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands           << VT.getMVTString()
644a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel           << "\n";
645a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      abort();
646a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    }
647266bc8f7774b153401e54ed537db299159840981Scott Michel
648266bc8f7774b153401e54ed537db299159840981Scott Michel    AddToISelQueue(Arg);
649a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    Opc = vtm->ldresult_ins;
650a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_imm) {
651475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Zero = CurDAG->getTargetConstant(0, VT);
65286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
65386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      AddToISelQueue(Zero);
65458c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
65586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
65658c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain);
65786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
65886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
659475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    Chain = SDValue(Result, 1);
66086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    AddToISelQueue(Chain);
66186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
662266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
663053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
664475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Op0 = Op.getOperand(0);
6657f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::LDRESULT) {
6667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        /* || Op0.getOpcode() == SPUISD::AFormAddr) */
6677f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      // (IndirectAddr (LDRESULT, imm))
668475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op1 = Op.getOperand(1);
66983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      MVT VT = Op.getValueType();
67058c5818c01e375a84dc601140470fa68638004cfScott Michel
6717f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = ");
672ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      DEBUG(Op.getOperand(0).getNode()->dump(CurDAG));
67358c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\nOp1 = ");
674ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      DEBUG(Op.getOperand(1).getNode()->dump(CurDAG));
67558c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\n");
67658c5818c01e375a84dc601140470fa68638004cfScott Michel
67758c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
67858c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
679f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman        Op1 = CurDAG->getTargetConstant(CN->getZExtValue(), VT);
6807f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32);
6817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op0);
6827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op1);
6837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[0] = Op0;
6847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[1] = Op1;
6857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        n_ops = 2;
68658c5818c01e375a84dc601140470fa68638004cfScott Michel      }
68758c5818c01e375a84dc601140470fa68638004cfScott Michel    }
688266bc8f7774b153401e54ed537db299159840981Scott Michel  }
689266bc8f7774b153401e54ed537db299159840981Scott Michel
69058c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
69158c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
69258c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
69358c5818c01e375a84dc601140470fa68638004cfScott Michel    else
69458c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops);
69558c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
69658c5818c01e375a84dc601140470fa68638004cfScott Michel    return SelectCode(Op);
697266bc8f7774b153401e54ed537db299159840981Scott Michel}
698266bc8f7774b153401e54ed537db299159840981Scott Michel
699266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a
700266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
701266bc8f7774b153401e54ed537db299159840981Scott Michel///
702266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
703266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
704266bc8f7774b153401e54ed537db299159840981Scott Michel}
705