SPUISelDAGToDAG.cpp revision 4d6ccb5f68cd7c6418a209f1fa4dbade569e4493
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"
1816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "SPUFrameLowering.h"
1994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h"
20266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h"
21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h"
22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h"
23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h"
24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h"
25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h"
26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h"
27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h"
28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h"
29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h"
30a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h"
31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h"
32dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h"
34266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h"
35dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
36266bc8f7774b153401e54ed537db299159840981Scott Michel
37266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm;
38266bc8f7774b153401e54ed537db299159840981Scott Michel
39266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace {
40266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
41266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
42266bc8f7774b153401e54ed537db299159840981Scott Michel  isI32IntS10Immediate(ConstantSDNode *CN)
43266bc8f7774b153401e54ed537db299159840981Scott Michel  {
447e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
45266bc8f7774b153401e54ed537db299159840981Scott Michel  }
46266bc8f7774b153401e54ed537db299159840981Scott Michel
47504c369213efb263136bb048e79af3516511c040Scott Michel  //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
48504c369213efb263136bb048e79af3516511c040Scott Michel  bool
49504c369213efb263136bb048e79af3516511c040Scott Michel  isI32IntU10Immediate(ConstantSDNode *CN)
50504c369213efb263136bb048e79af3516511c040Scott Michel  {
5134247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>(CN->getSExtValue());
52504c369213efb263136bb048e79af3516511c040Scott Michel  }
53504c369213efb263136bb048e79af3516511c040Scott Michel
54266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
55266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
56266bc8f7774b153401e54ed537db299159840981Scott Michel  isI16IntS10Immediate(ConstantSDNode *CN)
57266bc8f7774b153401e54ed537db299159840981Scott Michel  {
587e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer    return isInt<10>(CN->getSExtValue());
59266bc8f7774b153401e54ed537db299159840981Scott Michel  }
60266bc8f7774b153401e54ed537db299159840981Scott Michel
61ec2a08ff061af36b46160e475362959f21663e76Scott Michel  //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
62ec2a08ff061af36b46160e475362959f21663e76Scott Michel  bool
63ec2a08ff061af36b46160e475362959f21663e76Scott Michel  isI16IntU10Immediate(ConstantSDNode *CN)
64ec2a08ff061af36b46160e475362959f21663e76Scott Michel  {
6534247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer    return isUInt<10>((short) CN->getZExtValue());
66ec2a08ff061af36b46160e475362959f21663e76Scott Michel  }
67ec2a08ff061af36b46160e475362959f21663e76Scott Michel
68266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantSDNode predicate for signed 16-bit values
69266bc8f7774b153401e54ed537db299159840981Scott Michel  /*!
70266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg CN The constant SelectionDAG node holding the value
71266bc8f7774b153401e54ed537db299159840981Scott Michel    \arg Imm The returned 16-bit value, if returning true
72266bc8f7774b153401e54ed537db299159840981Scott Michel
73266bc8f7774b153401e54ed537db299159840981Scott Michel    This predicate tests the value in \a CN to see whether it can be
74266bc8f7774b153401e54ed537db299159840981Scott Michel    represented as a 16-bit, sign-extended quantity. Returns true if
75266bc8f7774b153401e54ed537db299159840981Scott Michel    this is the case.
76266bc8f7774b153401e54ed537db299159840981Scott Michel   */
77266bc8f7774b153401e54ed537db299159840981Scott Michel  bool
78266bc8f7774b153401e54ed537db299159840981Scott Michel  isIntS16Immediate(ConstantSDNode *CN, short &Imm)
79266bc8f7774b153401e54ed537db299159840981Scott Michel  {
80e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = CN->getValueType(0);
81f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    Imm = (short) CN->getZExtValue();
82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
83266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (vt == MVT::i32) {
85f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int32_t i_val = (int32_t) CN->getZExtValue();
86266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
87266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
88266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
89f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
90266bc8f7774b153401e54ed537db299159840981Scott Michel      short s_val = (short) i_val;
91266bc8f7774b153401e54ed537db299159840981Scott Michel      return i_val == s_val;
92266bc8f7774b153401e54ed537db299159840981Scott Michel    }
93266bc8f7774b153401e54ed537db299159840981Scott Michel  }
94266bc8f7774b153401e54ed537db299159840981Scott Michel
95266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
96266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
97266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
98266bc8f7774b153401e54ed537db299159840981Scott Michel  {
99e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = FPN->getValueType(0);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt == MVT::f32) {
101d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
102266bc8f7774b153401e54ed537db299159840981Scott Michel      int sval = (int) ((val << 16) >> 16);
103266bc8f7774b153401e54ed537db299159840981Scott Michel      Imm = (short) val;
104266bc8f7774b153401e54ed537db299159840981Scott Michel      return val == sval;
105266bc8f7774b153401e54ed537db299159840981Scott Michel    }
106266bc8f7774b153401e54ed537db299159840981Scott Michel
107266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
108266bc8f7774b153401e54ed537db299159840981Scott Michel  }
109266bc8f7774b153401e54ed537db299159840981Scott Michel
1107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the carry-generate shuffle mask.
1117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
113844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
1147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
12002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
123266bc8f7774b153401e54ed537db299159840981Scott Michel  }
124266bc8f7774b153401e54ed537db299159840981Scott Michel
1257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the borrow-generate shuffle mask
1267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
1287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
1357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
138266bc8f7774b153401e54ed537db299159840981Scott Michel  }
13902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //===------------------------------------------------------------------===//
1417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
1427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// instructions for SelectionDAG operations.
1437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  ///
1447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  class SPUDAGToDAGISel :
1457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    public SelectionDAGISel
1467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  {
147d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetMachine &TM;
148d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetLowering &SPUtli;
1497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    unsigned GlobalBaseReg;
1507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  public:
1527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
1537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SelectionDAGISel(tm),
1547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      TM(tm),
1557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SPUtli(*tm.getTargetLowering())
1567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    { }
1577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
158ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman    virtual bool runOnMachineFunction(MachineFunction &MF) {
1597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Make sure we re-emit a set of the global base reg if necessary
1607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      GlobalBaseReg = 0;
161ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman      SelectionDAGISel::runOnMachineFunction(MF);
1627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return true;
163c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
164266bc8f7774b153401e54ed537db299159840981Scott Michel
1657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI32Imm - Return a target constant with the specified value, of type
1667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i32.
1677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI32Imm(uint32_t Imm) {
168825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i32);
16994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    }
17094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
1717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getSmallIPtrImm - Return a target constant of pointer type.
1727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getSmallIPtrImm(unsigned Imm) {
1737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
17417aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner    }
1757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
176eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *emitBuildVector(SDNode *bvNode) {
177eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      EVT vecVT = bvNode->getValueType(0);
1787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      DebugLoc dl = bvNode->getDebugLoc();
1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Check to see if this vector can be represented as a CellSPU immediate
1817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // constant by invoking all of the instruction selection predicates:
182825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (((vecVT == MVT::v8i16) &&
183825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v4i32) &&
185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
1887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v2i64) &&
190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
191825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
192a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
193a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        HandleSDNode Dummy(SDValue(bvNode, 0));
194a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        if (SDNode *N = Select(bvNode))
195a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner          return N;
196a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return Dummy.getValue().getNode();
197a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      }
1987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // No, need to emit a constant pool spill:
2007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      std::vector<Constant*> CV;
2017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
202eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
203b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i));
204a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
2067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
20746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman      const Constant *CP = ConstantVector::get(CV);
2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CGPoolOffset =
211d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman              SPU::LowerConstantPool(CPIdx, *CurDAG, TM);
212bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
213a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
214a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         CurDAG->getEntryNode(), CGPoolOffset,
215e8639036b1fb3a5b5e9589fe4e9f2ee1b77c36bdChris Lattner                                         MachinePointerInfo::getConstantPool(),
216d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                         false, false, false, Alignment));
217a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
218a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
219a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return N;
220a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return Dummy.getValue().getNode();
2217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
2227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Select - Convert the specified operand from a target-independent to a
2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// target-specific node if it hasn't already been changed.
225eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *Select(SDNode *N);
2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 shl
228eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
2297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 srl
231eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
2327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 sra
234eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
2357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the necessary sequence for loading i64 constants:
237eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Alternate instruction emit sequence for loading i64 constants
240e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Returns true if the address N is an A-form (local store) address
243eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! D-form address predicate
247eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Alternate D-form address using i7 offset predicate
251eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                          SDValue &Base);
2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// D-form address selection workhorse
255eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                               SDValue &Base, int minOffset, int maxOffset);
2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Address predicate if N can be expressed as an indexed [r+r] operation.
259eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// inline asm expressions.
2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              char ConstraintCode,
2667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              std::vector<SDValue> &OutOps) {
2677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op0, Op1;
2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      switch (ConstraintCode) {
2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      default: return true;
2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'm':   // memory
271eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
272eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
273eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman          SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'o':   // offsetable
276eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
277eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op0 = Op;
2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op1 = getSmallIPtrImm(0);
2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        }
2817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'v':   // not offsetable
283266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
284c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
285266bc8f7774b153401e54ed537db299159840981Scott Michel#else
2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        SelectAddrIdxOnly(Op, Op, Op0, Op1);
2877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2884d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie#endif
2897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
29002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op0);
2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op1);
2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return false;
2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
295266bc8f7774b153401e54ed537db299159840981Scott Michel
2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual const char *getPassName() const {
2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return "Cell SPU DAG->DAG Pattern Instruction Selection";
2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
29902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
3001cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  private:
301bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    SDValue getRC( MVT );
302266bc8f7774b153401e54ed537db299159840981Scott Michel
3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Include the pieces autogenerated from the target description.
304266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  };
306844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
307844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
308266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
3099de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand
310266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
311266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
312266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
313266bc8f7774b153401e54ed537db299159840981Scott Michel */
314266bc8f7774b153401e54ed537db299159840981Scott Michelbool
315eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
316475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
317266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
318825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT OffsVT = MVT::i16;
319475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
3207f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila  int64_t val;
321266bc8f7774b153401e54ed537db299159840981Scott Michel
322266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
323266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3247f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    val = dyn_cast<ConstantSDNode>(N.getNode())->getSExtValue();
3257f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    Base = CurDAG->getTargetConstant( val , MVT::i32);
3267f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    Index = Zero;
3274d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return true;
3289de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3299de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3307f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    report_fatal_error("SPU SelectAFormAddr: Pool/Global not lowered.");
3319de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3329de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
333053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3349de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
335053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
33675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
337dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "not wrapped as A-form address.");
338053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
339266bc8f7774b153401e54ed537db299159840981Scott Michel
34002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  case SPUISD::AFormAddr:
341053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
342053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
343053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
344475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
345053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
346053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
347053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
348053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
349053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
350053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
351053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
352053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
353053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
35446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = GSDN->getGlobal();
355053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
356053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
357053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
358053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
359053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
360053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
361053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
362053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
363053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
364053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
365053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
366266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
367266bc8f7774b153401e54ed537db299159840981Scott Michel}
368266bc8f7774b153401e54ed537db299159840981Scott Michel
36902d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool
370eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
371475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
372203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
373203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
374203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
375203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
3767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
3777f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
378266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
379266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
380266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
381266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
382266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
383266bc8f7774b153401e54ed537db299159840981Scott Michel
384266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
385266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
386266bc8f7774b153401e54ed537db299159840981Scott Michel
387266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
388475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
389266bc8f7774b153401e54ed537db299159840981Scott Michel*/
390266bc8f7774b153401e54ed537db299159840981Scott Michelbool
391eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
392475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
3937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
39416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                               SPUFrameLowering::minFrameOffset(),
39516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                               SPUFrameLowering::maxFrameOffset());
3967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
3977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
3987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
399eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
400475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
402266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
403e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT PtrTy = SPUtli.getPointerTy();
404266bc8f7774b153401e54ed537db299159840981Scott Michel
405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
407b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman    FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N);
408203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
4094437ae213d5435390f0750213b53ec807c047f22Chris Lattner    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
410203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
41116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
412266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
413203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
414266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
415266bc8f7774b153401e54ed537db299159840981Scott Michel    }
416266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
417266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
418475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
419475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
420266bc8f7774b153401e54ed537db299159840981Scott Michel
421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
422053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
423053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
424053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
425053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
426053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
427053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
428b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4297810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
430266bc8f7774b153401e54ed537db299159840981Scott Michel
431053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
432b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0);
433203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4344437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
435203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4369de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
43716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
4389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
439203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4409de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4427f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
449b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4507810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
451053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
452053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
453b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1);
454203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4554437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
456203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
457053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
45816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
460203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4619de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4629de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4637f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
467266bc8f7774b153401e54ed537db299159840981Scott Michel      }
468497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
471475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
472475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
4747f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
4757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
4807f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
4817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
482475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
4837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
4857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4867810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
4887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
4897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4907810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4917f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
49202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      }
4937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
4957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
4967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
4977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
4987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
4999de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
500053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
502053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
50358c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
508bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  } else if (Opc == ISD::Register
509bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck           ||Opc == ISD::CopyFromReg
510bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::UNDEF
511bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::Constant) {
512eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    unsigned OpOpc = Op->getOpcode();
5139c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5149c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
5159c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
51611fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila      SDValue Offs;
5179c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
518eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
5199c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
5219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
5229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
5239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
52511fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila        Index = N;
5269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
5279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
528aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
529aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
530aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
53119c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N.getOperand(1);
532aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
53319c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N;
534aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
535aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
536aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
537aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
5389c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
539266bc8f7774b153401e54ed537db299159840981Scott Michel  }
5409c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
541266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
542266bc8f7774b153401e54ed537db299159840981Scott Michel}
543266bc8f7774b153401e54ed537db299159840981Scott Michel
544266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
545266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
546266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
547266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
548266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
549266bc8f7774b153401e54ed537db299159840981Scott Michel
5509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
5519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
5529c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
553266bc8f7774b153401e54ed537db299159840981Scott Michel*/
554266bc8f7774b153401e54ed537db299159840981Scott Michelbool
555eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
556475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
5589c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
55918fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
56018fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
5611a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
5621a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
56350843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
5649c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
565266bc8f7774b153401e54ed537db299159840981Scott Michel
5669c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
56758c5818c01e375a84dc601140470fa68638004cfScott Michel}
56858c5818c01e375a84dc601140470fa68638004cfScott Michel
5691cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*!
570bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue
5711cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a
5721cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call
5731cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class
5741cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/
5751cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) {
5761cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  switch( VT.SimpleTy ) {
577218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i8:
578bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32);
579218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i16:
580bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32);
5811cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i32:
582bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32);
583218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::f32:
584bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32);
5851cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i64:
586bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32);
58711edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila  case MVT::i128:
58811edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila    return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32);
589218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v16i8:
590218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v8i16:
591218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4i32:
592218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4f32:
5931cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::v2i64:
594218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v2f64:
595bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32);
5961cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  default:
5971cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    assert( false && "add a new case here" );
5984d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return SDValue();
5991cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  }
6001cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila}
6011cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila
602266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
603266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
604266bc8f7774b153401e54ed537db299159840981Scott Michel */
605266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
606eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) {
607266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
60858c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
609584520e8e2c1f8cc04bc8dd4dc4ea6c390627317Ted Kremenek  unsigned NewOpc = 0;
610eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  EVT OpVT = N->getValueType(0);
611475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
612ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = N->getDebugLoc();
613266bc8f7774b153401e54ed537db299159840981Scott Michel
614a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner  if (N->isMachineOpcode())
615266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
616c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
617c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (Opc == ISD::FrameIndex) {
61802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
619eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
620eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
62102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
62202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (FI < 128) {
623203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
62402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = TFI;
62502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[1] = Imm0;
626203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
627203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
628203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
629eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
630602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
6317d17097e4a1f5d166a67a00670e8eca317a3a8acKalle Raiskila                                              N->getValueType(0), TFI),
632602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                       0);
633203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
634203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
635825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
636c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // Catch the i64 constants that end up here. Note: The backend doesn't
637c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // attempt to legalize the constant (it's useless because DAGCombiner
638c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // will insert 64-bit constants and we can't stop it).
639eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectI64Constant(N, OpVT, N->getDebugLoc());
64094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
641825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && OpVT == MVT::i64) {
642eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
643e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT Op0VT = Op0.getValueType();
64423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
64523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                    Op0VT, (128 / Op0VT.getSizeInBits()));
646bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
64723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                   OpVT, (128 / OpVT.getSizeInBits()));
64894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue shufMask;
64994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
650825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    switch (Op0VT.getSimpleVT().SimpleTy) {
65194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    default:
65275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner      report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT");
65394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      /*NOTREACHED*/
654825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i32:
655825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
656825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
657825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x00010203, MVT::i32),
658825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
659825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
66094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
66194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
662825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i16:
663825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
664825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
665825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800203, MVT::i32),
666825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
667825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
66894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
66994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
670825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i8:
671825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
672825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
673825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808003, MVT::i32),
674825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
675825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x8080800b, MVT::i32));
67694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
67758c5818c01e375a84dc601140470fa68638004cfScott Michel    }
67894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
679eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
680bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
681a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
682a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                               Op0VecVT, Op0));
683bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
684a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDValue PromScalar;
685a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
686a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = SDValue(N, 0);
687a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
688a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = PromoteScalar.getValue();
689bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
69094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue zextShuffle =
691ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
692bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                            PromScalar, PromScalar,
693d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(shufMaskLoad, 0));
69494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
695a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy2(zextShuffle);
696a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
697a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = SDValue(N, 0);
698a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
699a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = Dummy2.getValue();
700a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
701a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       zextShuffle));
702bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
703a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
704a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SelectCode(Dummy.getValue().getNode());
705a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
706825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
70794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *CGLoad =
708eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
709d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
710a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
711a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
712a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
713bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
714a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
715a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
716a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
717a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
718825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
719d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
720eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
721d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
722a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
723a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
724a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
725bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
727a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
729a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
730825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
731d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
732eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
733d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
734a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
735a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
736a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
737a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
739a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
740a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
741c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (Opc == ISD::TRUNCATE) {
742eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
743c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && OpVT == MVT::i32
745825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && Op0.getValueType() == MVT::i64) {
7469de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
7479de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      //
7489de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Take advantage of the fact that the upper 32 bits are in the
7499de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // i32 preferred slot and avoid shuffle gymnastics:
750c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
751c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      if (CN != 0) {
752c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        unsigned shift_amt = unsigned(CN->getZExtValue());
753c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
754c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        if (shift_amt >= 32) {
755c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          SDNode *hi32 =
7561cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                  CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
7571cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                         Op0.getOperand(0), getRC(MVT::i32));
758c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
759c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          shift_amt -= 32;
760c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          if (shift_amt > 0) {
761c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            // Take care of the additional shift, if present:
762825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
763c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            unsigned Opc = SPU::ROTMAIr32_i32;
7649de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
765c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            if (Op0.getOpcode() == ISD::SRL)
766c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel              Opc = SPU::ROTMr32;
767c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
768602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
769602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                          shift);
770c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          }
771c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
772c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          return hi32;
773c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        }
774c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      }
775c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
77602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SHL) {
777a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
778eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSHLi64(N, OpVT);
77902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRL) {
780a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
781eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRLi64(N, OpVT);
78202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRA) {
783a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
784eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRAi64(N, OpVT);
7857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FNEG
786825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
787eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    DebugLoc dl = N->getDebugLoc();
7887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Check if the pattern is a special form of DFNMS:
7897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
790eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
7917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    if (Op0.getOpcode() == ISD::FSUB) {
7927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op00 = Op0.getOperand(0);
7937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      if (Op00.getOpcode() == ISD::FMUL) {
7947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        unsigned Opc = SPU::DFNMSf64;
795825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        if (OpVT == MVT::v2f64)
7967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Opc = SPU::DFNMSv2f64;
7977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
798602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        return CurDAG->getMachineNode(Opc, dl, OpVT,
799602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(0),
800602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(1),
801602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op0.getOperand(1));
8027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
8037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
805825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
8067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *signMask = 0;
807a82d3f7c57f03457c385add1687319d5c290f867Scott Michel    unsigned Opc = SPU::XORfneg64;
8087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
809825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
810eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
811825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
812a82d3f7c57f03457c385add1687319d5c290f867Scott Michel      Opc = SPU::XORfnegvec;
8137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
814825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                                 MVT::v2i64,
815eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                                 negConst, negConst).getNode());
8167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
818602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(Opc, dl, OpVT,
819eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                  N->getOperand(0), SDValue(signMask, 0));
8207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FABS) {
821825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
822825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
823602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
824eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
825825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
826825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
827825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
8287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                       absConst, absConst);
829eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      SDNode *signMask = emitBuildVector(absVec.getNode());
830602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
831eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
8327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
833266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
834266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
835e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = N->getValueType(0);
836475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
837475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
838266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
839bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
8408258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila    Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT,
8418258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    MVT::Other, Arg,
8428258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    getRC( VT.getSimpleVT()), Chain);
843266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
844bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
845053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
846f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // Look at the operands: SelectCode() will catch the cases that aren't
847f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // specifically handled here.
848f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    //
849f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // SPUInstrInfo catches the following patterns:
850f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect (SPUhi ...), (SPUlo ...))
851f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect $sp, imm)
852eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    EVT VT = N->getValueType(0);
853f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op0 = N->getOperand(0);
854f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op1 = N->getOperand(1);
855f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    RegisterSDNode *RN;
856f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel
857f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
858f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        || (Op0.getOpcode() == ISD::Register
859f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
860f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel                && RN->getReg() != SPU::R1))) {
861f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      NewOpc = SPU::Ar32;
862d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner      Ops[1] = Op1;
86358c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
86458c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
865f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
866d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        if (isInt<10>(CN->getSExtValue())) {
867d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          NewOpc = SPU::AIr32;
868d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          Ops[1] = Op1;
869d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        } else {
870bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck          Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl,
871bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                                                  N->getValueType(0),
872d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                                                  Op1),
873bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                           0);
874d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        }
87558c5818c01e375a84dc601140470fa68638004cfScott Michel      }
876f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[0] = Op0;
877f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      n_ops = 2;
87858c5818c01e375a84dc601140470fa68638004cfScott Michel    }
879266bc8f7774b153401e54ed537db299159840981Scott Michel  }
88002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
88158c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
88258c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
88358c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
88458c5818c01e375a84dc601140470fa68638004cfScott Michel    else
885602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
88658c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
887eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectCode(N);
888266bc8f7774b153401e54ed537db299159840981Scott Michel}
889266bc8f7774b153401e54ed537db299159840981Scott Michel
89002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
89102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm
89202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted
89302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left.
89402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
89502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl.
89602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
89702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
89802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
89902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
90002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
90102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
90202d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
903eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
904eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
905bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
90623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
907eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
908e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
90902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
91002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SelMaskVal;
911eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
91202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9131cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9141cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
915825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
916602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
917602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
918602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    CurDAG->getTargetConstant(0, OpVT));
919602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
920602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(ZeroFill, 0),
921602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(VecOp0, 0),
922602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(SelMask, 0));
92302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
92402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
92502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
92602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
92702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
92802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
92902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
930602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
931602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
932602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
93302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
93402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
93502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
93602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
937602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
938602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
939602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
94002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
94102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
94202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
943602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
944602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
945602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
94602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
947602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
948602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
949602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
951602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
952602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
95302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
954602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
955602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
95702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
958bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
9591cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
96102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
96202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
96302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts.
96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
96502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
96802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
96902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
97002d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
971eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
972eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
97323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
97423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
975eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
976e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *Shift = 0;
978eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9811cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
98402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
98502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
98602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
98802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
990602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
991602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
99502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
996602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
997602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
998602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
100002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
100102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1002602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1003602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1004602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
100502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1007602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1008602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    // Ensure that the shift amounts are negated!
1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   SDValue(Bytes, 0),
1013602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1015602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(Bits, 0),
1017602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
101802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1021602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
102202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1023602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1024602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1027bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10281cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
102902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
103002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
103102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts.
103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
103502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
103702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
103802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
103902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1040eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
104102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  // Promote Op0 to vector
1042bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
104323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
1044eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
1045e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
1046eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
104802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0 =
1049bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10501cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           VecVT, N->getOperand(0), getRC(MVT::v2i64));
105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
105302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *SignRot =
1054602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1055602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0), SignRotAmt);
105602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSign =
1057bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10581cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32));
105902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
106002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSignMask =
1061602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerMask =
1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1064602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
106502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerSelect =
1066602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1067602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperHalfSignMask, 0),
1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0),
1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperLowerMask, 0));
107002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *Shift = 0;
107202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
107402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
107502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
107802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bytes = 31 - bytes;
107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(UpperLowerSelect, 0),
1082602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
108302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
108402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bits = 8 - bits;
108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1088602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1089602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1090602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *NegShift =
1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1095602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
109602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1098602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1099602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
110002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1101602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1102602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(NegShift, 0));
110302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1105bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11061cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
110802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1109c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*!
1110c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant
1111c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */
1112eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
11137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
1114eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  ConstantSDNode *CN = cast<ConstantSDNode>(N);
11157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
11167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel}
11177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1118e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
11197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
112023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1121c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  SDValue i64vec =
11227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1123c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1124c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // Here's where it gets interesting, because we have to parse out the
1125c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // subtree handed back in i64vec:
1126c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1127bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  if (i64vec.getOpcode() == ISD::BITCAST) {
1128c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // The degenerate case where the upper and lower bits in the splat are
1129c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // identical:
1130c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = i64vec.getOperand(0);
1131c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
11329de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ReplaceUses(i64vec, Op0);
11331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(Op0.getNode()), 0),
11351cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1136c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1137c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue lhs = i64vec.getOperand(0);
1138c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue rhs = i64vec.getOperand(1);
1139c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue shufmask = i64vec.getOperand(2);
1140c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1141bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (lhs.getOpcode() == ISD::BITCAST) {
1142c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(lhs, lhs.getOperand(0));
1143c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      lhs = lhs.getOperand(0);
1144c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1145c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1146c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1147c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? lhs.getNode()
1148eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(lhs.getNode()));
1149c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1150bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (rhs.getOpcode() == ISD::BITCAST) {
1151c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(rhs, rhs.getOperand(0));
1152c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      rhs = rhs.getOperand(0);
1153c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1154c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1155c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1156c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? rhs.getNode()
1157eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(rhs.getNode()));
11589de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
1159bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (shufmask.getOpcode() == ISD::BITCAST) {
1160c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(shufmask, shufmask.getOperand(0));
1161c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      shufmask = shufmask.getOperand(0);
1162c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1163c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1164c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1165c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            ? shufmask.getNode()
1166eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                            : emitBuildVector(shufmask.getNode()));
1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1168a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner   SDValue shufNode =
1169a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1170c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1171a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                   SDValue(shufMaskNode, 0));
1172a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(shufNode);
1173a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDNode *SN = SelectCode(Dummy.getValue().getNode());
1174a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SN == 0) SN = Dummy.getValue().getNode();
1175bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
1176bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11771cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  OpVT, SDValue(SN, 0), getRC(MVT::i64));
11787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
11791cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(i64vec.getNode()), 0),
11811cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1182c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else {
118375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1184dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "condition");
1185c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel}
1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
118802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a
1189266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
1190266bc8f7774b153401e54ed537db299159840981Scott Michel///
1191266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1192266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
1193266bc8f7774b153401e54ed537db299159840981Scott Michel}
1194