1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines a pattern matching instruction selector for the Cell SPU,
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// converting from a legalized dag to a SPU-target dag.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPU.h"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUHazardRecognizers.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "SPUFrameLowering.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineConstantPool.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAG.h"
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAGISel.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/PseudoSourceValue.h"
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetOptions.h"
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/Statistic.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/GlobalValue.h"
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h"
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/LLVMContext.h"
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h"
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MathExtras.h"
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Compiler.h"
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h"
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace {
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isI32IntS10Immediate(ConstantSDNode *CN)
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return isInt<10>(CN->getSExtValue());
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isI32IntU10Immediate(ConstantSDNode *CN)
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return isUInt<10>(CN->getSExtValue());
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isI16IntS10Immediate(ConstantSDNode *CN)
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return isInt<10>(CN->getSExtValue());
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isI16IntU10Immediate(ConstantSDNode *CN)
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return isUInt<10>((short) CN->getZExtValue());
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantSDNode predicate for signed 16-bit values
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /*!
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    \arg CN The constant SelectionDAG node holding the value
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    \arg Imm The returned 16-bit value, if returning true
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    This predicate tests the value in \a CN to see whether it can be
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    represented as a 16-bit, sign-extended quantity. Returns true if
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    this is the case.
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman   */
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT vt = CN->getValueType(0);
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Imm = (short) CN->getZExtValue();
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (vt == MVT::i32) {
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int32_t i_val = (int32_t) CN->getZExtValue();
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      short s_val = (short) i_val;
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return i_val == s_val;
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int64_t i_val = (int64_t) CN->getZExtValue();
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      short s_val = (short) i_val;
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return i_val == s_val;
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static bool
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT vt = FPN->getValueType(0);
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (vt == MVT::f32) {
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int sval = (int) ((val << 16) >> 16);
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Imm = (short) val;
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return val == sval;
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! Generate the carry-generate shuffle mask.
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SmallVector<SDValue, 16 > ShufBytes;
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Create the shuffle mask for "rotating" the borrow up one register slot
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // once the borrow is generated.
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       &ShufBytes[0], ShufBytes.size());
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //! Generate the borrow-generate shuffle mask
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SmallVector<SDValue, 16 > ShufBytes;
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Create the shuffle mask for "rotating" the borrow up one register slot
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // once the borrow is generated.
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       &ShufBytes[0], ShufBytes.size());
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //===------------------------------------------------------------------===//
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// instructions for SelectionDAG operations.
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  class SPUDAGToDAGISel :
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    public SelectionDAGISel
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  {
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SPUTargetMachine &TM;
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SPUTargetLowering &SPUtli;
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned GlobalBaseReg;
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  public:
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SelectionDAGISel(tm),
157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      TM(tm),
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SPUtli(*tm.getTargetLowering())
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    { }
160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    virtual bool runOnMachineFunction(MachineFunction &MF) {
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Make sure we re-emit a set of the global base reg if necessary
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      GlobalBaseReg = 0;
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SelectionDAGISel::runOnMachineFunction(MF);
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// getI32Imm - Return a target constant with the specified value, of type
169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// i32.
170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    inline SDValue getI32Imm(uint32_t Imm) {
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->getTargetConstant(Imm, MVT::i32);
172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// getSmallIPtrImm - Return a target constant of pointer type.
175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    inline SDValue getSmallIPtrImm(unsigned Imm) {
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *emitBuildVector(SDNode *bvNode) {
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      EVT vecVT = bvNode->getValueType(0);
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      DebugLoc dl = bvNode->getDebugLoc();
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Check to see if this vector can be represented as a CellSPU immediate
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // constant by invoking all of the instruction selection predicates:
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (((vecVT == MVT::v8i16) &&
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          ((vecVT == MVT::v4i32) &&
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          ((vecVT == MVT::v2i64) &&
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        HandleSDNode Dummy(SDValue(bvNode, 0));
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (SDNode *N = Select(bvNode))
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return N;
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return Dummy.getValue().getNode();
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // No, need to emit a constant pool spill:
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      std::vector<Constant*> CV;
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i));
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      const Constant *CP = ConstantVector::get(CV);
211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue CGPoolOffset =
214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman              SPU::LowerConstantPool(CPIdx, *CurDAG, TM);
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                         CurDAG->getEntryNode(), CGPoolOffset,
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         MachinePointerInfo::getConstantPool(),
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                         false, false, Alignment));
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return N;
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return Dummy.getValue().getNode();
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// Select - Convert the specified operand from a target-independent to a
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// target-specific node if it hasn't already been changed.
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Select(SDNode *N);
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Emit the instruction sequence for i64 shl
231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Emit the instruction sequence for i64 srl
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Emit the instruction sequence for i64 sra
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Emit the necessary sequence for loading i64 constants:
240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Alternate instruction emit sequence for loading i64 constants
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Returns true if the address N is an A-form (local store) address
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         SDValue &Index);
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! D-form address predicate
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         SDValue &Index);
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// Alternate D-form address using i7 offset predicate
254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                          SDValue &Base);
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// D-form address selection workhorse
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue &Base, int minOffset, int maxOffset);
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //! Address predicate if N can be expressed as an indexed [r+r] operation.
262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                         SDValue &Index);
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// inline asm expressions.
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                              char ConstraintCode,
269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                              std::vector<SDValue> &OutOps) {
270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Op0, Op1;
271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      switch (ConstraintCode) {
272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      default: return true;
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case 'm':   // memory
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case 'o':   // offsetable
279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Op0 = Op;
282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Op1 = getSmallIPtrImm(0);
283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case 'v':   // not offsetable
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 1
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#else
289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        SelectAddrIdxOnly(Op, Op, Op0, Op1);
290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      OutOps.push_back(Op0);
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      OutOps.push_back(Op1);
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    virtual const char *getPassName() const {
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return "Cell SPU DAG->DAG Pattern Instruction Selection";
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  private:
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SDValue getRC( MVT );
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Include the pieces autogenerated from the target description.
307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUGenDAGISel.inc"
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  };
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Op The ISD instruction operand
313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg N The address to be tested
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Base The base address
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \arg Index The base address index
316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool
318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                    SDValue &Index) {
320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // These match the addr256k operand type:
321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT OffsVT = MVT::i16;
322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  int64_t val;
324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (N.getOpcode()) {
326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::Constant:
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    val = dyn_cast<ConstantSDNode>(N.getNode())->getSExtValue();
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Base = CurDAG->getTargetConstant( val , MVT::i32);
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Index = Zero;
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true; break;
331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::ConstantPool:
332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::GlobalAddress:
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    report_fatal_error("SPU SelectAFormAddr: Pool/Global not lowered.");
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /*NOTREACHED*/
335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::TargetConstant:
337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::TargetGlobalAddress:
338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case ISD::TargetJumpTable:
339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                      "not wrapped as A-form address.");
341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /*NOTREACHED*/
342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case SPUISD::AFormAddr:
344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Just load from memory if there's only a single use of the location,
345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // otherwise, this will get handled below with D-form offset addresses
346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (N.hasOneUse()) {
347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Op0 = N.getOperand(0);
348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      switch (Op0.getOpcode()) {
349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case ISD::TargetConstantPool:
350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case ISD::TargetJumpTable:
351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = Op0;
352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = Zero;
353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      case ISD::TargetGlobalAddress: {
356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        const GlobalValue *GV = GSDN->getGlobal();
358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (GV->getAlignment() == 16) {
359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Base = Op0;
360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Index = Zero;
361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return true;
362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        break;
364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool
373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SDValue &Base) {
375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const int minDForm2Offset = -(1 << 7);
376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const int maxDForm2Offset = (1 << 7) - 1;
377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               maxDForm2Offset);
379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Op The ISD instruction (ignored)
383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg N The address to be tested
384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Base Base address register/pointer
385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Index Base address index
386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Examine the input address by a base register plus a signed 10-bit
388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  displacement, [r+I10] (D-form address).
389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \return true if \a N is a D-form address with \a Base and \a Index set
391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  to non-empty SDValue instances.
392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/
393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool
394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 SDValue &Index) {
396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return DFormAddressPredicate(Op, N, Base, Index,
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               SPUFrameLowering::minFrameOffset(),
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               SPUFrameLowering::maxFrameOffset());
399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool
402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      SDValue &Index, int minOffset,
404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      int maxOffset) {
405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Opc = N.getOpcode();
406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT PtrTy = SPUtli.getPointerTy();
407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Opc == ISD::FrameIndex) {
409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Stack frame index must be less than 512 (divided by 16):
410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N);
411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int FI = int(FIN->getIndex());
412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               << FI << "\n");
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Base = CurDAG->getTargetConstant(0, PtrTy);
416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::ADD) {
420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Generated by getelementptr
421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SDValue Op0 = N.getOperand(0);
422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SDValue Op1 = N.getOperand(1);
423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Base = CurDAG->getTargetConstant(0, PtrTy);
427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Index = N;
428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (Op1.getOpcode() == ISD::Constant
430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               || Op1.getOpcode() == ISD::TargetConstant) {
431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int32_t offset = int32_t(CN->getSExtValue());
433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Op0.getOpcode() == ISD::FrameIndex) {
435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0);
436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        int FI = int(FIN->getIndex());
437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                   << " frame index = " << FI << "\n");
439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Base = CurDAG->getTargetConstant(offset, PtrTy);
442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return true;
444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else if (offset > minOffset && offset < maxOffset) {
446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = CurDAG->getTargetConstant(offset, PtrTy);
447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = Op0;
448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (Op0.getOpcode() == ISD::Constant
451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               || Op0.getOpcode() == ISD::TargetConstant) {
452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int32_t offset = int32_t(CN->getSExtValue());
454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Op1.getOpcode() == ISD::FrameIndex) {
456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1);
457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        int FI = int(FIN->getIndex());
458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                   << " frame index = " << FI << "\n");
460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Base = CurDAG->getTargetConstant(offset, PtrTy);
463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return true;
465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else if (offset > minOffset && offset < maxOffset) {
467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = CurDAG->getTargetConstant(offset, PtrTy);
468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = Op1;
469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == SPUISD::IndirectAddr) {
473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Indirect with constant offset -> D-Form address
474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SDValue Op0 = N.getOperand(0);
475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    const SDValue Op1 = N.getOperand(1);
476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Op0.getOpcode() == SPUISD::Hi
478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        && Op1.getOpcode() == SPUISD::Lo) {
479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Base = CurDAG->getTargetConstant(0, PtrTy);
481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Index = N;
482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int32_t offset = 0;
485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue idxOp;
486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (isa<ConstantSDNode>(Op1)) {
488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        offset = int32_t(CN->getSExtValue());
490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        idxOp = Op0;
491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else if (isa<ConstantSDNode>(Op0)) {
492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        offset = int32_t(CN->getSExtValue());
494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        idxOp = Op1;
495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (offset >= minOffset && offset <= maxOffset) {
498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = CurDAG->getTargetConstant(offset, PtrTy);
499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = idxOp;
500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == SPUISD::AFormAddr) {
504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Base = CurDAG->getTargetConstant(0, N.getValueType());
505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Index = N;
506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == SPUISD::LDRESULT) {
508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Base = CurDAG->getTargetConstant(0, N.getValueType());
509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Index = N;
510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (Opc == ISD::Register
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           ||Opc == ISD::CopyFromReg
513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           ||Opc == ISD::UNDEF
514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           ||Opc == ISD::Constant) {
515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned OpOpc = Op->getOpcode();
516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Direct load/store without getelementptr
519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Offs;
520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (Offs.getOpcode() == ISD::UNDEF)
525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = Offs;
528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = N;
529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      /* If otherwise unadorned, default to D-form address with 0 offset: */
533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Opc == ISD::CopyFromReg) {
534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = N.getOperand(1);
535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      } else {
536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Index = N;
537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Base = CurDAG->getTargetConstant(0, Index.getValueType());
540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Op The ISD instruction operand
549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg N The address operand
550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Base The base pointer operand
551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  \arg Index The offset/index operand
552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  If the address \a N can be expressed as an A-form or D-form address, returns
554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  false.  Otherwise, creates two operands, Base and Index that will become the
555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  (r)(r) X-form address.
556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman*/
557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool
558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 SDValue &Index) {
560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!SelectAFormAddr(Op, N, Base, Index)
561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      && !SelectDFormAddr(Op, N, Base, Index)) {
562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // If the address is neither A-form or D-form, punt and use an X-form
563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // address:
564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Base = N.getOperand(1);
565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Index = N.getOperand(0);
566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return false;
570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*!
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman to be used as the last parameter of a
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman \arg VT the value type for which we want a register class
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman*/
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue SPUDAGToDAGISel::getRC( MVT VT ) {
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch( VT.SimpleTy ) {
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::i8:
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32);
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::i16:
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32);
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::i32:
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32);
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::f32:
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32);
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::i64:
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32);
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::i128:
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32);
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v16i8:
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v8i16:
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v4i32:
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v4f32:
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v2i64:
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case MVT::v2f64:
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32);
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert( false && "add a new case here" );
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return SDValue();
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Convert the operand from a target-independent to a target-specific node
613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *
616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::Select(SDNode *N) {
617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Opc = N->getOpcode();
618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  int n_ops = -1;
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NewOpc = 0;
620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT OpVT = N->getValueType(0);
621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue Ops[8];
622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc dl = N->getDebugLoc();
623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (N->isMachineOpcode())
625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return NULL;   // Already selected.
626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Opc == ISD::FrameIndex) {
628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    int FI = cast<FrameIndexSDNode>(N)->getIndex();
629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (FI < 128) {
633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      NewOpc = SPU::AIr32;
634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[0] = TFI;
635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[1] = Imm0;
636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      n_ops = 2;
637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else {
638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      NewOpc = SPU::Ar32;
639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              N->getValueType(0), TFI),
642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       0);
643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      n_ops = 2;
644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Catch the i64 constants that end up here. Note: The backend doesn't
647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // attempt to legalize the constant (it's useless because DAGCombiner
648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // will insert 64-bit constants and we can't stop it).
649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SelectI64Constant(N, OpVT, N->getDebugLoc());
650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             && OpVT == MVT::i64) {
652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op0 = N->getOperand(0);
653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT Op0VT = Op0.getValueType();
654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    Op0VT, (128 / Op0VT.getSizeInBits()));
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   OpVT, (128 / OpVT.getSizeInBits()));
658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue shufMask;
659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (Op0VT.getSimpleVT().SimpleTy) {
661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT");
663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      /*NOTREACHED*/
664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case MVT::i32:
665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x00010203, MVT::i32),
668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case MVT::i16:
673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80800203, MVT::i32),
676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case MVT::i8:
681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808003, MVT::i32),
684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x80808080, MVT::i32),
685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                 CurDAG->getConstant(0x8080800b, MVT::i32));
686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                               Op0VecVT, Op0));
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue PromScalar;
695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      PromScalar = SDValue(N, 0);
697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else
698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      PromScalar = PromoteScalar.getValue();
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue zextShuffle =
701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            PromScalar, PromScalar,
703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                            SDValue(shufMaskLoad, 0));
704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy2(zextShuffle);
706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      zextShuffle = SDValue(N, 0);
708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else
709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      zextShuffle = Dummy2.getValue();
710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       zextShuffle));
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SelectCode(Dummy.getValue().getNode());
715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Dummy.getValue().getNode();
716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *CGLoad =
718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       N->getOperand(0), N->getOperand(1),
722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       SDValue(CGLoad, 0)));
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return N;
727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Dummy.getValue().getNode();
728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *CGLoad =
730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       N->getOperand(0), N->getOperand(1),
734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       SDValue(CGLoad, 0)));
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return N;
739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Dummy.getValue().getNode();
740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *CGLoad =
742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       N->getOperand(0), N->getOperand(1),
746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       SDValue(CGLoad, 0)));
747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return N;
750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Dummy.getValue().getNode();
751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::TRUNCATE) {
752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op0 = N->getOperand(0);
753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        && OpVT == MVT::i32
755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        && Op0.getValueType() == MVT::i64) {
756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      //
758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // Take advantage of the fact that the upper 32 bits are in the
759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // i32 preferred slot and avoid shuffle gymnastics:
760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (CN != 0) {
762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        unsigned shift_amt = unsigned(CN->getZExtValue());
763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (shift_amt >= 32) {
765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          SDNode *hi32 =
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         Op0.getOperand(0), getRC(MVT::i32));
768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          shift_amt -= 32;
770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          if (shift_amt > 0) {
771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            // Take care of the additional shift, if present:
772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            unsigned Opc = SPU::ROTMAIr32_i32;
774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            if (Op0.getOpcode() == ISD::SRL)
776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman              Opc = SPU::ROTMr32;
777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                          shift);
780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          }
781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return hi32;
783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::SHL) {
787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpVT == MVT::i64)
788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return SelectSHLi64(N, OpVT);
789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::SRL) {
790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpVT == MVT::i64)
791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return SelectSRLi64(N, OpVT);
792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::SRA) {
793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpVT == MVT::i64)
794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return SelectSRAi64(N, OpVT);
795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::FNEG
796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DebugLoc dl = N->getDebugLoc();
798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Check if the pattern is a special form of DFNMS:
799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op0 = N->getOperand(0);
801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (Op0.getOpcode() == ISD::FSUB) {
802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Op00 = Op0.getOperand(0);
803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Op00.getOpcode() == ISD::FMUL) {
804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        unsigned Opc = SPU::DFNMSf64;
805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (OpVT == MVT::v2f64)
806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Opc = SPU::DFNMSv2f64;
807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return CurDAG->getMachineNode(Opc, dl, OpVT,
809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      Op00.getOperand(0),
810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      Op00.getOperand(1),
811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                      Op0.getOperand(1));
812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *signMask = 0;
817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned Opc = SPU::XORfneg64;
818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpVT == MVT::f64) {
820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (OpVT == MVT::v2f64) {
822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Opc = SPU::XORfnegvec;
823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                 MVT::v2i64,
825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                 negConst, negConst).getNode());
826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return CurDAG->getMachineNode(Opc, dl, OpVT,
829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  N->getOperand(0), SDValue(signMask, 0));
830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == ISD::FABS) {
831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (OpVT == MVT::f64) {
832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    N->getOperand(0), SDValue(signMask, 0));
835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    } else if (OpVT == MVT::v2f64) {
836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                       absConst, absConst);
839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDNode *signMask = emitBuildVector(absVec.getNode());
840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    N->getOperand(0), SDValue(signMask, 0));
842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == SPUISD::LDRESULT) {
844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Custom select instructions for LDRESULT
845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT VT = N->getValueType(0);
846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Arg = N->getOperand(0);
847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Chain = N->getOperand(1);
848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Result;
849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT,
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    MVT::Other, Arg,
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    getRC( VT.getSimpleVT()), Chain);
853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return Result;
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (Opc == SPUISD::IndirectAddr) {
856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Look at the operands: SelectCode() will catch the cases that aren't
857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // specifically handled here.
858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //
859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // SPUInstrInfo catches the following patterns:
860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // (SPUindirect (SPUhi ...), (SPUlo ...))
861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // (SPUindirect $sp, imm)
862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    EVT VT = N->getValueType(0);
863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op0 = N->getOperand(0);
864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op1 = N->getOperand(1);
865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    RegisterSDNode *RN;
866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        || (Op0.getOpcode() == ISD::Register
869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                && RN->getReg() != SPU::R1))) {
871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      NewOpc = SPU::Ar32;
872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[1] = Op1;
873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Op1.getOpcode() == ISD::Constant) {
874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (isInt<10>(CN->getSExtValue())) {
877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          NewOpc = SPU::AIr32;
878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          Ops[1] = Op1;
879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        } else {
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl,
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                  N->getValueType(0),
882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                  Op1),
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           0);
884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        }
885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Ops[0] = Op0;
887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      n_ops = 2;
888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (n_ops > 0) {
892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (N->hasOneUse())
893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    else
895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else
897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SelectCode(N);
898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 left shifts. The basic algorithm
902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * is to fill the bottom two word slots with zeros so that zeros are shifted
903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * in as the entire quadword is shifted left.
904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *
905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * \note This code could also be used to implement v2i64 shl.
906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *
907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand
908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but
909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.)
910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence
911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *
913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue Op0 = N->getOperand(0);
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               OpVT, (128 / OpVT.getSizeInBits()));
917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue ShiftAmt = N->getOperand(1);
918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT ShiftAmtVT = ShiftAmt.getValueType();
919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue SelMaskVal;
921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc dl = N->getDebugLoc();
922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  Op0, getRC(MVT::v2i64) );
925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                    CurDAG->getTargetConstant(0, OpVT));
929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SDValue(ZeroFill, 0),
931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SDValue(VecOp0, 0),
932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SDValue(SelMask, 0));
933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bits = unsigned(CN->getZExtValue()) & 7;
937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bytes > 0) {
939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue(VecOp0, 0),
942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bits > 0) {
946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Bytes =
953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             ShiftAmt,
955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Bits =
957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             ShiftAmt,
959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(Shift, 0), SDValue(Bits, 0));
966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 logical right shifts.
974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *
975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand
976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but
977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.)
978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence
979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *
981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue Op0 = N->getOperand(0);
983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               OpVT, (128 / OpVT.getSizeInBits()));
985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue ShiftAmt = N->getOperand(1);
986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT ShiftAmtVT = ShiftAmt.getValueType();
987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *VecOp0, *Shift = 0;
988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc dl = N->getDebugLoc();
989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  Op0, getRC(MVT::v2i64) );
992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bits = unsigned(CN->getZExtValue()) & 7;
996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bytes > 0) {
998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue(VecOp0, 0),
1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
1002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bits > 0) {
1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Bytes =
1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             ShiftAmt,
1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *Bits =
1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             ShiftAmt,
1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Ensure that the shift amounts are negated!
1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   SDValue(Bytes, 0),
1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  SDValue(Bits, 0),
1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(Shift, 0), SDValue(Bits, 0));
1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * Emit the instruction sequence for i64 arithmetic right shifts.
1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *
1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param Op The shl operand
1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @param OpVT Op's machine value value type (doesn't need to be passed, but
1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * makes life easier.)
1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman * @return The SDNode with the entire instruction sequence
1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *
1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Promote Op0 to vector
105219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               OpVT, (128 / OpVT.getSizeInBits()));
1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue ShiftAmt = N->getOperand(1);
1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT ShiftAmtVT = ShiftAmt.getValueType();
1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc dl = N->getDebugLoc();
1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *VecOp0 =
105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           VecVT, N->getOperand(0), getRC(MVT::v2i64));
1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *SignRot =
1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           SDValue(VecOp0, 0), SignRotAmt);
1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *UpperHalfSign =
106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32));
1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *UpperHalfSignMask =
1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *UpperLowerMask =
1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *UpperLowerSelect =
1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           SDValue(UpperHalfSignMask, 0),
1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           SDValue(VecOp0, 0),
1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                           SDValue(UpperLowerMask, 0));
1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *Shift = 0;
1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    unsigned bits = unsigned(CN->getZExtValue()) & 7;
1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bytes > 0) {
1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      bytes = 31 - bytes;
1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue(UpperLowerSelect, 0),
1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (bits > 0) {
1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      bits = 8 - bits;
1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Shift =
1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *NegShift =
1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    Shift =
1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                             SDValue(Shift, 0), SDValue(NegShift, 0));
1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*!
1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Do the necessary magic necessary to load a i64 constant
1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */
1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           DebugLoc dl) {
1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ConstantSDNode *CN = cast<ConstantSDNode>(N);
1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                           DebugLoc dl) {
1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDValue i64vec =
1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Here's where it gets interesting, because we have to parse out the
1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // subtree handed back in i64vec:
1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (i64vec.getOpcode() == ISD::BITCAST) {
1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // The degenerate case where the upper and lower bits in the splat are
1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // identical:
1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue Op0 = i64vec.getOperand(0);
1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ReplaceUses(i64vec, Op0);
114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  SDValue(emitBuildVector(Op0.getNode()), 0),
114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  getRC(MVT::i64));
1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue lhs = i64vec.getOperand(0);
1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue rhs = i64vec.getOperand(1);
1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDValue shufmask = i64vec.getOperand(2);
1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (lhs.getOpcode() == ISD::BITCAST) {
1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ReplaceUses(lhs, lhs.getOperand(0));
1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      lhs = lhs.getOperand(0);
1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       ? lhs.getNode()
1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       : emitBuildVector(lhs.getNode()));
1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (rhs.getOpcode() == ISD::BITCAST) {
1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ReplaceUses(rhs, rhs.getOperand(0));
1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      rhs = rhs.getOperand(0);
1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       ? rhs.getNode()
1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       : emitBuildVector(rhs.getNode()));
1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (shufmask.getOpcode() == ISD::BITCAST) {
1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ReplaceUses(shufmask, shufmask.getOperand(0));
1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      shufmask = shufmask.getOperand(0);
1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                            ? shufmask.getNode()
1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                            : emitBuildVector(shufmask.getNode()));
1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman   SDValue shufNode =
1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                   SDValue(shufMaskNode, 0));
1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    HandleSDNode Dummy(shufNode);
1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    SDNode *SN = SelectCode(Dummy.getValue().getNode());
1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if (SN == 0) SN = Dummy.getValue().getNode();
118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  OpVT, SDValue(SN, 0), getRC(MVT::i64));
1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  SDValue(emitBuildVector(i64vec.getNode()), 0),
119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  getRC(MVT::i64));
1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                      "condition");
1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// createSPUISelDag - This pass converts a legalized DAG into a
1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SPU-specific DAG, ready for instruction scheduling.
1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return new SPUDAGToDAGISel(TM);
1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
1204