SPUISelDAGToDAG.cpp revision 053c1da8d956a794d158ac906b3927c923f97c4d
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"
20266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h"
21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h"
22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h"
23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h"
24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h"
25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
33266bc8f7774b153401e54ed537db299159840981Scott Michel#include <iostream>
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  {
44266bc8f7774b153401e54ed537db299159840981Scott Michel    return isS10Constant(CN->getValue());
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  {
51266bc8f7774b153401e54ed537db299159840981Scott Michel    return isS10Constant((int) CN->getValue());
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  {
68504c369213efb263136bb048e79af3516511c040Scott Michel    return isU10Constant((int) CN->getValue());
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  {
75266bc8f7774b153401e54ed537db299159840981Scott Michel    return isS10Constant((short) CN->getValue());
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  {
113266bc8f7774b153401e54ed537db299159840981Scott Michel    MVT::ValueType vt = CN->getValueType(0);
114266bc8f7774b153401e54ed537db299159840981Scott Michel    Imm = (short) CN->getValue();
115266bc8f7774b153401e54ed537db299159840981Scott Michel    if (vt >= MVT::i1 && vt <= 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  {
142266bc8f7774b153401e54ed537db299159840981Scott Michel    MVT::ValueType 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  //===------------------------------------------------------------------===//
16486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel  //! MVT::ValueType to "useful stuff" mapping structure:
165266bc8f7774b153401e54ed537db299159840981Scott Michel
166266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
167266bc8f7774b153401e54ed537db299159840981Scott Michel    MVT::ValueType VT;
168266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned ldresult_ins;	/// LDRESULT instruction (0 = undefined)
169266bc8f7774b153401e54ed537db299159840981Scott Michel    int prefslot_byte;		/// Byte offset of the "preferred" slot
170053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    unsigned insmask_ins;       /// Insert mask instruction for a-form
171266bc8f7774b153401e54ed537db299159840981Scott Michel  };
172266bc8f7774b153401e54ed537db299159840981Scott Michel
173266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
174053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::i1,    0,            3, 0 },
175053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::i8,    SPU::ORBIr8,  3, 0 },
176053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::i16,   SPU::ORHIr16, 2, 0 },
177053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::i32,   SPU::ORIr32,  0, 0 },
178053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::i64,   SPU::ORIr64,  0, 0 },
179053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::f32,   0,            0, 0 },
180053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::f64,   0,            0, 0 },
18158c5818c01e375a84dc601140470fa68638004cfScott Michel    // vector types... (sigh!)
182053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v16i8, 0,            0, SPU::CBD },
183053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v8i16, 0,            0, SPU::CHD },
184053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v4i32, 0,            0, SPU::CWD },
185053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v2i64, 0,            0, 0 },
186053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v4f32, 0,            0, SPU::CWD },
187053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    { MVT::v2f64, 0,            0, 0 }
188266bc8f7774b153401e54ed537db299159840981Scott Michel  };
189266bc8f7774b153401e54ed537db299159840981Scott Michel
190266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
191266bc8f7774b153401e54ed537db299159840981Scott Michel
192266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s *getValueTypeMapEntry(MVT::ValueType 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) {
197266bc8f7774b153401e54ed537db299159840981Scott Michel	retval = valtype_map + i;
198266bc8f7774b153401e54ed537db299159840981Scott 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 "
206266bc8f7774b153401e54ed537db299159840981Scott Michel	   << MVT::getValueTypeString(VT)
207266bc8f7774b153401e54ed537db299159840981Scott Michel	   << "\n";
208266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
209266bc8f7774b153401e54ed537db299159840981Scott Michel    }
210266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
211266bc8f7774b153401e54ed537db299159840981Scott Michel
212266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
213266bc8f7774b153401e54ed537db299159840981Scott Michel  }
214266bc8f7774b153401e54ed537db299159840981Scott Michel}
215266bc8f7774b153401e54ed537db299159840981Scott Michel
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:
228266bc8f7774b153401e54ed537db299159840981Scott Michel  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.
243266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
249266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
254266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand 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.
260266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *Select(SDOperand Op);
261266bc8f7774b153401e54ed537db299159840981Scott Michel
262266bc8f7774b153401e54ed537db299159840981Scott Michel  /// Return true if the address N is a RI7 format address [r+imm]
263266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
264266bc8f7774b153401e54ed537db299159840981Scott Michel			SDOperand &Base);
265266bc8f7774b153401e54ed537db299159840981Scott Michel
266266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Returns true if the address N is an A-form (local store) address
267266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
268266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
269266bc8f7774b153401e54ed537db299159840981Scott Michel
270266bc8f7774b153401e54ed537db299159840981Scott Michel  //! D-form address predicate
271266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
272266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
273266bc8f7774b153401e54ed537db299159840981Scott Michel
274266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Address predicate if N can be expressed as an indexed [r+r] operation.
275266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
276266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
277266bc8f7774b153401e54ed537db299159840981Scott Michel
278266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
279266bc8f7774b153401e54ed537db299159840981Scott Michel  /// inline asm expressions.
280266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
281266bc8f7774b153401e54ed537db299159840981Scott Michel					    char ConstraintCode,
282266bc8f7774b153401e54ed537db299159840981Scott Michel					    std::vector<SDOperand> &OutOps,
283266bc8f7774b153401e54ed537db299159840981Scott Michel					    SelectionDAG &DAG) {
284266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op0, Op1;
285266bc8f7774b153401e54ed537db299159840981Scott Michel    switch (ConstraintCode) {
286266bc8f7774b153401e54ed537db299159840981Scott Michel    default: return true;
287266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'm':   // memory
288266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
289266bc8f7774b153401e54ed537db299159840981Scott Michel	  && !SelectAFormAddr(Op, Op, Op0, Op1))
290266bc8f7774b153401e54ed537db299159840981Scott Michel	SelectXFormAddr(Op, Op, Op0, Op1);
291266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
292266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'o':   // offsetable
293266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
294266bc8f7774b153401e54ed537db299159840981Scott Michel	  && !SelectAFormAddr(Op, Op, Op0, Op1)) {
295266bc8f7774b153401e54ed537db299159840981Scott Michel	Op0 = Op;
296266bc8f7774b153401e54ed537db299159840981Scott Michel	AddToISelQueue(Op0);     // r+0.
297266bc8f7774b153401e54ed537db299159840981Scott Michel	Op1 = getSmallIPtrImm(0);
298266bc8f7774b153401e54ed537db299159840981Scott Michel      }
299266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
300266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'v':   // not offsetable
301266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
302266bc8f7774b153401e54ed537db299159840981Scott Michel      assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
303266bc8f7774b153401e54ed537db299159840981Scott Michel#else
304266bc8f7774b153401e54ed537db299159840981Scott Michel      SelectAddrIdxOnly(Op, Op, Op0, Op1);
305266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
306266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
307266bc8f7774b153401e54ed537db299159840981Scott Michel    }
308266bc8f7774b153401e54ed537db299159840981Scott Michel
309266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op0);
310266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op1);
311266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
312266bc8f7774b153401e54ed537db299159840981Scott Michel  }
313266bc8f7774b153401e54ed537db299159840981Scott Michel
314266bc8f7774b153401e54ed537db299159840981Scott Michel  /// InstructionSelectBasicBlock - This callback is invoked by
315266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
316266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
317266bc8f7774b153401e54ed537db299159840981Scott Michel
318266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual const char *getPassName() const {
319266bc8f7774b153401e54ed537db299159840981Scott Michel    return "Cell SPU DAG->DAG Pattern Instruction Selection";
320266bc8f7774b153401e54ed537db299159840981Scott Michel  }
321266bc8f7774b153401e54ed537db299159840981Scott Michel
322266bc8f7774b153401e54ed537db299159840981Scott Michel  /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
323266bc8f7774b153401e54ed537db299159840981Scott Michel  /// this target when scheduling the DAG.
324266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual HazardRecognizer *CreateTargetHazardRecognizer() {
325266bc8f7774b153401e54ed537db299159840981Scott Michel    const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo();
326266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(II && "No InstrInfo?");
327266bc8f7774b153401e54ed537db299159840981Scott Michel    return new SPUHazardRecognizer(*II);
328266bc8f7774b153401e54ed537db299159840981Scott Michel  }
329266bc8f7774b153401e54ed537db299159840981Scott Michel
330266bc8f7774b153401e54ed537db299159840981Scott Michel  // Include the pieces autogenerated from the target description.
331266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
332266bc8f7774b153401e54ed537db299159840981Scott Michel};
333266bc8f7774b153401e54ed537db299159840981Scott Michel
334266bc8f7774b153401e54ed537db299159840981Scott Michel/// InstructionSelectBasicBlock - This callback is invoked by
335266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
336266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
337266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG)
338266bc8f7774b153401e54ed537db299159840981Scott Michel{
339266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
340266bc8f7774b153401e54ed537db299159840981Scott Michel
341266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
342266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.setRoot(SelectRoot(DAG.getRoot()));
343266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.RemoveDeadNodes();
344266bc8f7774b153401e54ed537db299159840981Scott Michel
345266bc8f7774b153401e54ed537db299159840981Scott Michel  // Emit machine code to BB.
346266bc8f7774b153401e54ed537db299159840981Scott Michel  ScheduleAndEmitDAG(DAG);
347266bc8f7774b153401e54ed537db299159840981Scott Michel}
348266bc8f7774b153401e54ed537db299159840981Scott Michel
349266bc8f7774b153401e54ed537db299159840981Scott Michelbool
350266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
351266bc8f7774b153401e54ed537db299159840981Scott Michel				  SDOperand &Base) {
352266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
353266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned VT = N.getValueType();
354266bc8f7774b153401e54ed537db299159840981Scott Michel  MVT::ValueType PtrVT = SPUtli.getPointerTy();
355266bc8f7774b153401e54ed537db299159840981Scott Michel  ConstantSDNode *CN = 0;
356266bc8f7774b153401e54ed537db299159840981Scott Michel  int Imm;
357266bc8f7774b153401e54ed537db299159840981Scott Michel
358266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc == ISD::ADD) {
359266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op0 = N.getOperand(0);
360266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op1 = N.getOperand(1);
361266bc8f7774b153401e54ed537db299159840981Scott Michel    if (Op1.getOpcode() == ISD::Constant ||
362266bc8f7774b153401e54ed537db299159840981Scott Michel	Op1.getOpcode() == ISD::TargetConstant) {
363266bc8f7774b153401e54ed537db299159840981Scott Michel      CN = cast<ConstantSDNode>(Op1);
364266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = int(CN->getValue());
365266bc8f7774b153401e54ed537db299159840981Scott Michel      if (Imm <= 0xff) {
366266bc8f7774b153401e54ed537db299159840981Scott Michel	Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
367266bc8f7774b153401e54ed537db299159840981Scott Michel	Base = Op0;
368266bc8f7774b153401e54ed537db299159840981Scott Michel	return true;
369266bc8f7774b153401e54ed537db299159840981Scott Michel      }
370266bc8f7774b153401e54ed537db299159840981Scott Michel    }
371266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::GlobalAddress
372266bc8f7774b153401e54ed537db299159840981Scott Michel	     || Opc == ISD::TargetGlobalAddress
373266bc8f7774b153401e54ed537db299159840981Scott Michel	     || Opc == ISD::Register) {
374266bc8f7774b153401e54ed537db299159840981Scott Michel    // Plain old local store address:
375266bc8f7774b153401e54ed537db299159840981Scott Michel    Disp = CurDAG->getTargetConstant(0, VT);
376266bc8f7774b153401e54ed537db299159840981Scott Michel    Base = N;
377266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
378053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    SDOperand Op1 = N.getOperand(1);
380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (Op1.getOpcode() == ISD::TargetConstant
381053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || Op1.getOpcode() == ISD::Constant) {
382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      CN = cast<ConstantSDNode>(N.getOperand(1));
383053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      assert(CN != 0 && "SelectIndirectAddr/SPUISD::DForm2Addr expecting constant");
384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Imm = unsigned(CN->getValue());
385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Imm < 0xff) {
386053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT);
387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = N.getOperand(0);
388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
390266bc8f7774b153401e54ed537db299159840981Scott Michel    }
391266bc8f7774b153401e54ed537db299159840981Scott Michel  }
392266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
393266bc8f7774b153401e54ed537db299159840981Scott Michel}
394266bc8f7774b153401e54ed537db299159840981Scott Michel
395266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
396266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand
397266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
398266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
399266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
400266bc8f7774b153401e54ed537db299159840981Scott Michel */
401266bc8f7774b153401e54ed537db299159840981Scott Michelbool
402266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
403266bc8f7774b153401e54ed537db299159840981Scott Michel		    SDOperand &Index) {
404266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
405266bc8f7774b153401e54ed537db299159840981Scott Michel  MVT::ValueType OffsVT = MVT::i16;
406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  SDOperand Zero = CurDAG->getTargetConstant(0, OffsVT);
407266bc8f7774b153401e54ed537db299159840981Scott Michel
408266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
409266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
4109de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
4119de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
4129de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
4139de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    abort();
4149de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
4159de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
416053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
4179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
418053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
419053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as "
420053c1da8d956a794d158ac906b3927c923f97c4dScott Michel         << "A-form address.\n";
421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    abort();
422053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
423266bc8f7774b153401e54ed537db299159840981Scott Michel
424053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case SPUISD::AFormAddr:
425053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
426053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
427053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
428053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      SDOperand Op0 = N.getOperand(0);
429053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
430053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
431053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
432053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
433053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
434053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
435053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
436053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
437053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
438053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalValue *GV = GSDN->getGlobal();
439053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
440053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
441053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
442053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
443053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
450266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
451266bc8f7774b153401e54ed537db299159840981Scott Michel}
452266bc8f7774b153401e54ed537db299159840981Scott Michel
453266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
454266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
455266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
456266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
457266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
458266bc8f7774b153401e54ed537db299159840981Scott Michel
459266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
460266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
461266bc8f7774b153401e54ed537db299159840981Scott Michel
462266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
463266bc8f7774b153401e54ed537db299159840981Scott Michel  to non-empty SDOperand instances.
464266bc8f7774b153401e54ed537db299159840981Scott Michel*/
465266bc8f7774b153401e54ed537db299159840981Scott Michelbool
466266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
467266bc8f7774b153401e54ed537db299159840981Scott Michel				 SDOperand &Index) {
468266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
469266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned PtrTy = SPUtli.getPointerTy();
470266bc8f7774b153401e54ed537db299159840981Scott Michel
471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
473266bc8f7774b153401e54ed537db299159840981Scott Michel    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
474266bc8f7774b153401e54ed537db299159840981Scott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel	  << FI->getIndex() << "\n");
476266bc8f7774b153401e54ed537db299159840981Scott Michel    if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
477266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
478266bc8f7774b153401e54ed537db299159840981Scott Michel      Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
479266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
480266bc8f7774b153401e54ed537db299159840981Scott Michel    }
481266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
482266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op0 = N.getOperand(0);
484053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op1 = N.getOperand(1);
485266bc8f7774b153401e54ed537db299159840981Scott Michel
486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
489053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
492053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
4939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
495266bc8f7774b153401e54ed537db299159840981Scott Michel
496053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
4989de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
4999de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel              << " frame index = " << FI->getIndex() << "\n");
5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
5029de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
5039de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
5049de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5059de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
5069de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      } else if (offset > SPUFrameInfo::minFrameOffset()
5079de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel                 && offset < SPUFrameInfo::maxFrameOffset()) {
5089de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
510053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
511053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
513053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
514053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
516053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
517053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op1);
519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel              << " frame index = " << FI->getIndex() << "\n");
521053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
522053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
523053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
524053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
5259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
5269de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
527053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      } else if (offset > SPUFrameInfo::minFrameOffset()
528053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 && offset < SPUFrameInfo::maxFrameOffset()) {
529053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
530053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
531053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
532266bc8f7774b153401e54ed537db299159840981Scott Michel      }
533497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op0 = N.getOperand(0);
537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    const SDOperand Op1 = N.getOperand(1);
538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    SDOperand Zero = CurDAG->getTargetConstant(0, N.getValueType());
539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (Op1.getOpcode() == ISD::Constant
541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || Op1.getOpcode() == ISD::TargetConstant) {
542053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (offset > SPUFrameInfo::minFrameOffset()
545053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          && offset < SPUFrameInfo::maxFrameOffset()) {
546053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
547053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
548053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
549053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
550053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
551053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
552053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
553053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      int32_t offset = int32_t(CN->getSignExtended());
554053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (offset > SPUFrameInfo::minFrameOffset()
555053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          && offset < SPUFrameInfo::maxFrameOffset()) {
556053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == SPUISD::Hi
561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               && Op1.getOpcode() == SPUISD::Lo) {
562053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
5639de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
564053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
5659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
567053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
568053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
569053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
57058c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
571266bc8f7774b153401e54ed537db299159840981Scott Michel  }
572266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
573266bc8f7774b153401e54ed537db299159840981Scott Michel}
574266bc8f7774b153401e54ed537db299159840981Scott Michel
575266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
576266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
577266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
578266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
579266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
580266bc8f7774b153401e54ed537db299159840981Scott Michel
581266bc8f7774b153401e54ed537db299159840981Scott Michel  If the address \a N can be expressed as a [r + s10imm] address, returns false.
582266bc8f7774b153401e54ed537db299159840981Scott Michel  Otherwise, creates two operands, Base and Index that will become the [r+r]
583266bc8f7774b153401e54ed537db299159840981Scott Michel  address.
584266bc8f7774b153401e54ed537db299159840981Scott Michel*/
585266bc8f7774b153401e54ed537db299159840981Scott Michelbool
586266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
587266bc8f7774b153401e54ed537db299159840981Scott Michel				 SDOperand &Index) {
588266bc8f7774b153401e54ed537db299159840981Scott Michel  if (SelectAFormAddr(Op, N, Base, Index)
589266bc8f7774b153401e54ed537db299159840981Scott Michel      || SelectDFormAddr(Op, N, Base, Index))
590266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
591266bc8f7774b153401e54ed537db299159840981Scott Michel
592053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  // All else fails, punt and use an X-form address:
593053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Base = N.getOperand(0);
594053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  Index = N.getOperand(1);
595053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  return true;
59658c5818c01e375a84dc601140470fa68638004cfScott Michel}
59758c5818c01e375a84dc601140470fa68638004cfScott Michel
598266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
599266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
600266bc8f7774b153401e54ed537db299159840981Scott Michel */
601266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
602266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::Select(SDOperand Op) {
603266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *N = Op.Val;
604266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
60558c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
60658c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
60758c5818c01e375a84dc601140470fa68638004cfScott Michel  MVT::ValueType OpVT = Op.getValueType();
60858c5818c01e375a84dc601140470fa68638004cfScott Michel  SDOperand Ops[8];
609266bc8f7774b153401e54ed537db299159840981Scott Michel
610266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) {
611266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
612266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
613266bc8f7774b153401e54ed537db299159840981Scott Michel    // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
614266bc8f7774b153401e54ed537db299159840981Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
6159de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    MVT::ValueType PtrVT = SPUtli.getPointerTy();
6169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT);
6179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT);
618266bc8f7774b153401e54ed537db299159840981Scott Michel
6199999e685ea86e9cb8c8d59bfb2f3f4c20acc4de4Scott Michel    DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n");
62058c5818c01e375a84dc601140470fa68638004cfScott Michel    NewOpc = SPU::AIr32;
62158c5818c01e375a84dc601140470fa68638004cfScott Michel    Ops[0] = TFI;
62258c5818c01e375a84dc601140470fa68638004cfScott Michel    Ops[1] = Zero;
62358c5818c01e375a84dc601140470fa68638004cfScott Michel    n_ops = 2;
62458c5818c01e375a84dc601140470fa68638004cfScott Michel  } else if (Opc == ISD::ZERO_EXTEND) {
62558c5818c01e375a84dc601140470fa68638004cfScott Michel    // (zero_extend:i16 (and:i8 <arg>, <const>))
62658c5818c01e375a84dc601140470fa68638004cfScott Michel    const SDOperand &Op1 = N->getOperand(0);
62758c5818c01e375a84dc601140470fa68638004cfScott Michel
62858c5818c01e375a84dc601140470fa68638004cfScott Michel    if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) {
62958c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::AND) {
63058c5818c01e375a84dc601140470fa68638004cfScott Michel        // Fold this into a single ANDHI. This is often seen in expansions of i1
63158c5818c01e375a84dc601140470fa68638004cfScott Michel        // to i8, then i8 to i16 in logical/branching operations.
63258c5818c01e375a84dc601140470fa68638004cfScott Michel        DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
63358c5818c01e375a84dc601140470fa68638004cfScott Michel                      "<arg>, <const>))\n");
63458c5818c01e375a84dc601140470fa68638004cfScott Michel        NewOpc = SPU::ANDHI1To2;
63558c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[0] = Op1.getOperand(0);
63658c5818c01e375a84dc601140470fa68638004cfScott Michel        Ops[1] = Op1.getOperand(1);
63758c5818c01e375a84dc601140470fa68638004cfScott Michel        n_ops = 2;
63858c5818c01e375a84dc601140470fa68638004cfScott Michel      }
63958c5818c01e375a84dc601140470fa68638004cfScott Michel    }
640053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::INSERT_MASK) {
641053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    SDOperand Op0 = Op.getOperand(0);
642053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (Op0.getOpcode() == SPUISD::AFormAddr) {
643053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUvecinsmask (SPUaform <arg>, 0)) ->
644053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (CBD|CHD|CWD 0, arg)
645053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      const valtype_map_s *vtm = getValueTypeMapEntry(OpVT);
646053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getOperand(1));
647053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      assert(vtm->insmask_ins != 0 && "missing insert mask instruction");
648053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      NewOpc = vtm->insmask_ins;
649053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[0] = CurDAG->getTargetConstant(CN->getValue(), Op0.getValueType());
650053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[1] = Op0;
651053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      n_ops = 2;
652053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
653053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      AddToISelQueue(Op0);
654053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::FrameIndex) {
655053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUvecinsmask <fi>) ->
656053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (CBD|CHD|CWD 0, <fi>)
657053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      const valtype_map_s *vtm = getValueTypeMapEntry(OpVT);
658053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      NewOpc = vtm->insmask_ins;
659053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[0] = CurDAG->getTargetConstant(0, Op0.getValueType());
660053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[1] = Op0;
661053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      n_ops = 2;
662053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (isHighLow(Op0)) {
663053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUvecinsmask (SPUindirect (SPUhi <arg>, 0), (SPUlow <arg>, 0))) ->
664053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (CBD|CHD|CWD 0, arg)
665053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      const valtype_map_s *vtm = getValueTypeMapEntry(OpVT);
666053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      NewOpc = vtm->insmask_ins;
667053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[0] = CurDAG->getTargetConstant(0, Op0.getValueType());
668053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Ops[1] = Op0;
669053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      n_ops = 2;
670053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      AddToISelQueue(Op0);
671053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
672266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
673266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
674266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned VT = N->getValueType(0);
675266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Arg = N->getOperand(0);
676266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Chain = N->getOperand(1);
677266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
678266bc8f7774b153401e54ed537db299159840981Scott Michel
679266bc8f7774b153401e54ed537db299159840981Scott Michel    AddToISelQueue(Arg);
68086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    if (!MVT::isFloatingPoint(VT)) {
68186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      SDOperand Zero = CurDAG->getTargetConstant(0, VT);
68286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      const valtype_map_s *vtm = getValueTypeMapEntry(VT);
68386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
68486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      if (vtm->ldresult_ins == 0) {
68586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	cerr << "LDRESULT for unsupported type: "
68686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	     << MVT::getValueTypeString(VT)
68786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	     << "\n";
68886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	abort();
68986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      } else
69086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	Opc = vtm->ldresult_ins;
69186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
69286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      AddToISelQueue(Zero);
69358c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
69486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
69558c5818c01e375a84dc601140470fa68638004cfScott Michel      Opc = (VT == MVT::f32 ? SPU::ORf32 : SPU::ORf64);
69658c5818c01e375a84dc601140470fa68638004cfScott Michel      Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain);
69786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
69886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
699266bc8f7774b153401e54ed537db299159840981Scott Michel    Chain = SDOperand(Result, 1);
70086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    AddToISelQueue(Chain);
70186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
702266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
703053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
70458c5818c01e375a84dc601140470fa68638004cfScott Michel    SDOperand Op0 = Op.getOperand(0);
70558c5818c01e375a84dc601140470fa68638004cfScott Michel    if (Op0.getOpcode() == SPUISD::LDRESULT
70658c5818c01e375a84dc601140470fa68638004cfScott Michel        || Op0.getOpcode() == SPUISD::AFormAddr) {
707053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (IndirectAddr (LDRESULT|AFormAddr, imm))
70858c5818c01e375a84dc601140470fa68638004cfScott Michel      SDOperand Op1 = Op.getOperand(1);
70958c5818c01e375a84dc601140470fa68638004cfScott Michel      MVT::ValueType VT = Op.getValueType();
71058c5818c01e375a84dc601140470fa68638004cfScott Michel
711053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      DEBUG(cerr << "CellSPU: IndirectAddr("
712053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 << (Op0.getOpcode() == SPUISD::LDRESULT
713053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                     ? "LDRESULT"
714053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                     : "AFormAddr")
715053c1da8d956a794d158ac906b3927c923f97c4dScott Michel                 << ", imm):\nOp0 = ");
71658c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(Op.getOperand(0).Val->dump(CurDAG));
71758c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\nOp1 = ");
71858c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(Op.getOperand(1).Val->dump(CurDAG));
71958c5818c01e375a84dc601140470fa68638004cfScott Michel      DEBUG(cerr << "\n");
72058c5818c01e375a84dc601140470fa68638004cfScott Michel
72158c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
72258c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
72358c5818c01e375a84dc601140470fa68638004cfScott Michel        Op1 = CurDAG->getTargetConstant(CN->getValue(), VT);
72458c5818c01e375a84dc601140470fa68638004cfScott Michel      }
72558c5818c01e375a84dc601140470fa68638004cfScott Michel      AddToISelQueue(Op0);
72658c5818c01e375a84dc601140470fa68638004cfScott Michel      AddToISelQueue(Op1);
72758c5818c01e375a84dc601140470fa68638004cfScott Michel      NewOpc = SPU::AIr32;
72858c5818c01e375a84dc601140470fa68638004cfScott Michel      Ops[0] = Op0;
72958c5818c01e375a84dc601140470fa68638004cfScott Michel      Ops[1] = Op1;
73058c5818c01e375a84dc601140470fa68638004cfScott Michel      n_ops = 2;
73158c5818c01e375a84dc601140470fa68638004cfScott Michel    }
732266bc8f7774b153401e54ed537db299159840981Scott Michel  }
733266bc8f7774b153401e54ed537db299159840981Scott Michel
73458c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
73558c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
73658c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
73758c5818c01e375a84dc601140470fa68638004cfScott Michel    else
73858c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops);
73958c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
74058c5818c01e375a84dc601140470fa68638004cfScott Michel    return SelectCode(Op);
741266bc8f7774b153401e54ed537db299159840981Scott Michel}
742266bc8f7774b153401e54ed537db299159840981Scott Michel
743266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a
744266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
745266bc8f7774b153401e54ed537db299159840981Scott Michel///
746266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
747266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
748266bc8f7774b153401e54ed537db299159840981Scott Michel}
749