SPUISelDAGToDAG.cpp revision 11edd0cedc98cda93681a6e9779f542c7354ec86
14ee451de366474b9c228b4e5fa573795a715216dChris Lattner//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===//
2266bc8f7774b153401e54ed537db299159840981Scott Michel//
3266bc8f7774b153401e54ed537db299159840981Scott Michel//                     The LLVM Compiler Infrastructure
4266bc8f7774b153401e54ed537db299159840981Scott Michel//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7266bc8f7774b153401e54ed537db299159840981Scott Michel//
8266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
9266bc8f7774b153401e54ed537db299159840981Scott Michel//
10266bc8f7774b153401e54ed537db299159840981Scott Michel// This file defines a pattern matching instruction selector for the Cell SPU,
11266bc8f7774b153401e54ed537db299159840981Scott Michel// converting from a legalized dag to a SPU-target dag.
12266bc8f7774b153401e54ed537db299159840981Scott Michel//
13266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===//
14266bc8f7774b153401e54ed537db299159840981Scott Michel
15266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPU.h"
16266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUTargetMachine.h"
17266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h"
18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h"
19203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h"
2094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h"
21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h"
22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h"
23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h"
24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h"
25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h"
2694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h"
27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
32a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h"
33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
35266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
37dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
38266bc8f7774b153401e54ed537db299159840981Scott Michel
39266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
40266bc8f7774b153401e54ed537db299159840981Scott Michel
41266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
42266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
43266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
44266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
45266bc8f7774b153401e54ed537db299159840981Scott Michel  {
467e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
47266bc8f7774b153401e54ed537db299159840981Scott Michel  }
48266bc8f7774b153401e54ed537db299159840981Scott Michel
49504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
50504c369213efb263136bb048e79af3516511c040Scott Michel  bool
51504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
52504c369213efb263136bb048e79af3516511c040Scott Michel  {
5334247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>(CN->getSExtValue());
54504c369213efb263136bb048e79af3516511c040Scott Michel  }
55504c369213efb263136bb048e79af3516511c040Scott Michel
56266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
57266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
58266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
59266bc8f7774b153401e54ed537db299159840981Scott Michel  {
607e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
61266bc8f7774b153401e54ed537db299159840981Scott Michel  }
62266bc8f7774b153401e54ed537db299159840981Scott Michel
63ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
64ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
65ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
66ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
6734247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>((short) CN->getZExtValue());
68ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
69ec2a08ff061af36b46160e475362959f21663e76Scott Michel
70266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
71266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
72266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
73266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
74266bc8f7774b153401e54ed537db299159840981Scott Michel
75266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
76266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
77266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
78266bc8f7774b153401e54ed537db299159840981Scott Michel   */
79266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
80266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
81266bc8f7774b153401e54ed537db299159840981Scott Michel  {
82e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = CN->getValueType(0);
83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
85266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
86825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (vt == MVT::i32) {
87f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
88266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
89266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
90266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
91f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
92266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
93266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
94266bc8f7774b153401e54ed537db299159840981Scott Michel    }
95266bc8f7774b153401e54ed537db299159840981Scott Michel
96266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
97266bc8f7774b153401e54ed537db299159840981Scott Michel  }
98266bc8f7774b153401e54ed537db299159840981Scott Michel
99266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
100266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
101266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
102266bc8f7774b153401e54ed537db299159840981Scott Michel  {
103e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = FPN->getValueType(0);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt == MVT::f32) {
105d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
106266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
107266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
108266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
109266bc8f7774b153401e54ed537db299159840981Scott Michel    }
110266bc8f7774b153401e54ed537db299159840981Scott Michel
111266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
112266bc8f7774b153401e54ed537db299159840981Scott Michel  }
113266bc8f7774b153401e54ed537db299159840981Scott Michel
1147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the carry-generate shuffle mask.
1157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
117844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
1187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
12402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
127266bc8f7774b153401e54ed537db299159840981Scott Michel  }
128266bc8f7774b153401e54ed537db299159840981Scott Michel
1297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the borrow-generate shuffle mask
1307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
1327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
1397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
142266bc8f7774b153401e54ed537db299159840981Scott Michel  }
14302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //===------------------------------------------------------------------===//
1457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
1467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// instructions for SelectionDAG operations.
1477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  ///
1487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  class SPUDAGToDAGISel :
1497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    public SelectionDAGISel
1507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  {
151d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetMachine &TM;
152d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetLowering &SPUtli;
1537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    unsigned GlobalBaseReg;
1547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  public:
1567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
1577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SelectionDAGISel(tm),
1587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      TM(tm),
1597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SPUtli(*tm.getTargetLowering())
1607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    { }
1617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
162ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman    virtual bool runOnMachineFunction(MachineFunction &MF) {
1637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Make sure we re-emit a set of the global base reg if necessary
1647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      GlobalBaseReg = 0;
165ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman      SelectionDAGISel::runOnMachineFunction(MF);
1667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return true;
167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
168266bc8f7774b153401e54ed537db299159840981Scott Michel
1697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI32Imm - Return a target constant with the specified value, of type
1707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i32.
1717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI32Imm(uint32_t Imm) {
172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i32);
17394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    }
17494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
1757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getSmallIPtrImm - Return a target constant of pointer type.
1767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getSmallIPtrImm(unsigned Imm) {
1777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
17817aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner    }
1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
180eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *emitBuildVector(SDNode *bvNode) {
181eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      EVT vecVT = bvNode->getValueType(0);
1827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      DebugLoc dl = bvNode->getDebugLoc();
1837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Check to see if this vector can be represented as a CellSPU immediate
1857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // constant by invoking all of the instruction selection predicates:
186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (((vecVT == MVT::v8i16) &&
187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v4i32) &&
189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
191825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
1927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
193825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v2i64) &&
194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
195825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
196a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
197a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        HandleSDNode Dummy(SDValue(bvNode, 0));
198a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        if (SDNode *N = Select(bvNode))
199a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner          return N;
200a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return Dummy.getValue().getNode();
201a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      }
2027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // No, need to emit a constant pool spill:
2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      std::vector<Constant*> CV;
2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
206eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
207b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i));
208a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
21146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman      const Constant *CP = ConstantVector::get(CV);
2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
2147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CGPoolOffset =
215d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman              SPU::LowerConstantPool(CPIdx, *CurDAG, TM);
216bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
217a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
218a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         CurDAG->getEntryNode(), CGPoolOffset,
219e8639036b1fb3a5b5e9589fe4e9f2ee1b77c36bdChris Lattner                                         MachinePointerInfo::getConstantPool(),
220a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         false, false, Alignment));
221a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
222a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
223a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return N;
224a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return Dummy.getValue().getNode();
2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Select - Convert the specified operand from a target-independent to a
2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// target-specific node if it hasn't already been changed.
229eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *Select(SDNode *N);
2307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 shl
232eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 srl
235eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
2367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 sra
238eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the necessary sequence for loading i64 constants:
241eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Alternate instruction emit sequence for loading i64 constants
244e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Returns true if the address N is an A-form (local store) address
247eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! D-form address predicate
251eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Alternate D-form address using i7 offset predicate
255eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                          SDValue &Base);
2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// D-form address selection workhorse
259eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                               SDValue &Base, int minOffset, int maxOffset);
2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Address predicate if N can be expressed as an indexed [r+r] operation.
263eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// inline asm expressions.
2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              char ConstraintCode,
2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              std::vector<SDValue> &OutOps) {
2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op0, Op1;
2727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      switch (ConstraintCode) {
2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      default: return true;
2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'm':   // memory
275eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
276eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
277eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman          SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'o':   // offsetable
280eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
281eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op0 = Op;
2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op1 = getSmallIPtrImm(0);
2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        }
2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'v':   // not offsetable
287266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
288c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
289266bc8f7774b153401e54ed537db299159840981Scott Michel#else
2907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        SelectAddrIdxOnly(Op, Op, Op0, Op1);
291266bc8f7774b153401e54ed537db299159840981Scott Michel#endif
2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
29402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op0);
2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op1);
2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return false;
2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
299266bc8f7774b153401e54ed537db299159840981Scott Michel
3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual const char *getPassName() const {
3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return "Cell SPU DAG->DAG Pattern Instruction Selection";
3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
30302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// this target when scheduling the DAG.
3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      const TargetInstrInfo *II = TM.getInstrInfo();
3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      assert(II && "No InstrInfo?");
3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return new SPUHazardRecognizer(*II);
3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
311bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
3121cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  private:
313bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    SDValue getRC( MVT );
314266bc8f7774b153401e54ed537db299159840981Scott Michel
3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Include the pieces autogenerated from the target description.
316266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  };
318844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
319844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
320266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
3219de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand
322266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
323266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
324266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
325266bc8f7774b153401e54ed537db299159840981Scott Michel */
326266bc8f7774b153401e54ed537db299159840981Scott Michelbool
327eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
328475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
329266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT OffsVT = MVT::i16;
331475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
332266bc8f7774b153401e54ed537db299159840981Scott Michel
333266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
334266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3359de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3369de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
33775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered.");
3389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3399de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
340053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
342053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
34375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
344dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "not wrapped as A-form address.");
345053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
346266bc8f7774b153401e54ed537db299159840981Scott Michel
34702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  case SPUISD::AFormAddr:
348053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
349053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
350053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
351475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
352053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
353053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
354053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
355053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
356053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
357053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
358053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
359053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
360053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
36146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = GSDN->getGlobal();
362053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
363053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
364053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
365053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
366053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
367053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
368053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
369053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
370053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
371053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
372053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
373266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
374266bc8f7774b153401e54ed537db299159840981Scott Michel}
375266bc8f7774b153401e54ed537db299159840981Scott Michel
37602d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool
377eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
378475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
379203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
380203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
381203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
382203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
3837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
3847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
385266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
386266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
387266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
388266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
389266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
390266bc8f7774b153401e54ed537db299159840981Scott Michel
391266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
392266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
393266bc8f7774b153401e54ed537db299159840981Scott Michel
394266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
395475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
396266bc8f7774b153401e54ed537db299159840981Scott Michel*/
397266bc8f7774b153401e54ed537db299159840981Scott Michelbool
398eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
399475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
4007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
4019c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::minFrameOffset(),
4029c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel                               SPUFrameInfo::maxFrameOffset());
4037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
4047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
406eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
407475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
409266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
410e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT PtrTy = SPUtli.getPointerTy();
411266bc8f7774b153401e54ed537db299159840981Scott Michel
412053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
413053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
414b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman    FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N);
415203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
4164437ae213d5435390f0750213b53ec807c047f22Chris Lattner    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
417203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
418203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
419266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
420203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
421266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
422266bc8f7774b153401e54ed537db299159840981Scott Michel    }
423266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
424266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
425475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
426475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
427266bc8f7774b153401e54ed537db299159840981Scott Michel
428053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
429053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
430053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
431053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
432053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
433053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
434053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
435b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4367810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
437266bc8f7774b153401e54ed537db299159840981Scott Michel
438053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
439b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0);
440203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4414437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
442203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
444203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
446203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4479de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4509de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
451053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
452053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
453053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
454053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
456b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4577810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
458053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
460b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1);
461203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4624437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
463203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
465203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
467203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
474266bc8f7774b153401e54ed537db299159840981Scott Michel      }
475497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
480053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
4817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
4827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
4849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
485053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
4869de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
4877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
4887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
489475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4917f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
4927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4937810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
4957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
4967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4977810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
49902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      }
5007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
5017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
5027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
5037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
5047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
5069de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
51058c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
515bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  } else if (Opc == ISD::Register
516bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck           ||Opc == ISD::CopyFromReg
517bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::UNDEF
518bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::Constant) {
519eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    unsigned OpOpc = Op->getOpcode();
5209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
5229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
52311fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila      SDValue Offs;
5249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
525eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
5269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
5289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
5299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
5309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
53211fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila        Index = N;
5339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
5349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
535aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
536aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
537aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
53819c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N.getOperand(1);
539aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
54019c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N;
541aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
542aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
543aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
544aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
5459c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
546266bc8f7774b153401e54ed537db299159840981Scott Michel  }
5479c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
548266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
549266bc8f7774b153401e54ed537db299159840981Scott Michel}
550266bc8f7774b153401e54ed537db299159840981Scott Michel
551266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
552266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
553266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
554266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
555266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
556266bc8f7774b153401e54ed537db299159840981Scott Michel
5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
5589c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
5599c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
560266bc8f7774b153401e54ed537db299159840981Scott Michel*/
561266bc8f7774b153401e54ed537db299159840981Scott Michelbool
562eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
563475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
5649c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
5659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
56618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
56718fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
5681a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
5691a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
57050843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
5719c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
572266bc8f7774b153401e54ed537db299159840981Scott Michel
5739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
57458c5818c01e375a84dc601140470fa68638004cfScott Michel}
57558c5818c01e375a84dc601140470fa68638004cfScott Michel
5761cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*!
577bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue
5781cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a
5791cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call
5801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class
5811cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/
5821cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) {
5831cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  switch( VT.SimpleTy ) {
584218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i8:
585bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32);
586bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    break;
587218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i16:
588bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32);
589bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    break;
5901cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i32:
591bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32);
592bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    break;
593218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::f32:
594bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32);
595bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    break;
5961cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i64:
597bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32);
5981cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    break;
59911edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila  case MVT::i128:
60011edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila    return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32);
60111edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila    break;
602218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v16i8:
603218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v8i16:
604218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4i32:
605218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4f32:
6061cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::v2i64:
607218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v2f64:
608bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32);
6091cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    break;
6101cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  default:
6111cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    assert( false && "add a new case here" );
6121cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  }
6131cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  return SDValue();
6141cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila}
6151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila
616266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
617266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
618266bc8f7774b153401e54ed537db299159840981Scott Michel */
619266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
620eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) {
621266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
62258c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
62358c5818c01e375a84dc601140470fa68638004cfScott Michel  unsigned NewOpc;
624eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  EVT OpVT = N->getValueType(0);
625475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
626ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = N->getDebugLoc();
627266bc8f7774b153401e54ed537db299159840981Scott Michel
628a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner  if (N->isMachineOpcode())
629266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
630c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
631c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (Opc == ISD::FrameIndex) {
63202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
633eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
634eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
63502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
63602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (FI < 128) {
637203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
63802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = TFI;
63902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[1] = Imm0;
640203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
641203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
642203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
643eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
644602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
645eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                              N->getValueType(0), TFI, Imm0),
646602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                       0);
647203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
648203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
649825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
650c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // Catch the i64 constants that end up here. Note: The backend doesn't
651c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // attempt to legalize the constant (it's useless because DAGCombiner
652c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // will insert 64-bit constants and we can't stop it).
653eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectI64Constant(N, OpVT, N->getDebugLoc());
65494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
655825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && OpVT == MVT::i64) {
656eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
657e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT Op0VT = Op0.getValueType();
65823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
65923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                    Op0VT, (128 / Op0VT.getSizeInBits()));
660bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
66123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                   OpVT, (128 / OpVT.getSizeInBits()));
66294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue shufMask;
66394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
664825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    switch (Op0VT.getSimpleVT().SimpleTy) {
66594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    default:
66675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner      report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT");
66794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      /*NOTREACHED*/
668825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i32:
669825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
670825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
671825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x00010203, MVT::i32),
672825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
673825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
67494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
67594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
676825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i16:
677825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
678825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
679825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800203, MVT::i32),
680825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
68294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
68394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
684825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i8:
685825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
686825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
687825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808003, MVT::i32),
688825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
689825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x8080800b, MVT::i32));
69094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
69158c5818c01e375a84dc601140470fa68638004cfScott Michel    }
69294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
693eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
694bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
695a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
696a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                               Op0VecVT, Op0));
697bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
698a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDValue PromScalar;
699a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
700a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = SDValue(N, 0);
701a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
702a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = PromoteScalar.getValue();
703bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
70494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue zextShuffle =
705ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
706bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                            PromScalar, PromScalar,
707d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(shufMaskLoad, 0));
70894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
709a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy2(zextShuffle);
710a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
711a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = SDValue(N, 0);
712a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
713a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = Dummy2.getValue();
714a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
715a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       zextShuffle));
716bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
717a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
718a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SelectCode(Dummy.getValue().getNode());
719a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
720825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
72194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *CGLoad =
722eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
723d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
724a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
725a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
727bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
729a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
730a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
731a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
732825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
733d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
734eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
735d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
736a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
737a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
739bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
740a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
741a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
742a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
743a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
745d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
746eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
747d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
748a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
749a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
750a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
751a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
752a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
753a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
754a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
755c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (Opc == ISD::TRUNCATE) {
756eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
757c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
758825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && OpVT == MVT::i32
759825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && Op0.getValueType() == MVT::i64) {
7609de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
7619de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      //
7629de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Take advantage of the fact that the upper 32 bits are in the
7639de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // i32 preferred slot and avoid shuffle gymnastics:
764c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
765c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      if (CN != 0) {
766c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        unsigned shift_amt = unsigned(CN->getZExtValue());
767c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
768c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        if (shift_amt >= 32) {
769c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          SDNode *hi32 =
7701cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                  CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
7711cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                         Op0.getOperand(0), getRC(MVT::i32));
772c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
773c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          shift_amt -= 32;
774c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          if (shift_amt > 0) {
775c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            // Take care of the additional shift, if present:
776825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
777c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            unsigned Opc = SPU::ROTMAIr32_i32;
7789de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
779c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            if (Op0.getOpcode() == ISD::SRL)
780c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel              Opc = SPU::ROTMr32;
781c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
782602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
783602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                          shift);
784c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          }
785c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
786c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          return hi32;
787c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        }
788c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      }
789c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
79002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SHL) {
791a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
792eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSHLi64(N, OpVT);
79302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRL) {
794a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
795eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRLi64(N, OpVT);
79602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRA) {
797a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
798eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRAi64(N, OpVT);
7997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FNEG
800825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
801eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    DebugLoc dl = N->getDebugLoc();
8027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Check if the pattern is a special form of DFNMS:
8037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
804eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
8057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    if (Op0.getOpcode() == ISD::FSUB) {
8067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op00 = Op0.getOperand(0);
8077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      if (Op00.getOpcode() == ISD::FMUL) {
8087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        unsigned Opc = SPU::DFNMSf64;
809825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        if (OpVT == MVT::v2f64)
8107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Opc = SPU::DFNMSv2f64;
8117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
812602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        return CurDAG->getMachineNode(Opc, dl, OpVT,
813602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(0),
814602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(1),
815602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op0.getOperand(1));
8167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
8177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
819825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
8207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *signMask = 0;
821a82d3f7c57f03457c385add1687319d5c290f867Scott Michel    unsigned Opc = SPU::XORfneg64;
8227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
823825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
824eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
825825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
826a82d3f7c57f03457c385add1687319d5c290f867Scott Michel      Opc = SPU::XORfnegvec;
8277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
828825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                                 MVT::v2i64,
829eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                                 negConst, negConst).getNode());
8307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
832602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(Opc, dl, OpVT,
833eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                  N->getOperand(0), SDValue(signMask, 0));
8347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FABS) {
835825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
836825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
837602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
838eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
839825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
840825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
841825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
8427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                       absConst, absConst);
843eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      SDNode *signMask = emitBuildVector(absVec.getNode());
844602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
845eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
8467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
847266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
848266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
849e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = N->getValueType(0);
850475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
851475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
852266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
853bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
8548258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila    Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT,
8558258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    MVT::Other, Arg,
8568258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    getRC( VT.getSimpleVT()), Chain);
857266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
858bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
859053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
860f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // Look at the operands: SelectCode() will catch the cases that aren't
861f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // specifically handled here.
862f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    //
863f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // SPUInstrInfo catches the following patterns:
864f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect (SPUhi ...), (SPUlo ...))
865f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect $sp, imm)
866eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    EVT VT = N->getValueType(0);
867f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op0 = N->getOperand(0);
868f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op1 = N->getOperand(1);
869f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    RegisterSDNode *RN;
870f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel
871f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
872f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        || (Op0.getOpcode() == ISD::Register
873f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
874f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel                && RN->getReg() != SPU::R1))) {
875f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      NewOpc = SPU::Ar32;
876d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner      Ops[1] = Op1;
87758c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
87858c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
879f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
880d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        if (isInt<10>(CN->getSExtValue())) {
881d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          NewOpc = SPU::AIr32;
882d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          Ops[1] = Op1;
883d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        } else {
884bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck          Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl,
885bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                                                  N->getValueType(0),
886d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                                                  Op1),
887bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                           0);
888d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        }
88958c5818c01e375a84dc601140470fa68638004cfScott Michel      }
890f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[0] = Op0;
891f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      n_ops = 2;
89258c5818c01e375a84dc601140470fa68638004cfScott Michel    }
893266bc8f7774b153401e54ed537db299159840981Scott Michel  }
89402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
89558c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
89658c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
89758c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
89858c5818c01e375a84dc601140470fa68638004cfScott Michel    else
899602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
90058c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
901eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectCode(N);
902266bc8f7774b153401e54ed537db299159840981Scott Michel}
903266bc8f7774b153401e54ed537db299159840981Scott Michel
90402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
90502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm
90602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted
90702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left.
90802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
90902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl.
91002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
91102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
91202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
91302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
91402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
91502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
91602d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
917eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
918eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
919bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
92023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
921eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
922e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
92302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
92402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SelMaskVal;
925eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
92602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9271cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9281cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
929825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
930602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
931602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
932602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    CurDAG->getTargetConstant(0, OpVT));
933602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
934602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(ZeroFill, 0),
935602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(VecOp0, 0),
936602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(SelMask, 0));
93702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
93802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
93902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
94002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
94102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
94202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
94302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
944602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
945602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
946602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
94702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
94802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
94902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
951602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
952602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
953602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
95402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
95502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
957602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
958602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
959602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
961602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
962602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
963602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
965602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
966602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
968602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
969602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
97002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
97102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
972bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
9731cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
97402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
97502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
97602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts.
97802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
98102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
98402d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
985eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
986eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
98723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
98823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
989eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
990e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *Shift = 0;
992eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9941cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9951cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
99602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
100002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
100102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
100202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1003602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
1004602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
1005602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
100602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
100702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
100802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1010602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
101502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1017602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1018602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1021602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1022602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
102302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    // Ensure that the shift amounts are negated!
1025602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1026602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   SDValue(Bytes, 0),
1027602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1029602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1030602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(Bits, 0),
1031602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1034602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1035602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1037602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1038602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
103902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1041bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10421cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
104402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
104602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts.
104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
104802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
105302d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1054eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  // Promote Op0 to vector
1056bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
105723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
1058eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
1059e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
1060eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0 =
1063bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10641cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           VecVT, N->getOperand(0), getRC(MVT::v2i64));
106502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *SignRot =
1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0), SignRotAmt);
107002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSign =
1071bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10721cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32));
107302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSignMask =
1075602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerMask =
1077602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerSelect =
1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperHalfSignMask, 0),
1082602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0),
1083602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperLowerMask, 0));
108402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *Shift = 0;
108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
108802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bytes = 31 - bytes;
109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1095602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(UpperLowerSelect, 0),
1096602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
109902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
110002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bits = 8 - bits;
110102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1102602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1103602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1104602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
110502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
110602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *NegShift =
1108602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1109602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
111102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1112602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1113602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
111402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1115602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1116602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(NegShift, 0));
111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
111802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1119bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11201cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
112102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
112202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1123c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*!
1124c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant
1125c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */
1126eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
11277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
1128eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  ConstantSDNode *CN = cast<ConstantSDNode>(N);
11297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
11307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel}
11317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1132e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
11337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
113423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1135c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  SDValue i64vec =
11367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1137c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1138c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // Here's where it gets interesting, because we have to parse out the
1139c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // subtree handed back in i64vec:
1140c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1141bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  if (i64vec.getOpcode() == ISD::BITCAST) {
1142c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // The degenerate case where the upper and lower bits in the splat are
1143c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // identical:
1144c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = i64vec.getOperand(0);
1145c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
11469de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ReplaceUses(i64vec, Op0);
11471cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11481cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(Op0.getNode()), 0),
11491cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1150c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1151c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue lhs = i64vec.getOperand(0);
1152c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue rhs = i64vec.getOperand(1);
1153c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue shufmask = i64vec.getOperand(2);
1154c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1155bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (lhs.getOpcode() == ISD::BITCAST) {
1156c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(lhs, lhs.getOperand(0));
1157c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      lhs = lhs.getOperand(0);
1158c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1159c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1160c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1161c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? lhs.getNode()
1162eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(lhs.getNode()));
1163c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1164bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (rhs.getOpcode() == ISD::BITCAST) {
1165c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(rhs, rhs.getOperand(0));
1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      rhs = rhs.getOperand(0);
1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1168c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1169c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1170c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? rhs.getNode()
1171eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(rhs.getNode()));
11729de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
1173bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (shufmask.getOpcode() == ISD::BITCAST) {
1174c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(shufmask, shufmask.getOperand(0));
1175c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      shufmask = shufmask.getOperand(0);
1176c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1177c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1178c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1179c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            ? shufmask.getNode()
1180eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                            : emitBuildVector(shufmask.getNode()));
1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1182a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner   SDValue shufNode =
1183a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1185a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                   SDValue(shufMaskNode, 0));
1186a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(shufNode);
1187a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDNode *SN = SelectCode(Dummy.getValue().getNode());
1188a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SN == 0) SN = Dummy.getValue().getNode();
1189bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
1190bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11911cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  OpVT, SDValue(SN, 0), getRC(MVT::i64));
11927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
11931cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11941cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(i64vec.getNode()), 0),
11951cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1196c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else {
119775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1198dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "condition");
1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel}
1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
120202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a
1203266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
1204266bc8f7774b153401e54ed537db299159840981Scott Michel///
1205266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1206266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
1207266bc8f7774b153401e54ed537db299159840981Scott Michel}
1208