SPUISelDAGToDAG.cpp revision aedc637c966b6eaa3ca33e9220efe5ec34517de7
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
35266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
36266bc8f7774b153401e54ed537db299159840981Scott Michel
37266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
38266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
39266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
40266bc8f7774b153401e54ed537db299159840981Scott Michel  isI64IntS10Immediate(ConstantSDNode *CN)
41266bc8f7774b153401e54ed537db299159840981Scott Michel  {
427810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
43266bc8f7774b153401e54ed537db299159840981Scott Michel  }
44266bc8f7774b153401e54ed537db299159840981Scott Michel
45266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
46266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
47266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
48266bc8f7774b153401e54ed537db299159840981Scott Michel  {
497810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
50266bc8f7774b153401e54ed537db299159840981Scott Michel  }
51266bc8f7774b153401e54ed537db299159840981Scott Michel
52266bc8f7774b153401e54ed537db299159840981Scott Michel#if 0
53266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for sign-extended, 10-bit immediate values
54266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
55266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(SDNode *N)
56266bc8f7774b153401e54ed537db299159840981Scott Michel  {
57266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
58266bc8f7774b153401e54ed537db299159840981Scott Michel            && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
59266bc8f7774b153401e54ed537db299159840981Scott Michel  }
60266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
61266bc8f7774b153401e54ed537db299159840981Scott Michel
62504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
63504c369213efb263136bb048e79af3516511c040Scott Michel  bool
64504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
65504c369213efb263136bb048e79af3516511c040Scott Michel  {
667810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isU10Constant(CN->getSExtValue());
67504c369213efb263136bb048e79af3516511c040Scott Michel  }
68504c369213efb263136bb048e79af3516511c040Scott Michel
69266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
70266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
71266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
72266bc8f7774b153401e54ed537db299159840981Scott Michel  {
737810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman    return isS10Constant(CN->getSExtValue());
74266bc8f7774b153401e54ed537db299159840981Scott Michel  }
75266bc8f7774b153401e54ed537db299159840981Scott Michel
76266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
77266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
78266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(SDNode *N)
79266bc8f7774b153401e54ed537db299159840981Scott Michel  {
80266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
81266bc8f7774b153401e54ed537db299159840981Scott Michel            && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
82266bc8f7774b153401e54ed537db299159840981Scott Michel  }
83266bc8f7774b153401e54ed537db299159840981Scott Michel
84ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
85ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
86ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
87ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
88f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return isU10Constant((short) CN->getZExtValue());
89ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
90ec2a08ff061af36b46160e475362959f21663e76Scott Michel
91ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! SDNode predicate for i16 sign-extended, 10-bit immediate values
92ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
93ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(SDNode *N)
94ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
95ec2a08ff061af36b46160e475362959f21663e76Scott Michel    return (N->getOpcode() == ISD::Constant
96ec2a08ff061af36b46160e475362959f21663e76Scott Michel            && isI16IntU10Immediate(cast<ConstantSDNode>(N)));
97ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
98ec2a08ff061af36b46160e475362959f21663e76Scott Michel
99266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
100266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
101266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
102266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
103266bc8f7774b153401e54ed537db299159840981Scott Michel
104266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
105266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
106266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
107266bc8f7774b153401e54ed537db299159840981Scott Michel   */
108266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
109266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
110266bc8f7774b153401e54ed537db299159840981Scott Michel  {
11183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT vt = CN->getValueType(0);
112f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
1138e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
114266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
115266bc8f7774b153401e54ed537db299159840981Scott Michel    } else if (vt == MVT::i32) {
116f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
117266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
118266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
119266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
120f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
121266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
122266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
123266bc8f7774b153401e54ed537db299159840981Scott Michel    }
124266bc8f7774b153401e54ed537db299159840981Scott Michel
125266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
126266bc8f7774b153401e54ed537db299159840981Scott Michel  }
127266bc8f7774b153401e54ed537db299159840981Scott Michel
128266bc8f7774b153401e54ed537db299159840981Scott Michel  //! SDNode predicate for signed 16-bit values.
129266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
130266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(SDNode *N, short &Imm)
131266bc8f7774b153401e54ed537db299159840981Scott Michel  {
132266bc8f7774b153401e54ed537db299159840981Scott Michel    return (N->getOpcode() == ISD::Constant
133266bc8f7774b153401e54ed537db299159840981Scott Michel            && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
134266bc8f7774b153401e54ed537db299159840981Scott Michel  }
135266bc8f7774b153401e54ed537db299159840981Scott Michel
136266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
137266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
138266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
139266bc8f7774b153401e54ed537db299159840981Scott Michel  {
14083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT vt = FPN->getValueType(0);
141266bc8f7774b153401e54ed537db299159840981Scott Michel    if (vt == MVT::f32) {
142d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
143266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
144266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
145266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
146266bc8f7774b153401e54ed537db299159840981Scott Michel    }
147266bc8f7774b153401e54ed537db299159840981Scott Michel
148266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
149266bc8f7774b153401e54ed537db299159840981Scott Michel  }
150266bc8f7774b153401e54ed537db299159840981Scott Michel
151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  bool
152475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  isHighLow(const SDValue &Op)
153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  {
154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    return (Op.getOpcode() == SPUISD::IndirectAddr
155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel            && ((Op.getOperand(0).getOpcode() == SPUISD::Hi
156053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 && Op.getOperand(1).getOpcode() == SPUISD::Lo)
157053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                || (Op.getOperand(0).getOpcode() == SPUISD::Lo
158053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                    && Op.getOperand(1).getOpcode() == SPUISD::Hi)));
159053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
160053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
161266bc8f7774b153401e54ed537db299159840981Scott Michel  //===------------------------------------------------------------------===//
16283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  //! MVT to "useful stuff" mapping structure:
163266bc8f7774b153401e54ed537db299159840981Scott Michel
164266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
16583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT;
1667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    unsigned ldresult_ins;      /// LDRESULT instruction (0 = undefined)
167a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    bool ldresult_imm;          /// LDRESULT instruction requires immediate?
1687f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    int prefslot_byte;          /// Byte offset of the "preferred" slot
169266bc8f7774b153401e54ed537db299159840981Scott Michel  };
170266bc8f7774b153401e54ed537db299159840981Scott Michel
171266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
172a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i1,    0,            false, 3 },
173a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i8,    SPU::ORBIr8,  true,  3 },
174a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i16,   SPU::ORHIr16, true,  2 },
175a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i32,   SPU::ORIr32,  true,  0 },
176a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::i64,   SPU::ORr64,   false, 0 },
177a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::f32,   SPU::ORf32,   false, 0 },
178a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::f64,   SPU::ORf64,   false, 0 },
17958c5818c01e375a84dc601140470fa68638004cfScott Michel    // vector types... (sigh!)
180a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v16i8, 0,            false, 0 },
181a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v8i16, 0,            false, 0 },
182a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v4i32, 0,            false, 0 },
183a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v2i64, 0,            false, 0 },
184a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v4f32, 0,            false, 0 },
185a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    { MVT::v2f64, 0,            false, 0 }
186266bc8f7774b153401e54ed537db299159840981Scott Michel  };
187266bc8f7774b153401e54ed537db299159840981Scott Michel
188266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
189266bc8f7774b153401e54ed537db299159840981Scott Michel
19083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  const valtype_map_s *getValueTypeMapEntry(MVT VT)
191266bc8f7774b153401e54ed537db299159840981Scott Michel  {
192266bc8f7774b153401e54ed537db299159840981Scott Michel    const valtype_map_s *retval = 0;
193266bc8f7774b153401e54ed537db299159840981Scott Michel    for (size_t i = 0; i < n_valtype_map; ++i) {
194266bc8f7774b153401e54ed537db299159840981Scott Michel      if (valtype_map[i].VT == VT) {
1957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        retval = valtype_map + i;
1967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        break;
197266bc8f7774b153401e54ed537db299159840981Scott Michel      }
198266bc8f7774b153401e54ed537db299159840981Scott Michel    }
199266bc8f7774b153401e54ed537db299159840981Scott Michel
200266bc8f7774b153401e54ed537db299159840981Scott Michel
201266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG
202266bc8f7774b153401e54ed537db299159840981Scott Michel    if (retval == 0) {
203266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
20483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands           << VT.getMVTString()
2057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel           << "\n";
206266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
207266bc8f7774b153401e54ed537db299159840981Scott Michel    }
208266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
209266bc8f7774b153401e54ed537db299159840981Scott Michel
210266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
211266bc8f7774b153401e54ed537db299159840981Scott Michel  }
212266bc8f7774b153401e54ed537db299159840981Scott Michel}
213266bc8f7774b153401e54ed537db299159840981Scott Michel
214844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace {
215844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
216266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===//
217266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
218266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations.
219266bc8f7774b153401e54ed537db299159840981Scott Michel///
220266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel :
221266bc8f7774b153401e54ed537db299159840981Scott Michel  public SelectionDAGISel
222266bc8f7774b153401e54ed537db299159840981Scott Michel{
223266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetMachine &TM;
224266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetLowering &SPUtli;
225266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned GlobalBaseReg;
226266bc8f7774b153401e54ed537db299159840981Scott Michel
227266bc8f7774b153401e54ed537db299159840981Scott Michelpublic:
2281002c0203450620594a85454c6a095ca94b87cb2Dan Gohman  explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
229266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel(*tm.getTargetLowering()),
230266bc8f7774b153401e54ed537db299159840981Scott Michel    TM(tm),
231266bc8f7774b153401e54ed537db299159840981Scott Michel    SPUtli(*tm.getTargetLowering())
232266bc8f7774b153401e54ed537db299159840981Scott Michel  {}
233266bc8f7774b153401e54ed537db299159840981Scott Michel
234266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool runOnFunction(Function &Fn) {
235266bc8f7774b153401e54ed537db299159840981Scott Michel    // Make sure we re-emit a set of the global base reg if necessary
236266bc8f7774b153401e54ed537db299159840981Scott Michel    GlobalBaseReg = 0;
237266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel::runOnFunction(Fn);
238266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
239266bc8f7774b153401e54ed537db299159840981Scott Michel  }
240266bc8f7774b153401e54ed537db299159840981Scott Michel
241266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI32Imm - Return a target constant with the specified value, of type
242266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i32.
243475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getI32Imm(uint32_t Imm) {
244266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i32);
245266bc8f7774b153401e54ed537db299159840981Scott Michel  }
246266bc8f7774b153401e54ed537db299159840981Scott Michel
247266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI64Imm - Return a target constant with the specified value, of type
248266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i64.
249475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getI64Imm(uint64_t Imm) {
250266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i64);
251266bc8f7774b153401e54ed537db299159840981Scott Michel  }
252266bc8f7774b153401e54ed537db299159840981Scott Michel
253266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getSmallIPtrImm - Return a target constant of pointer type.
254475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  inline SDValue getSmallIPtrImm(unsigned Imm) {
255266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
256266bc8f7774b153401e54ed537db299159840981Scott Michel  }
257266bc8f7774b153401e54ed537db299159840981Scott Michel
258266bc8f7774b153401e54ed537db299159840981Scott Michel  /// Select - Convert the specified operand from a target-independent to a
259266bc8f7774b153401e54ed537db299159840981Scott Michel  /// target-specific node if it hasn't already been changed.
260475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDNode *Select(SDValue Op);
261266bc8f7774b153401e54ed537db299159840981Scott Michel
262266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Returns true if the address N is an A-form (local store) address
263475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
264475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
265266bc8f7774b153401e54ed537db299159840981Scott Michel
266266bc8f7774b153401e54ed537db299159840981Scott Michel  //! D-form address predicate
267475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
268475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
2697f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// Alternate D-form address using i7 offset predicate
271475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
272475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                        SDValue &Base);
2737f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
2747f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  /// D-form address selection workhorse
275475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp,
276475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                             SDValue &Base, int minOffset, int maxOffset);
277266bc8f7774b153401e54ed537db299159840981Scott Michel
278266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Address predicate if N can be expressed as an indexed [r+r] operation.
279475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
280475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                       SDValue &Index);
281266bc8f7774b153401e54ed537db299159840981Scott Michel
282266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
283266bc8f7774b153401e54ed537db299159840981Scott Michel  /// inline asm expressions.
284475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
2857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                            char ConstraintCode,
286f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman                                            std::vector<SDValue> &OutOps) {
287475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Op0, Op1;
288266bc8f7774b153401e54ed537db299159840981Scott Michel    switch (ConstraintCode) {
289266bc8f7774b153401e54ed537db299159840981Scott Michel    default: return true;
290266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'm':   // memory
291266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
2927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1))
2937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        SelectXFormAddr(Op, Op, Op0, Op1);
294266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
295266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'o':   // offsetable
296266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
2977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel          && !SelectAFormAddr(Op, Op, Op0, Op1)) {
2987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op0 = Op;
2997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Op1 = getSmallIPtrImm(0);
300266bc8f7774b153401e54ed537db299159840981Scott Michel      }
301266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
302266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'v':   // not offsetable
303266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
304266bc8f7774b153401e54ed537db299159840981Scott Michel      assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
305266bc8f7774b153401e54ed537db299159840981Scott Michel#else
306266bc8f7774b153401e54ed537db299159840981Scott Michel      SelectAddrIdxOnly(Op, Op, Op0, Op1);
307266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
308266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
309266bc8f7774b153401e54ed537db299159840981Scott Michel    }
310266bc8f7774b153401e54ed537db299159840981Scott Michel
311266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op0);
312266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op1);
313266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
314266bc8f7774b153401e54ed537db299159840981Scott Michel  }
315266bc8f7774b153401e54ed537db299159840981Scott Michel
316db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng  /// InstructionSelect - This callback is invoked by
317266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
318f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman  virtual void InstructionSelect();
319266bc8f7774b153401e54ed537db299159840981Scott Michel
320266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual const char *getPassName() const {
321266bc8f7774b153401e54ed537db299159840981Scott Michel    return "Cell SPU DAG->DAG Pattern Instruction Selection";
322266bc8f7774b153401e54ed537db299159840981Scott Michel  }
323266bc8f7774b153401e54ed537db299159840981Scott Michel
324266bc8f7774b153401e54ed537db299159840981Scott Michel  /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
325266bc8f7774b153401e54ed537db299159840981Scott Michel  /// this target when scheduling the DAG.
326266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual HazardRecognizer *CreateTargetHazardRecognizer() {
3276448d91ad1e5497fe2f7015d61b57cb5f3040879Dan Gohman    const TargetInstrInfo *II = TM.getInstrInfo();
328266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(II && "No InstrInfo?");
329266bc8f7774b153401e54ed537db299159840981Scott Michel    return new SPUHazardRecognizer(*II);
330266bc8f7774b153401e54ed537db299159840981Scott Michel  }
331266bc8f7774b153401e54ed537db299159840981Scott Michel
332266bc8f7774b153401e54ed537db299159840981Scott Michel  // Include the pieces autogenerated from the target description.
333266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
334266bc8f7774b153401e54ed537db299159840981Scott Michel};
335266bc8f7774b153401e54ed537db299159840981Scott Michel
336844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
337844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
338db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by
339266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
340266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
341f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect()
342266bc8f7774b153401e54ed537db299159840981Scott Michel{
343266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
344266bc8f7774b153401e54ed537db299159840981Scott Michel
345266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
3468ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene  SelectRoot(*CurDAG);
347f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman  CurDAG->RemoveDeadNodes();
348266bc8f7774b153401e54ed537db299159840981Scott Michel}
349266bc8f7774b153401e54ed537db299159840981Scott Michel
350266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
351266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand
352266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
353266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
354266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
355266bc8f7774b153401e54ed537db299159840981Scott Michel */
356266bc8f7774b153401e54ed537db299159840981Scott Michelbool
357475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
358475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
359266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
36083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OffsVT = MVT::i16;
361475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
362266bc8f7774b153401e54ed537db299159840981Scott Michel
363266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
364266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3679de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
3689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    abort();
3699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
371053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
373053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
374053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as "
375053c1da8d956a794d158ac906b3927c923f97c4dScott Michel         << "A-form address.\n";
376053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    abort();
377053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
378266bc8f7774b153401e54ed537db299159840981Scott Michel
379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case SPUISD::AFormAddr:
380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
381053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
383475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
386053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
390053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
392053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
393053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalValue *GV = GSDN->getGlobal();
394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
395053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
396053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
400053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
405266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
406266bc8f7774b153401e54ed537db299159840981Scott Michel}
407266bc8f7774b153401e54ed537db299159840981Scott Michel
4087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
409475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
410475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
411203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
412203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
413203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
414203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
4157f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4167f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
417266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
418266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
419266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
420266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
421266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
422266bc8f7774b153401e54ed537db299159840981Scott Michel
423266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
424266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
425266bc8f7774b153401e54ed537db299159840981Scott Michel
426266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
427475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
428266bc8f7774b153401e54ed537db299159840981Scott Michel*/
429266bc8f7774b153401e54ed537db299159840981Scott Michelbool
430475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
431475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
4327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
4339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::minFrameOffset(),
4349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::maxFrameOffset());
4357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
438475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
439475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
441266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
44283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT PtrTy = SPUtli.getPointerTy();
443266bc8f7774b153401e54ed537db299159840981Scott Michel
444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
446203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
447203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
448266bc8f7774b153401e54ed537db299159840981Scott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
449203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
450203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
451266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
452203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
453266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
454266bc8f7774b153401e54ed537db299159840981Scott Michel    }
455266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
456266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
457475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
458475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
459266bc8f7774b153401e54ed537db299159840981Scott Michel
460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
4679de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
4687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
469266bc8f7774b153401e54ed537db299159840981Scott Michel
470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
471203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
472203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
474203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
476203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
478203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
484053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
485053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
4897810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
492203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
493203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
496053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
497203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
498053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
499203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
503053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
504053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
505053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
506266bc8f7774b153401e54ed537db299159840981Scott Michel      }
507497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
510475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
511475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
5137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
5147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
517053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
5207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
521475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
5227f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5237f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
5247f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
5257810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5267f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
5277f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
5287f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
5297810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
5347f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
5357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
54258c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5447f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5457f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5467f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
5479c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) {
5489c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    unsigned OpOpc = Op.getOpcode();
5499c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
5519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
5529c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      SDValue Addr, Offs;
5539c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5549c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Get the register from CopyFromReg
5559c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Opc == ISD::CopyFromReg)
5569c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Addr = N.getOperand(1);
5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      else
5589c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Addr = N;                       // Register
5599c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
560aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2));
5619c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5629c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
5639c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
5649c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
5659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5669c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
5679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Index = Addr;
5689c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
5699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
570aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
571aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
572aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
573aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel	Index = N.getOperand(1);
574aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
575aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel	Index = N;
576aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
577aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
578aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
579aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
5809c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
581266bc8f7774b153401e54ed537db299159840981Scott Michel  }
5829c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
583266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
584266bc8f7774b153401e54ed537db299159840981Scott Michel}
585266bc8f7774b153401e54ed537db299159840981Scott Michel
586266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
587266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
588266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
589266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
590266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
591266bc8f7774b153401e54ed537db299159840981Scott Michel
5929c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
5939c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
5949c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
595266bc8f7774b153401e54ed537db299159840981Scott Michel*/
596266bc8f7774b153401e54ed537db299159840981Scott Michelbool
597475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
598475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
5999c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
6009c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
60118fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
60218fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
6031a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
6041a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
60550843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
6069c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
607266bc8f7774b153401e54ed537db299159840981Scott Michel
6089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
60958c5818c01e375a84dc601140470fa68638004cfScott Michel}
61058c5818c01e375a84dc601140470fa68638004cfScott Michel
611266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
612266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
613266bc8f7774b153401e54ed537db299159840981Scott Michel */
614266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
615475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) {
616ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  SDNode *N = Op.getNode();
617266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
61858c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
61958c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
62083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT OpVT = Op.getValueType();
621475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
622266bc8f7774b153401e54ed537db299159840981Scott Michel
623e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman  if (N->isMachineOpcode()) {
624266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
625266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
626203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Selects to (add $sp, FI * stackSlotSize)
627203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI =
628203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex());
62983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT PtrVT = SPUtli.getPointerTy();
630203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel
631203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    // Adjust stack slot to actual offset in frame:
632203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (isS10Constant(FI)) {
633203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, "
634203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
635203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
636203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
637203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
638203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getTargetConstant(FI, PtrVT);
639203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
640203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
641203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, "
642203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << FI
643203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                 << "\n");
644203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
645203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
646203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Ops[1] = CurDAG->getConstant(FI, PtrVT);
647203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
648203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
64958c5818c01e375a84dc601140470fa68638004cfScott Michel  } else if (Opc == ISD::ZERO_EXTEND) {
65058c5818c01e375a84dc601140470fa68638004cfScott Michel    // (zero_extend:i16 (and:i8 <arg>, <const>))
651475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue &Op1 = N->getOperand(0);
65258c5818c01e375a84dc601140470fa68638004cfScott Michel
65358c5818c01e375a84dc601140470fa68638004cfScott Michel    if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) {
65458c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::AND) {
65558c5818c01e375a84dc601140470fa68638004cfScott Michel        // Fold this into a single ANDHI. This is often seen in expansions of i1
65658c5818c01e375a84dc601140470fa68638004cfScott Michel        // to i8, then i8 to i16 in logical/branching operations.
65758c5818c01e375a84dc601140470fa68638004cfScott Michel        DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
65858c5818c01e375a84dc601140470fa68638004cfScott Michel                      "<arg>, <const>))\n");
659a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel        NewOpc = SPU::ANDHIi8i16;
66058c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[0] = Op1.getOperand(0);
66158c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[1] = Op1.getOperand(1);
66258c5818c01e375a84dc601140470fa68638004cfScott Michel        n_ops = 2;
66358c5818c01e375a84dc601140470fa68638004cfScott Michel      }
66458c5818c01e375a84dc601140470fa68638004cfScott Michel    }
665266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
666266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
66783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT = N->getValueType(0);
668475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
669475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
670266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
671a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
672a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel
673a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_ins == 0) {
674a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      cerr << "LDRESULT for unsupported type: "
67583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands           << VT.getMVTString()
676a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel           << "\n";
677a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel      abort();
678a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    }
679266bc8f7774b153401e54ed537db299159840981Scott Michel
680a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    Opc = vtm->ldresult_ins;
681a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel    if (vtm->ldresult_imm) {
682475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Zero = CurDAG->getTargetConstant(0, VT);
68386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
68458c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
68586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
68630ee7df71c4b08da5d7e3f772f29f7c9ca57d8faScott Michel      Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Arg, Chain);
68786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
68886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
689475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    Chain = SDValue(Result, 1);
69086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
691266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
692053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
693475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Op0 = Op.getOperand(0);
6947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::LDRESULT) {
6957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        /* || Op0.getOpcode() == SPUISD::AFormAddr) */
6967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      // (IndirectAddr (LDRESULT, imm))
697475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op1 = Op.getOperand(1);
69883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      MVT VT = Op.getValueType();
69958c5818c01e375a84dc601140470fa68638004cfScott Michel
7007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = ");
701ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      DEBUG(Op.getOperand(0).getNode()->dump(CurDAG));
70258c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\nOp1 = ");
703ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      DEBUG(Op.getOperand(1).getNode()->dump(CurDAG));
70458c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\n");
70558c5818c01e375a84dc601140470fa68638004cfScott Michel
70658c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
70758c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
708f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman        Op1 = CurDAG->getTargetConstant(CN->getZExtValue(), VT);
7097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32);
7107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[0] = Op0;
7117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Ops[1] = Op1;
7127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        n_ops = 2;
71358c5818c01e375a84dc601140470fa68638004cfScott Michel      }
71458c5818c01e375a84dc601140470fa68638004cfScott Michel    }
715266bc8f7774b153401e54ed537db299159840981Scott Michel  }
716266bc8f7774b153401e54ed537db299159840981Scott Michel
71758c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
71858c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
71958c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
72058c5818c01e375a84dc601140470fa68638004cfScott Michel    else
72158c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops);
72258c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
72358c5818c01e375a84dc601140470fa68638004cfScott Michel    return SelectCode(Op);
724266bc8f7774b153401e54ed537db299159840981Scott Michel}
725266bc8f7774b153401e54ed537db299159840981Scott Michel
726266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a
727266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
728266bc8f7774b153401e54ed537db299159840981Scott Michel///
729266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
730266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
731266bc8f7774b153401e54ed537db299159840981Scott Michel}
732