SPUISelDAGToDAG.cpp revision 497e888daf9ba6489928e1153804ed12a7fe44c5
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
153266bc8f7774b153401e54ed537db299159840981Scott Michel  //===------------------------------------------------------------------===//
15486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel  //! MVT::ValueType to "useful stuff" mapping structure:
155266bc8f7774b153401e54ed537db299159840981Scott Michel
156266bc8f7774b153401e54ed537db299159840981Scott Michel  struct valtype_map_s {
157266bc8f7774b153401e54ed537db299159840981Scott Michel    MVT::ValueType VT;
158266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned ldresult_ins;	/// LDRESULT instruction (0 = undefined)
159266bc8f7774b153401e54ed537db299159840981Scott Michel    int prefslot_byte;		/// Byte offset of the "preferred" slot
160266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned brcc_eq_ins;	/// br_cc equal instruction
161266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned brcc_neq_ins;	/// br_cc not equal instruction
162266bc8f7774b153401e54ed537db299159840981Scott Michel  };
163266bc8f7774b153401e54ed537db299159840981Scott Michel
164266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s valtype_map[] = {
16586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::i1,  0,            3, 0,         0 },
16686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::i8,  0,            3, 0,         0 },
16786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::i16, SPU::ORHIr16, 2, SPU::BRHZ, SPU::BRHNZ },
16886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::i32, SPU::ORIr32,  0, SPU::BRZ,  SPU::BRNZ },
16986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::i64, SPU::ORIr64,  0, 0,         0 },
17086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::f32, 0,            0, 0,         0 },
17186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    { MVT::f64, 0,            0, 0,         0 }
172266bc8f7774b153401e54ed537db299159840981Scott Michel  };
173266bc8f7774b153401e54ed537db299159840981Scott Michel
174266bc8f7774b153401e54ed537db299159840981Scott Michel  const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
175266bc8f7774b153401e54ed537db299159840981Scott Michel
176266bc8f7774b153401e54ed537db299159840981Scott Michel  const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT)
177266bc8f7774b153401e54ed537db299159840981Scott Michel  {
178266bc8f7774b153401e54ed537db299159840981Scott Michel    const valtype_map_s *retval = 0;
179266bc8f7774b153401e54ed537db299159840981Scott Michel    for (size_t i = 0; i < n_valtype_map; ++i) {
180266bc8f7774b153401e54ed537db299159840981Scott Michel      if (valtype_map[i].VT == VT) {
181266bc8f7774b153401e54ed537db299159840981Scott Michel	retval = valtype_map + i;
182266bc8f7774b153401e54ed537db299159840981Scott Michel	break;
183266bc8f7774b153401e54ed537db299159840981Scott Michel      }
184266bc8f7774b153401e54ed537db299159840981Scott Michel    }
185266bc8f7774b153401e54ed537db299159840981Scott Michel
186266bc8f7774b153401e54ed537db299159840981Scott Michel
187266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG
188266bc8f7774b153401e54ed537db299159840981Scott Michel    if (retval == 0) {
189266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
190266bc8f7774b153401e54ed537db299159840981Scott Michel	   << MVT::getValueTypeString(VT)
191266bc8f7774b153401e54ed537db299159840981Scott Michel	   << "\n";
192266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
193266bc8f7774b153401e54ed537db299159840981Scott Michel    }
194266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
195266bc8f7774b153401e54ed537db299159840981Scott Michel
196266bc8f7774b153401e54ed537db299159840981Scott Michel    return retval;
197266bc8f7774b153401e54ed537db299159840981Scott Michel  }
198266bc8f7774b153401e54ed537db299159840981Scott Michel}
199266bc8f7774b153401e54ed537db299159840981Scott Michel
200266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===//
201266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
202266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations.
203266bc8f7774b153401e54ed537db299159840981Scott Michel///
204266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel :
205266bc8f7774b153401e54ed537db299159840981Scott Michel  public SelectionDAGISel
206266bc8f7774b153401e54ed537db299159840981Scott Michel{
207266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetMachine &TM;
208266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUTargetLowering &SPUtli;
209266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned GlobalBaseReg;
210266bc8f7774b153401e54ed537db299159840981Scott Michel
211266bc8f7774b153401e54ed537db299159840981Scott Michelpublic:
212266bc8f7774b153401e54ed537db299159840981Scott Michel  SPUDAGToDAGISel(SPUTargetMachine &tm) :
213266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel(*tm.getTargetLowering()),
214266bc8f7774b153401e54ed537db299159840981Scott Michel    TM(tm),
215266bc8f7774b153401e54ed537db299159840981Scott Michel    SPUtli(*tm.getTargetLowering())
216266bc8f7774b153401e54ed537db299159840981Scott Michel  {}
217266bc8f7774b153401e54ed537db299159840981Scott Michel
218266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool runOnFunction(Function &Fn) {
219266bc8f7774b153401e54ed537db299159840981Scott Michel    // Make sure we re-emit a set of the global base reg if necessary
220266bc8f7774b153401e54ed537db299159840981Scott Michel    GlobalBaseReg = 0;
221266bc8f7774b153401e54ed537db299159840981Scott Michel    SelectionDAGISel::runOnFunction(Fn);
222266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
223266bc8f7774b153401e54ed537db299159840981Scott Michel  }
224266bc8f7774b153401e54ed537db299159840981Scott Michel
225266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI32Imm - Return a target constant with the specified value, of type
226266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i32.
227266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand getI32Imm(uint32_t Imm) {
228266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i32);
229266bc8f7774b153401e54ed537db299159840981Scott Michel  }
230266bc8f7774b153401e54ed537db299159840981Scott Michel
231266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getI64Imm - Return a target constant with the specified value, of type
232266bc8f7774b153401e54ed537db299159840981Scott Michel  /// i64.
233266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand getI64Imm(uint64_t Imm) {
234266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, MVT::i64);
235266bc8f7774b153401e54ed537db299159840981Scott Michel  }
236266bc8f7774b153401e54ed537db299159840981Scott Michel
237266bc8f7774b153401e54ed537db299159840981Scott Michel  /// getSmallIPtrImm - Return a target constant of pointer type.
238266bc8f7774b153401e54ed537db299159840981Scott Michel  inline SDOperand getSmallIPtrImm(unsigned Imm) {
239266bc8f7774b153401e54ed537db299159840981Scott Michel    return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
240266bc8f7774b153401e54ed537db299159840981Scott Michel  }
241266bc8f7774b153401e54ed537db299159840981Scott Michel
242266bc8f7774b153401e54ed537db299159840981Scott Michel  /// Select - Convert the specified operand from a target-independent to a
243266bc8f7774b153401e54ed537db299159840981Scott Michel  /// target-specific node if it hasn't already been changed.
244266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *Select(SDOperand Op);
245266bc8f7774b153401e54ed537db299159840981Scott Michel
246266bc8f7774b153401e54ed537db299159840981Scott Michel  /// Return true if the address N is a RI7 format address [r+imm]
247266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
248266bc8f7774b153401e54ed537db299159840981Scott Michel			SDOperand &Base);
249266bc8f7774b153401e54ed537db299159840981Scott Michel
250266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Returns true if the address N is an A-form (local store) address
251266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
252266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
253266bc8f7774b153401e54ed537db299159840981Scott Michel
254266bc8f7774b153401e54ed537db299159840981Scott Michel  //! D-form address predicate
255266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
256266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
257266bc8f7774b153401e54ed537db299159840981Scott Michel
258266bc8f7774b153401e54ed537db299159840981Scott Michel  //! Address predicate if N can be expressed as an indexed [r+r] operation.
259266bc8f7774b153401e54ed537db299159840981Scott Michel  bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
260266bc8f7774b153401e54ed537db299159840981Scott Michel		       SDOperand &Index);
261266bc8f7774b153401e54ed537db299159840981Scott Michel
262266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
263266bc8f7774b153401e54ed537db299159840981Scott Michel  /// inline asm expressions.
264266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
265266bc8f7774b153401e54ed537db299159840981Scott Michel					    char ConstraintCode,
266266bc8f7774b153401e54ed537db299159840981Scott Michel					    std::vector<SDOperand> &OutOps,
267266bc8f7774b153401e54ed537db299159840981Scott Michel					    SelectionDAG &DAG) {
268266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op0, Op1;
269266bc8f7774b153401e54ed537db299159840981Scott Michel    switch (ConstraintCode) {
270266bc8f7774b153401e54ed537db299159840981Scott Michel    default: return true;
271266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'm':   // memory
272266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
273266bc8f7774b153401e54ed537db299159840981Scott Michel	  && !SelectAFormAddr(Op, Op, Op0, Op1))
274266bc8f7774b153401e54ed537db299159840981Scott Michel	SelectXFormAddr(Op, Op, Op0, Op1);
275266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
276266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'o':   // offsetable
277266bc8f7774b153401e54ed537db299159840981Scott Michel      if (!SelectDFormAddr(Op, Op, Op0, Op1)
278266bc8f7774b153401e54ed537db299159840981Scott Michel	  && !SelectAFormAddr(Op, Op, Op0, Op1)) {
279266bc8f7774b153401e54ed537db299159840981Scott Michel	Op0 = Op;
280266bc8f7774b153401e54ed537db299159840981Scott Michel	AddToISelQueue(Op0);     // r+0.
281266bc8f7774b153401e54ed537db299159840981Scott Michel	Op1 = getSmallIPtrImm(0);
282266bc8f7774b153401e54ed537db299159840981Scott Michel      }
283266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
284266bc8f7774b153401e54ed537db299159840981Scott Michel    case 'v':   // not offsetable
285266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
286266bc8f7774b153401e54ed537db299159840981Scott Michel      assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
287266bc8f7774b153401e54ed537db299159840981Scott Michel#else
288266bc8f7774b153401e54ed537db299159840981Scott Michel      SelectAddrIdxOnly(Op, Op, Op0, Op1);
289266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
290266bc8f7774b153401e54ed537db299159840981Scott Michel      break;
291266bc8f7774b153401e54ed537db299159840981Scott Michel    }
292266bc8f7774b153401e54ed537db299159840981Scott Michel
293266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op0);
294266bc8f7774b153401e54ed537db299159840981Scott Michel    OutOps.push_back(Op1);
295266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
296266bc8f7774b153401e54ed537db299159840981Scott Michel  }
297266bc8f7774b153401e54ed537db299159840981Scott Michel
298266bc8f7774b153401e54ed537db299159840981Scott Michel  /// InstructionSelectBasicBlock - This callback is invoked by
299266bc8f7774b153401e54ed537db299159840981Scott Michel  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
300266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
301266bc8f7774b153401e54ed537db299159840981Scott Michel
302266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual const char *getPassName() const {
303266bc8f7774b153401e54ed537db299159840981Scott Michel    return "Cell SPU DAG->DAG Pattern Instruction Selection";
304266bc8f7774b153401e54ed537db299159840981Scott Michel  }
305266bc8f7774b153401e54ed537db299159840981Scott Michel
306266bc8f7774b153401e54ed537db299159840981Scott Michel  /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
307266bc8f7774b153401e54ed537db299159840981Scott Michel  /// this target when scheduling the DAG.
308266bc8f7774b153401e54ed537db299159840981Scott Michel  virtual HazardRecognizer *CreateTargetHazardRecognizer() {
309266bc8f7774b153401e54ed537db299159840981Scott Michel    const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo();
310266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(II && "No InstrInfo?");
311266bc8f7774b153401e54ed537db299159840981Scott Michel    return new SPUHazardRecognizer(*II);
312266bc8f7774b153401e54ed537db299159840981Scott Michel  }
313266bc8f7774b153401e54ed537db299159840981Scott Michel
314266bc8f7774b153401e54ed537db299159840981Scott Michel  // Include the pieces autogenerated from the target description.
315266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
316266bc8f7774b153401e54ed537db299159840981Scott Michel};
317266bc8f7774b153401e54ed537db299159840981Scott Michel
318266bc8f7774b153401e54ed537db299159840981Scott Michel/// InstructionSelectBasicBlock - This callback is invoked by
319266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
320266bc8f7774b153401e54ed537db299159840981Scott Michelvoid
321266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG)
322266bc8f7774b153401e54ed537db299159840981Scott Michel{
323266bc8f7774b153401e54ed537db299159840981Scott Michel  DEBUG(BB->dump());
324266bc8f7774b153401e54ed537db299159840981Scott Michel
325266bc8f7774b153401e54ed537db299159840981Scott Michel  // Select target instructions for the DAG.
326266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.setRoot(SelectRoot(DAG.getRoot()));
327266bc8f7774b153401e54ed537db299159840981Scott Michel  DAG.RemoveDeadNodes();
328266bc8f7774b153401e54ed537db299159840981Scott Michel
329266bc8f7774b153401e54ed537db299159840981Scott Michel  // Emit machine code to BB.
330266bc8f7774b153401e54ed537db299159840981Scott Michel  ScheduleAndEmitDAG(DAG);
331266bc8f7774b153401e54ed537db299159840981Scott Michel}
332266bc8f7774b153401e54ed537db299159840981Scott Michel
333266bc8f7774b153401e54ed537db299159840981Scott Michelbool
334266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
335266bc8f7774b153401e54ed537db299159840981Scott Michel				  SDOperand &Base) {
336266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
337266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned VT = N.getValueType();
338266bc8f7774b153401e54ed537db299159840981Scott Michel  MVT::ValueType PtrVT = SPUtli.getPointerTy();
339266bc8f7774b153401e54ed537db299159840981Scott Michel  ConstantSDNode *CN = 0;
340266bc8f7774b153401e54ed537db299159840981Scott Michel  int Imm;
341266bc8f7774b153401e54ed537db299159840981Scott Michel
342266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc == ISD::ADD) {
343266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op0 = N.getOperand(0);
344266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Op1 = N.getOperand(1);
345266bc8f7774b153401e54ed537db299159840981Scott Michel    if (Op1.getOpcode() == ISD::Constant ||
346266bc8f7774b153401e54ed537db299159840981Scott Michel	Op1.getOpcode() == ISD::TargetConstant) {
347266bc8f7774b153401e54ed537db299159840981Scott Michel      CN = cast<ConstantSDNode>(Op1);
348266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = int(CN->getValue());
349266bc8f7774b153401e54ed537db299159840981Scott Michel      if (Imm <= 0xff) {
350266bc8f7774b153401e54ed537db299159840981Scott Michel	Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
351266bc8f7774b153401e54ed537db299159840981Scott Michel	Base = Op0;
352266bc8f7774b153401e54ed537db299159840981Scott Michel	return true;
353266bc8f7774b153401e54ed537db299159840981Scott Michel      }
354266bc8f7774b153401e54ed537db299159840981Scott Michel    }
355266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::GlobalAddress
356266bc8f7774b153401e54ed537db299159840981Scott Michel	     || Opc == ISD::TargetGlobalAddress
357266bc8f7774b153401e54ed537db299159840981Scott Michel	     || Opc == ISD::Register) {
358266bc8f7774b153401e54ed537db299159840981Scott Michel    // Plain old local store address:
359266bc8f7774b153401e54ed537db299159840981Scott Michel    Disp = CurDAG->getTargetConstant(0, VT);
360266bc8f7774b153401e54ed537db299159840981Scott Michel    Base = N;
361266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
362266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::DFormAddr) {
363266bc8f7774b153401e54ed537db299159840981Scott Michel    // D-Form address: This is pretty straightforward, naturally...
364266bc8f7774b153401e54ed537db299159840981Scott Michel    CN = cast<ConstantSDNode>(N.getOperand(1));
365266bc8f7774b153401e54ed537db299159840981Scott Michel    assert(CN != 0 && "SelectDFormAddr/SPUISD::DForm2Addr expecting constant");
366266bc8f7774b153401e54ed537db299159840981Scott Michel    Imm = unsigned(CN->getValue());
367266bc8f7774b153401e54ed537db299159840981Scott Michel    if (Imm < 0xff) {
368266bc8f7774b153401e54ed537db299159840981Scott Michel      Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT);
369266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = N.getOperand(0);
370266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
371266bc8f7774b153401e54ed537db299159840981Scott Michel    }
372266bc8f7774b153401e54ed537db299159840981Scott Michel  }
373266bc8f7774b153401e54ed537db299159840981Scott Michel
374266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
375266bc8f7774b153401e54ed537db299159840981Scott Michel}
376266bc8f7774b153401e54ed537db299159840981Scott Michel
377266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
378266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand
379266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
380266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
381266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
382266bc8f7774b153401e54ed537db299159840981Scott Michel */
383266bc8f7774b153401e54ed537db299159840981Scott Michelbool
384266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
385266bc8f7774b153401e54ed537db299159840981Scott Michel		    SDOperand &Index) {
386266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
387266bc8f7774b153401e54ed537db299159840981Scott Michel  MVT::ValueType OffsVT = MVT::i16;
3889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  MVT::ValueType PtrVT = SPUtli.getPointerTy();
389266bc8f7774b153401e54ed537db299159840981Scott Michel
390266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
391266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
3959de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    abort();
3969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
398266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::TargetConstant: {
399266bc8f7774b153401e54ed537db299159840981Scott Michel    // Loading from a constant address.
400266bc8f7774b153401e54ed537db299159840981Scott Michel    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
401266bc8f7774b153401e54ed537db299159840981Scott Michel    int Imm = (int)CN->getValue();
402266bc8f7774b153401e54ed537db299159840981Scott Michel    if (Imm < 0x3ffff && (Imm & 0x3) == 0) {
403266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(Imm, PtrVT);
404266bc8f7774b153401e54ed537db299159840981Scott Michel      // Note that this operand will be ignored by the assembly printer...
405266bc8f7774b153401e54ed537db299159840981Scott Michel      Index = CurDAG->getTargetConstant(0, OffsVT);
406266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
407266bc8f7774b153401e54ed537db299159840981Scott Michel    }
408266bc8f7774b153401e54ed537db299159840981Scott Michel  }
4099de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
4109de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetConstantPool:
4119de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case SPUISD::AFormAddr: {
4129de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    // The address is in Base. N is a dummy that will be ignored by
413266bc8f7774b153401e54ed537db299159840981Scott Michel    // the assembly printer.
414266bc8f7774b153401e54ed537db299159840981Scott Michel    Base = N;
415266bc8f7774b153401e54ed537db299159840981Scott Michel    Index = CurDAG->getTargetConstant(0, OffsVT);
416266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
417266bc8f7774b153401e54ed537db299159840981Scott Michel  }
418266bc8f7774b153401e54ed537db299159840981Scott Michel  }
419266bc8f7774b153401e54ed537db299159840981Scott Michel
420266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
421266bc8f7774b153401e54ed537db299159840981Scott Michel}
422266bc8f7774b153401e54ed537db299159840981Scott Michel
423266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
424266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
425266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
426266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
427266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
428266bc8f7774b153401e54ed537db299159840981Scott Michel
429266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
430266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
431266bc8f7774b153401e54ed537db299159840981Scott Michel
432266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
433266bc8f7774b153401e54ed537db299159840981Scott Michel  to non-empty SDOperand instances.
434266bc8f7774b153401e54ed537db299159840981Scott Michel*/
435266bc8f7774b153401e54ed537db299159840981Scott Michelbool
436266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
437266bc8f7774b153401e54ed537db299159840981Scott Michel				 SDOperand &Index) {
438266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
439266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned PtrTy = SPUtli.getPointerTy();
440266bc8f7774b153401e54ed537db299159840981Scott Michel
441266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc == ISD::Register) {
442266bc8f7774b153401e54ed537db299159840981Scott Michel    Base = N;
443266bc8f7774b153401e54ed537db299159840981Scott Michel    Index = CurDAG->getTargetConstant(0, PtrTy);
444266bc8f7774b153401e54ed537db299159840981Scott Michel    return true;
445266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
446266bc8f7774b153401e54ed537db299159840981Scott Michel    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
447266bc8f7774b153401e54ed537db299159840981Scott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel	       << FI->getIndex() << "\n");
449266bc8f7774b153401e54ed537db299159840981Scott Michel    if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
450266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
451266bc8f7774b153401e54ed537db299159840981Scott Michel      Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
452266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
453266bc8f7774b153401e54ed537db299159840981Scott Michel    }
454266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
455266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
456266bc8f7774b153401e54ed537db299159840981Scott Michel    const SDOperand Op0 = N.getOperand(0); // Frame index/base
457266bc8f7774b153401e54ed537db299159840981Scott Michel    const SDOperand Op1 = N.getOperand(1); // Offset within base
458266bc8f7774b153401e54ed537db299159840981Scott Michel
459497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    if ((Op1.getOpcode() == ISD::Constant
460497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel	 || Op1.getOpcode() == ISD::TargetConstant)
461497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel	&& Op0.getOpcode() != SPUISD::XFormAddr) {
4629de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
4639de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      assert(CN != 0 && "SelectDFormAddr: Expected a constant");
464266bc8f7774b153401e54ed537db299159840981Scott Michel
4659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      int32_t offset = (int32_t) CN->getSignExtended();
4669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      unsigned Opc0 = Op0.getOpcode();
467266bc8f7774b153401e54ed537db299159840981Scott Michel
4689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      if ((offset & 0xf) != 0) {
4699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        // Unaligned offset: punt and let X-form address handle it.
4709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        // NOTE: This really doesn't have to be strictly 16-byte aligned,
4719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        // since the load/store quadword instructions will implicitly
4729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        // zero the lower 4 bits of the resulting address.
4739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        return false;
474266bc8f7774b153401e54ed537db299159840981Scott Michel      }
4759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
4769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      if (Opc0 == ISD::FrameIndex) {
4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
4789de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel              << " frame index = " << FI->getIndex() << "\n");
4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
4819de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
4839de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
4849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4869de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      } else if (offset > SPUFrameInfo::minFrameOffset()
4879de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel                 && offset < SPUFrameInfo::maxFrameOffset()) {
4889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
4899de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        if (Opc0 == ISD::GlobalAddress) {
4909de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          // Convert global address to target global address
4919de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0);
4929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy);
4939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        } else {
4959de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          // Otherwise, just take operand 0
4969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Index = Op0;
4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4989de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
499266bc8f7774b153401e54ed537db299159840981Scott Michel      }
5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    } else
5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return false;
502266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::DFormAddr) {
503497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    // D-Form address: This is pretty straightforward,
504497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    // naturally... but make sure that this isn't a D-form address
505497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    // with a X-form address embedded within:
506497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    const SDOperand Op0 = N.getOperand(0); // Frame index/base
507497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    const SDOperand Op1 = N.getOperand(1); // Offset within base
508497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel
509497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    if (Op0.getOpcode() != SPUISD::XFormAddr) {
510497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
511497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant");
512497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
513497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      Index = Op0;
514497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      return true;
515497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
5169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  } else if (Opc == ISD::FrameIndex) {
5179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    // Stack frame index must be less than 512 (divided by 16):
5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
5199de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
5209de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel	  << FI->getIndex() << "\n");
5219de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
5229de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
5239de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
5249de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
5259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
526266bc8f7774b153401e54ed537db299159840981Scott Michel  }
527266bc8f7774b153401e54ed537db299159840981Scott Michel
528266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
529266bc8f7774b153401e54ed537db299159840981Scott Michel}
530266bc8f7774b153401e54ed537db299159840981Scott Michel
531266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
532266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
533266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
534266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
535266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
536266bc8f7774b153401e54ed537db299159840981Scott Michel
537266bc8f7774b153401e54ed537db299159840981Scott Michel  If the address \a N can be expressed as a [r + s10imm] address, returns false.
538266bc8f7774b153401e54ed537db299159840981Scott Michel  Otherwise, creates two operands, Base and Index that will become the [r+r]
539266bc8f7774b153401e54ed537db299159840981Scott Michel  address.
540266bc8f7774b153401e54ed537db299159840981Scott Michel*/
541266bc8f7774b153401e54ed537db299159840981Scott Michelbool
542266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
543266bc8f7774b153401e54ed537db299159840981Scott Michel				 SDOperand &Index) {
544266bc8f7774b153401e54ed537db299159840981Scott Michel  if (SelectAFormAddr(Op, N, Base, Index)
545266bc8f7774b153401e54ed537db299159840981Scott Michel      || SelectDFormAddr(Op, N, Base, Index))
546266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
547266bc8f7774b153401e54ed537db299159840981Scott Michel
548266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
549266bc8f7774b153401e54ed537db299159840981Scott Michel
550266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc == ISD::ADD) {
551266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand N1 = N.getOperand(0);
552266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand N2 = N.getOperand(1);
553266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned N1Opc = N1.getOpcode();
554266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned N2Opc = N2.getOpcode();
555266bc8f7774b153401e54ed537db299159840981Scott Michel
556266bc8f7774b153401e54ed537db299159840981Scott Michel    if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo)
5579de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel	 || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)
5589de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        || (N1Opc == SPUISD::XFormAddr)) {
559266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = N.getOperand(0);
560266bc8f7774b153401e54ed537db299159840981Scott Michel      Index = N.getOperand(1);
561266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
562266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
563266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "SelectXFormAddr: Unhandled ADD operands:\n";
564266bc8f7774b153401e54ed537db299159840981Scott Michel      N1.Val->dump();
565266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "\n";
566266bc8f7774b153401e54ed537db299159840981Scott Michel      N2.Val->dump();
567266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "\n";
568266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
569266bc8f7774b153401e54ed537db299159840981Scott Michel      /*UNREACHED*/
570266bc8f7774b153401e54ed537db299159840981Scott Michel    }
5719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  } else if (Opc == SPUISD::XFormAddr) {
5729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    Base = N;
5739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    Index = N.getOperand(1);
5749de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    return true;
575497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel  } else if (Opc == SPUISD::DFormAddr) {
576497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    // Must be a D-form address with an X-form address embedded
577497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    // within:
578497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    Base = N.getOperand(0);
579497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    Index = N.getOperand(1);
580497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    return true;
581266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (N.getNumOperands() == 2) {
582266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand N1 = N.getOperand(0);
583266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand N2 = N.getOperand(1);
584266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned N1Opc = N1.getOpcode();
585266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned N2Opc = N2.getOpcode();
586266bc8f7774b153401e54ed537db299159840981Scott Michel
587266bc8f7774b153401e54ed537db299159840981Scott Michel    if ((N1Opc == ISD::CopyToReg || N1Opc == ISD::Register)
588266bc8f7774b153401e54ed537db299159840981Scott Michel	&& (N2Opc == ISD::CopyToReg || N2Opc == ISD::Register)) {
589266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = N.getOperand(0);
590266bc8f7774b153401e54ed537db299159840981Scott Michel      Index = N.getOperand(1);
591266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
592266bc8f7774b153401e54ed537db299159840981Scott Michel      /*UNREACHED*/
593266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
594266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "SelectXFormAddr: 2-operand unhandled operand:\n";
595497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel      N.Val->dump(CurDAG);
596266bc8f7774b153401e54ed537db299159840981Scott Michel      cerr << "\n";
597266bc8f7774b153401e54ed537db299159840981Scott Michel      abort();
598266bc8f7774b153401e54ed537db299159840981Scott Michel    /*UNREACHED*/
599266bc8f7774b153401e54ed537db299159840981Scott Michel    }
600266bc8f7774b153401e54ed537db299159840981Scott Michel  } else {
601266bc8f7774b153401e54ed537db299159840981Scott Michel    cerr << "SelectXFormAddr: Unhandled operand type:\n";
602497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    N.Val->dump(CurDAG);
603266bc8f7774b153401e54ed537db299159840981Scott Michel    cerr << "\n";
604266bc8f7774b153401e54ed537db299159840981Scott Michel    abort();
605266bc8f7774b153401e54ed537db299159840981Scott Michel    /*UNREACHED*/
606266bc8f7774b153401e54ed537db299159840981Scott Michel  }
607266bc8f7774b153401e54ed537db299159840981Scott Michel
608266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
609266bc8f7774b153401e54ed537db299159840981Scott Michel}
610266bc8f7774b153401e54ed537db299159840981Scott Michel
611266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
612266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
613266bc8f7774b153401e54ed537db299159840981Scott Michel */
614266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
615266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::Select(SDOperand Op) {
616266bc8f7774b153401e54ed537db299159840981Scott Michel  SDNode *N = Op.Val;
617266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
618266bc8f7774b153401e54ed537db299159840981Scott Michel
619266bc8f7774b153401e54ed537db299159840981Scott Michel  if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) {
620266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
621266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::FrameIndex) {
622266bc8f7774b153401e54ed537db299159840981Scott Michel    // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
623266bc8f7774b153401e54ed537db299159840981Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
6249de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    MVT::ValueType PtrVT = SPUtli.getPointerTy();
6259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT);
6269de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT);
627266bc8f7774b153401e54ed537db299159840981Scott Michel
6289999e685ea86e9cb8c8d59bfb2f3f4c20acc4de4Scott Michel    DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n");
6299de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    if (N->hasOneUse())
6309de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, Zero);
6319de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    CurDAG->getTargetNode(SPU::AIr32, Op.getValueType(), TFI, Zero);
632266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
633266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
634266bc8f7774b153401e54ed537db299159840981Scott Michel    unsigned VT = N->getValueType(0);
635266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Arg = N->getOperand(0);
636266bc8f7774b153401e54ed537db299159840981Scott Michel    SDOperand Chain = N->getOperand(1);
637266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
638266bc8f7774b153401e54ed537db299159840981Scott Michel
639266bc8f7774b153401e54ed537db299159840981Scott Michel    AddToISelQueue(Arg);
64086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    if (!MVT::isFloatingPoint(VT)) {
64186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      SDOperand Zero = CurDAG->getTargetConstant(0, VT);
64286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      const valtype_map_s *vtm = getValueTypeMapEntry(VT);
64386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
64486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      if (vtm->ldresult_ins == 0) {
64586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	cerr << "LDRESULT for unsupported type: "
64686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	     << MVT::getValueTypeString(VT)
64786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	     << "\n";
64886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	abort();
64986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      } else
65086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	Opc = vtm->ldresult_ins;
65186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
65286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      AddToISelQueue(Zero);
65386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      Result = CurDAG->SelectNodeTo(N, Opc, VT, MVT::Other, Arg, Zero, Chain);
65486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    } else {
65586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel      Result =
65686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel	CurDAG->SelectNodeTo(N, (VT == MVT::f32 ? SPU::ORf32 : SPU::ORf64),
65786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel			     MVT::Other, Arg, Arg, Chain);
65886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    }
65986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
660266bc8f7774b153401e54ed537db299159840981Scott Michel    Chain = SDOperand(Result, 1);
66186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel    AddToISelQueue(Chain);
66286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel
663266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
664266bc8f7774b153401e54ed537db299159840981Scott Michel  }
665266bc8f7774b153401e54ed537db299159840981Scott Michel
666266bc8f7774b153401e54ed537db299159840981Scott Michel  return SelectCode(Op);
667266bc8f7774b153401e54ed537db299159840981Scott Michel}
668266bc8f7774b153401e54ed537db299159840981Scott Michel
669266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a
670266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
671266bc8f7774b153401e54ed537db299159840981Scott Michel///
672266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
673266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
674266bc8f7774b153401e54ed537db299159840981Scott Michel}
675