SPUISelDAGToDAG.cpp revision e8be6c63915e0389f1eef6b53c64300d13b2ce99
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  {
4478c47fa50b903d5dcb4e07a5c048a35cbc2add9eScott Michel    return isS10Constant(CN->getSignExtended());
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  {
5178c47fa50b903d5dcb4e07a5c048a35cbc2add9eScott Michel    return isS10Constant(CN->getSignExtended());
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  {
6879698f60c4693ba305ba994b8349a3f6a6d6031eScott Michel    return isU10Constant(CN->getSignExtended());
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  {
7579698f60c4693ba305ba994b8349a3f6a6d6031eScott Michel    return isS10Constant(CN->getSignExtended());
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  {
90ec2a08ff061af36b46160e475362959f21663e76Scott Michel    return isU10Constant((short) CN->getValue());
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);
114266bc8f7774b153401e54ed537db299159840981Scott Michel    Imm = (short) CN->getValue();
1158e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
116266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
117266bc8f7774b153401e54ed537db299159840981Scott Michel    } else if (vt == MVT::i32) {
118266bc8f7774b153401e54ed537db299159840981Scott Michel      int32_t i_val = (int32_t) CN->getValue();
119266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
120266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
121266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
122266bc8f7774b153401e54ed537db299159840981Scott Michel      int64_t i_val = (int64_t) CN->getValue();
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
154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  isHighLow(const SDOperand &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.
245266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
251266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
256266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
262266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *Select(SDOperand Op);
263266bc8f7774b153401e54ed537db299159840981Scott Michel
264266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Returns true if the address N is an A-form (local store) address
265266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
2667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                       SDOperand &Index);
267266bc8f7774b153401e54ed537db299159840981Scott Michel
268266bc8f7774b153401e54ed537db299159840981Scott Michel  //! D-form address predicate
269266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
2707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                       SDOperand &Index);
2717f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2727f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// Alternate D-form address using i7 offset predicate
2737f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
2747f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                        SDOperand &Base);
2757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// D-form address selection workhorse
2777f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  bool DFormAddressPredicate(SDOperand Op, SDOperand N, SDOperand &Disp,
2787f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                             SDOperand &Base, int minOffset, int maxOffset);
279266bc8f7774b153401e54ed537db299159840981Scott Michel
280266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Address predicate if N can be expressed as an indexed [r+r] operation.
281266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
2827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                       SDOperand &Index);
283266bc8f7774b153401e54ed537db299159840981Scott Michel
284266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
285266bc8f7774b153401e54ed537db299159840981Scott Michel  /// inline asm expressions.
286266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
2877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                            char ConstraintCode,
2887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                            std::vector<SDOperand> &OutOps,
2897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                            SelectionDAG &DAG) {
290266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op0, Op1;
291266bc8f7774b153401e54ed537db299159840981Scott Michel    switch (ConstraintCode) {
292266bc8f7774b153401e54ed537db299159840981Scott Michel    default: return true;
293266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'm':   // memory
294266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
2957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1))
2967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        SelectXFormAddr(Op, Op, Op0, Op1);
297266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
298266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'o':   // offsetable
299266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
3007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1)) {
3017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op0 = Op;
3027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op0);     // r+0.
3037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op1 = getSmallIPtrImm(0);
304266bc8f7774b153401e54ed537db299159840981Scott Michel      }
305266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
306266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'v':   // not offsetable
307266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
308266bc8f7774b153401e54ed537db299159840981Scott Michel      assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
309266bc8f7774b153401e54ed537db299159840981Scott Michel#else
310266bc8f7774b153401e54ed537db299159840981Scott Michel      SelectAddrIdxOnly(Op, Op, Op0, Op1);
311266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
312266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
313266bc8f7774b153401e54ed537db299159840981Scott Michel    }
314266bc8f7774b153401e54ed537db299159840981Scott Michel
315266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op0);
316266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op1);
317266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
318266bc8f7774b153401e54ed537db299159840981Scott Michel  }
319266bc8f7774b153401e54ed537db299159840981Scott Michel
320db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng  /// InstructionSelect - This callback is invoked by
321266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
322db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng  virtual void InstructionSelect(SelectionDAG &DAG);
323266bc8f7774b153401e54ed537db299159840981Scott Michel
324266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual const char *getPassName() const {
325266bc8f7774b153401e54ed537db299159840981Scott Michel    return "Cell SPU DAG->DAG Pattern Instruction Selection";
326266bc8f7774b153401e54ed537db299159840981Scott Michel  }
327266bc8f7774b153401e54ed537db299159840981Scott Michel
328266bc8f7774b153401e54ed537db299159840981Scott Michel  /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
329266bc8f7774b153401e54ed537db299159840981Scott Michel  /// this target when scheduling the DAG.
330266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual HazardRecognizer *CreateTargetHazardRecognizer() {
331266bc8f7774b153401e54ed537db299159840981Scott Michel    const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo();
332266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(II && "No InstrInfo?");
333266bc8f7774b153401e54ed537db299159840981Scott Michel    return new SPUHazardRecognizer(*II);
334266bc8f7774b153401e54ed537db299159840981Scott Michel  }
335266bc8f7774b153401e54ed537db299159840981Scott Michel
336266bc8f7774b153401e54ed537db299159840981Scott Michel  // Include the pieces autogenerated from the target description.
337266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
338266bc8f7774b153401e54ed537db299159840981Scott Michel};
339266bc8f7774b153401e54ed537db299159840981Scott Michel
340844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
341844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
342db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by
343266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
344266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
345db8d56b825efeb576d67b9dbe39d736d93306222Evan ChengSPUDAGToDAGISel::InstructionSelect(SelectionDAG &DAG)
346266bc8f7774b153401e54ed537db299159840981Scott Michel{
347266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
348266bc8f7774b153401e54ed537db299159840981Scott Michel
349266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
350266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.setRoot(SelectRoot(DAG.getRoot()));
351266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.RemoveDeadNodes();
352266bc8f7774b153401e54ed537db299159840981Scott Michel}
353266bc8f7774b153401e54ed537db299159840981Scott Michel
354266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
355266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand
356266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
357266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
358266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
359266bc8f7774b153401e54ed537db299159840981Scott Michel */
360266bc8f7774b153401e54ed537db299159840981Scott Michelbool
361266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
3627f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                    SDOperand &Index) {
363266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
36483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OffsVT = MVT::i16;
365053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  SDOperand Zero = CurDAG->getTargetConstant(0, OffsVT);
366266bc8f7774b153401e54ed537db299159840981Scott Michel
367266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
368266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
3729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    abort();
3739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3749de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
375053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
377053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
378053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as "
379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel         << "A-form address.\n";
380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    abort();
381053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
382266bc8f7774b153401e54ed537db299159840981Scott Michel
383053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case SPUISD::AFormAddr:
384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
386053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      SDOperand Op0 = N.getOperand(0);
388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
390053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
392053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
393053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
395053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
396053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalValue *GV = GSDN->getGlobal();
398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
400053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
407053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
408053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
409266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
410266bc8f7774b153401e54ed537db299159840981Scott Michel}
411266bc8f7774b153401e54ed537db299159840981Scott Michel
4127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
4137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott MichelSPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
4147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                  SDOperand &Base) {
415203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
416203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
417203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
418203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
4197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
421266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
422266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
423266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
424266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
425266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
426266bc8f7774b153401e54ed537db299159840981Scott Michel
427266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
428266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
429266bc8f7774b153401e54ed537db299159840981Scott Michel
430266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
431266bc8f7774b153401e54ed537db299159840981Scott Michel  to non-empty SDOperand instances.
432266bc8f7774b153401e54ed537db299159840981Scott Michel*/
433266bc8f7774b153401e54ed537db299159840981Scott Michelbool
434266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
4357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                 SDOperand &Index) {
4367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
4377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                              SPUFrameInfo::minFrameOffset(),
4387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                              SPUFrameInfo::maxFrameOffset());
4397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4417f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
4427f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott MichelSPUDAGToDAGISel::DFormAddressPredicate(SDOperand Op, SDOperand N, SDOperand &Base,
4437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      SDOperand &Index, int minOffset,
4447f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
445266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
44683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT PtrTy = SPUtli.getPointerTy();
447266bc8f7774b153401e54ed537db299159840981Scott Michel
448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
450203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
451203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
452266bc8f7774b153401e54ed537db299159840981Scott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
453203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
454203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
455266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
456203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
457266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
458266bc8f7774b153401e54ed537db299159840981Scott Michel    }
459266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
460266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op0 = N.getOperand(0);
462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op1 = N.getOperand(1);
463266bc8f7774b153401e54ed537db299159840981Scott Michel
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
4719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
473266bc8f7774b153401e54ed537db299159840981Scott Michel
474053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
475203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
476203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
478203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
480203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
4819de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
482203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4839de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4869de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
489053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
492053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
493053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
495053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
496203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
497203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
498053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
499203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
500053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
501203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
502053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
503203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5049de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5059de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
510266bc8f7774b153401e54ed537db299159840981Scott Michel      }
511497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
513053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
514053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op0 = N.getOperand(0);
515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op1 = N.getOperand(1);
516053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
5177f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
5187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5209de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
521053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5229de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5237f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
5247f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
5257f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      SDOperand idxOp;
5267f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5277f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
5287f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
5297f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        offset = int32_t(CN->getSignExtended());
5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
5327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
5337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        offset = int32_t(CN->getSignExtended());
5347f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
5357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
5387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
5397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
5407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
5417f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
545053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
54658c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5487f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5507f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
551266bc8f7774b153401e54ed537db299159840981Scott Michel  }
552266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
553266bc8f7774b153401e54ed537db299159840981Scott Michel}
554266bc8f7774b153401e54ed537db299159840981Scott Michel
555266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
556266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
557266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
558266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
559266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
560266bc8f7774b153401e54ed537db299159840981Scott Michel
561266bc8f7774b153401e54ed537db299159840981Scott Michel  If the address \a N can be expressed as a [r + s10imm] address, returns false.
562266bc8f7774b153401e54ed537db299159840981Scott Michel  Otherwise, creates two operands, Base and Index that will become the [r+r]
563266bc8f7774b153401e54ed537db299159840981Scott Michel  address.
564266bc8f7774b153401e54ed537db299159840981Scott Michel*/
565266bc8f7774b153401e54ed537db299159840981Scott Michelbool
566266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
5677f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                 SDOperand &Index) {
568266bc8f7774b153401e54ed537db299159840981Scott Michel  if (SelectAFormAddr(Op, N, Base, Index)
569266bc8f7774b153401e54ed537db299159840981Scott Michel      || SelectDFormAddr(Op, N, Base, Index))
570266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
571266bc8f7774b153401e54ed537db299159840981Scott Michel
572053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  // All else fails, punt and use an X-form address:
573053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Base = N.getOperand(0);
574053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Index = N.getOperand(1);
575053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  return true;
57658c5818c01e375a84dc601140470fa68638004cfScott Michel}
57758c5818c01e375a84dc601140470fa68638004cfScott Michel
578266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
579266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
580266bc8f7774b153401e54ed537db299159840981Scott Michel */
581266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
582266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::Select(SDOperand Op) {
583266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *N = Op.Val;
584266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
58558c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
58658c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
58783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OpVT = Op.getValueType();
58858c5818c01e375a84dc601140470fa68638004cfScott Michel  SDOperand Ops[8];
589266bc8f7774b153401e54ed537db299159840981Scott Michel
590e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman  if (N->isMachineOpcode()) {
591266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
592266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
593203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Selects to (add $sp, FI * stackSlotSize)
594203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI =
595203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex());
59683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT PtrVT = SPUtli.getPointerTy();
597203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel
598203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Adjust stack slot to actual offset in frame:
599203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (isS10Constant(FI)) {
600203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, "
601203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
602203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
603203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
604203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
605203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getTargetConstant(FI, PtrVT);
606203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
607203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
608203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, "
609203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
610203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
611203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
612203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
613203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getConstant(FI, PtrVT);
614203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
615203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel
616203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      AddToISelQueue(Ops[1]);
617203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
61858c5818c01e375a84dc601140470fa68638004cfScott Michel  } else if (Opc == ISD::ZERO_EXTEND) {
61958c5818c01e375a84dc601140470fa68638004cfScott Michel    // (zero_extend:i16 (and:i8 <arg>, <const>))
62058c5818c01e375a84dc601140470fa68638004cfScott Michel    const SDOperand &Op1 = N->getOperand(0);
62158c5818c01e375a84dc601140470fa68638004cfScott Michel
62258c5818c01e375a84dc601140470fa68638004cfScott Michel    if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) {
62358c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::AND) {
62458c5818c01e375a84dc601140470fa68638004cfScott Michel        // Fold this into a single ANDHI. This is often seen in expansions of i1
62558c5818c01e375a84dc601140470fa68638004cfScott Michel        // to i8, then i8 to i16 in logical/branching operations.
62658c5818c01e375a84dc601140470fa68638004cfScott Michel        DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
62758c5818c01e375a84dc601140470fa68638004cfScott Michel                      "<arg>, <const>))\n");
628a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel        NewOpc = SPU::ANDHIi8i16;
62958c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[0] = Op1.getOperand(0);
63058c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[1] = Op1.getOperand(1);
63158c5818c01e375a84dc601140470fa68638004cfScott Michel        n_ops = 2;
63258c5818c01e375a84dc601140470fa68638004cfScott Michel      }
63358c5818c01e375a84dc601140470fa68638004cfScott Michel    }
634266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
635266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
63683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT = N->getValueType(0);
637266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Arg = N->getOperand(0);
638266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Chain = N->getOperand(1);
639266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
640a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
641a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel
642a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_ins == 0) {
643a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      cerr << "LDRESULT for unsupported type: "
64483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands           << VT.getMVTString()
645a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel           << "\n";
646a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      abort();
647a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    }
648266bc8f7774b153401e54ed537db299159840981Scott Michel
649266bc8f7774b153401e54ed537db299159840981Scott Michel    AddToISelQueue(Arg);
650a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    Opc = vtm->ldresult_ins;
651a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_imm) {
65286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      SDOperand Zero = CurDAG->getTargetConstant(0, VT);
65386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
65486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      AddToISelQueue(Zero);
65558c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
65686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
65758c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain);
65886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
65986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
660266bc8f7774b153401e54ed537db299159840981Scott Michel    Chain = SDOperand(Result, 1);
66186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    AddToISelQueue(Chain);
66286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
663266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
664053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
66558c5818c01e375a84dc601140470fa68638004cfScott Michel    SDOperand Op0 = Op.getOperand(0);
6667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::LDRESULT) {
6677f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        /* || Op0.getOpcode() == SPUISD::AFormAddr) */
6687f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      // (IndirectAddr (LDRESULT, imm))
66958c5818c01e375a84dc601140470fa68638004cfScott Michel      SDOperand Op1 = Op.getOperand(1);
67083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      MVT VT = Op.getValueType();
67158c5818c01e375a84dc601140470fa68638004cfScott Michel
6727f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = ");
67358c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(Op.getOperand(0).Val->dump(CurDAG));
67458c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\nOp1 = ");
67558c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(Op.getOperand(1).Val->dump(CurDAG));
67658c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\n");
67758c5818c01e375a84dc601140470fa68638004cfScott Michel
67858c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
67958c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
68058c5818c01e375a84dc601140470fa68638004cfScott Michel        Op1 = CurDAG->getTargetConstant(CN->getValue(), VT);
6817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32);
6827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op0);
6837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        AddToISelQueue(Op1);
6847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[0] = Op0;
6857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[1] = Op1;
6867f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        n_ops = 2;
68758c5818c01e375a84dc601140470fa68638004cfScott Michel      }
68858c5818c01e375a84dc601140470fa68638004cfScott Michel    }
689266bc8f7774b153401e54ed537db299159840981Scott Michel  }
690266bc8f7774b153401e54ed537db299159840981Scott Michel
69158c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
69258c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
69358c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
69458c5818c01e375a84dc601140470fa68638004cfScott Michel    else
69558c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops);
69658c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
69758c5818c01e375a84dc601140470fa68638004cfScott Michel    return SelectCode(Op);
698266bc8f7774b153401e54ed537db299159840981Scott Michel}
699266bc8f7774b153401e54ed537db299159840981Scott Michel
700266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a
701266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
702266bc8f7774b153401e54ed537db299159840981Scott Michel///
703266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
704266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
705266bc8f7774b153401e54ed537db299159840981Scott Michel}
706