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();
861144af3c9b4da48cd581156e05b24261c8de366aRichard Smith      return i_val == SignExtend32<16>(i_val);
87266bc8f7774b153401e54ed537db299159840981Scott Michel    } else {
88f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman      int64_t i_val = (int64_t) CN->getZExtValue();
891144af3c9b4da48cd581156e05b24261c8de366aRichard Smith      return i_val == SignExtend64<16>(i_val);
90266bc8f7774b153401e54ed537db299159840981Scott Michel    }
91266bc8f7774b153401e54ed537db299159840981Scott Michel  }
92266bc8f7774b153401e54ed537db299159840981Scott Michel
93266bc8f7774b153401e54ed537db299159840981Scott Michel  //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
94266bc8f7774b153401e54ed537db299159840981Scott Michel  static bool
95266bc8f7774b153401e54ed537db299159840981Scott Michel  isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
96266bc8f7774b153401e54ed537db299159840981Scott Michel  {
97e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT vt = FPN->getValueType(0);
98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (vt == MVT::f32) {
99d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner      int val = FloatToBits(FPN->getValueAPF().convertToFloat());
1001144af3c9b4da48cd581156e05b24261c8de366aRichard Smith      if (val == SignExtend32<16>(val)) {
1011144af3c9b4da48cd581156e05b24261c8de366aRichard Smith        Imm = (short) val;
1021144af3c9b4da48cd581156e05b24261c8de366aRichard Smith        return true;
1031144af3c9b4da48cd581156e05b24261c8de366aRichard Smith      }
104266bc8f7774b153401e54ed537db299159840981Scott Michel    }
105266bc8f7774b153401e54ed537db299159840981Scott Michel
106266bc8f7774b153401e54ed537db299159840981Scott Michel    return false;
107266bc8f7774b153401e54ed537db299159840981Scott Michel  }
108266bc8f7774b153401e54ed537db299159840981Scott Michel
1097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the carry-generate shuffle mask.
1107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
112844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
1137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32));
11902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
122266bc8f7774b153401e54ed537db299159840981Scott Michel  }
123266bc8f7774b153401e54ed537db299159840981Scott Michel
1247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //! Generate the borrow-generate shuffle mask
1257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) {
1267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SmallVector<SDValue, 16 > ShufBytes;
1277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Create the shuffle mask for "rotating" the borrow up one register slot
1297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // once the borrow is generated.
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32));
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32));
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32));
1347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
1367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                       &ShufBytes[0], ShufBytes.size());
137266bc8f7774b153401e54ed537db299159840981Scott Michel  }
13802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  //===------------------------------------------------------------------===//
1407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
1417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  /// instructions for SelectionDAG operations.
1427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  ///
1437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  class SPUDAGToDAGISel :
1447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    public SelectionDAGISel
1457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  {
146d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetMachine &TM;
147d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    const SPUTargetLowering &SPUtli;
1487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    unsigned GlobalBaseReg;
1497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  public:
1517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
1527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SelectionDAGISel(tm),
1537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      TM(tm),
1547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SPUtli(*tm.getTargetLowering())
1557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    { }
1567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
157ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman    virtual bool runOnMachineFunction(MachineFunction &MF) {
1587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Make sure we re-emit a set of the global base reg if necessary
1597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      GlobalBaseReg = 0;
160ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman      SelectionDAGISel::runOnMachineFunction(MF);
1617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return true;
162c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
163266bc8f7774b153401e54ed537db299159840981Scott Michel
1647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getI32Imm - Return a target constant with the specified value, of type
1657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// i32.
1667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getI32Imm(uint32_t Imm) {
167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      return CurDAG->getTargetConstant(Imm, MVT::i32);
16894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    }
16994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
1707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// getSmallIPtrImm - Return a target constant of pointer type.
1717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    inline SDValue getSmallIPtrImm(unsigned Imm) {
1727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
17317aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner    }
1747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
175eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *emitBuildVector(SDNode *bvNode) {
176eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      EVT vecVT = bvNode->getValueType(0);
1777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      DebugLoc dl = bvNode->getDebugLoc();
1787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // Check to see if this vector can be represented as a CellSPU immediate
1807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // constant by invoking all of the instruction selection predicates:
181825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      if (((vecVT == MVT::v8i16) &&
182825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
183825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v4i32) &&
184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
1877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel            (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson          ((vecVT == MVT::v2i64) &&
189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson           ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
191a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) {
192a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        HandleSDNode Dummy(SDValue(bvNode, 0));
193a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        if (SDNode *N = Select(bvNode))
194a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner          return N;
195a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return Dummy.getValue().getNode();
196a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      }
1977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      // No, need to emit a constant pool spill:
1997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      std::vector<Constant*> CV;
2007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
201eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
202b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i));
203a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue()));
2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
20646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman      const Constant *CP = ConstantVector::get(CV);
2077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy());
2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue CGPoolOffset =
210d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman              SPU::LowerConstantPool(CPIdx, *CurDAG, TM);
211bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
212a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl,
213a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                         CurDAG->getEntryNode(), CGPoolOffset,
214e8639036b1fb3a5b5e9589fe4e9f2ee1b77c36bdChris Lattner                                         MachinePointerInfo::getConstantPool(),
215d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                         false, false, false, Alignment));
216a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue());
217a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
218a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner        return N;
219a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return Dummy.getValue().getNode();
2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
2217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Select - Convert the specified operand from a target-independent to a
2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// target-specific node if it hasn't already been changed.
224eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *Select(SDNode *N);
2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 shl
227eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 srl
230eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the instruction sequence for i64 sra
233eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Emit the necessary sequence for loading i64 constants:
236eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
2377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Alternate instruction emit sequence for loading i64 constants
239e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Returns true if the address N is an A-form (local store) address
242eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! D-form address predicate
246eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// Alternate D-form address using i7 offset predicate
250eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                          SDValue &Base);
2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// D-form address selection workhorse
254eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
2557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                               SDValue &Base, int minOffset, int maxOffset);
2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    //! Address predicate if N can be expressed as an indexed [r+r] operation.
258eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
2597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                         SDValue &Index);
2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    /// inline asm expressions.
2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              char ConstraintCode,
2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                              std::vector<SDValue> &OutOps) {
2667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op0, Op1;
2677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      switch (ConstraintCode) {
2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      default: return true;
2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'm':   // memory
270eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
271eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
272eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman          SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'o':   // offsetable
275eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman        if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
276eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op0 = Op;
2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Op1 = getSmallIPtrImm(0);
2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        }
2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      case 'v':   // not offsetable
282266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1
283c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled.");
284266bc8f7774b153401e54ed537db299159840981Scott Michel#else
2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        SelectAddrIdxOnly(Op, Op, Op0, Op1);
2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        break;
2874d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie#endif
2887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
28902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
2907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op0);
2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      OutOps.push_back(Op1);
2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return false;
2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
294266bc8f7774b153401e54ed537db299159840981Scott Michel
2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    virtual const char *getPassName() const {
2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      return "Cell SPU DAG->DAG Pattern Instruction Selection";
2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
29802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
2991cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  private:
300bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    SDValue getRC( MVT );
301266bc8f7774b153401e54ed537db299159840981Scott Michel
3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Include the pieces autogenerated from the target description.
303266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc"
3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  };
305844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
306844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
307266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
3089de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand
309266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested
310266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address
311266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index
312266bc8f7774b153401e54ed537db299159840981Scott Michel */
313266bc8f7774b153401e54ed537db299159840981Scott Michelbool
314eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
315475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                    SDValue &Index) {
316266bc8f7774b153401e54ed537db299159840981Scott Michel  // These match the addr256k operand type:
317825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  EVT OffsVT = MVT::i16;
318475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
3197f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila  int64_t val;
320266bc8f7774b153401e54ed537db299159840981Scott Michel
321266bc8f7774b153401e54ed537db299159840981Scott Michel  switch (N.getOpcode()) {
322266bc8f7774b153401e54ed537db299159840981Scott Michel  case ISD::Constant:
3237f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    val = dyn_cast<ConstantSDNode>(N.getNode())->getSExtValue();
3247f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    Base = CurDAG->getTargetConstant( val , MVT::i32);
3257f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    Index = Zero;
3264d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return true;
3279de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::ConstantPool:
3289de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::GlobalAddress:
3297f5de8b4c64280587c2c9a9a0ba4e1ada7e050e5Kalle Raiskila    report_fatal_error("SPU SelectAFormAddr: Pool/Global not lowered.");
3309de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    /*NOTREACHED*/
3319de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
332053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetConstant:
3339de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel  case ISD::TargetGlobalAddress:
334053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  case ISD::TargetJumpTable:
33575361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global "
336dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "not wrapped as A-form address.");
337053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    /*NOTREACHED*/
338266bc8f7774b153401e54ed537db299159840981Scott Michel
33902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  case SPUISD::AFormAddr:
340053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Just load from memory if there's only a single use of the location,
341053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // otherwise, this will get handled below with D-form offset addresses
342053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if (N.hasOneUse()) {
343475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op0 = N.getOperand(0);
344053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      switch (Op0.getOpcode()) {
345053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetConstantPool:
346053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetJumpTable:
347053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = Op0;
348053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Zero;
349053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
350053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
351053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      case ISD::TargetGlobalAddress: {
352053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
35346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = GSDN->getGlobal();
354053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        if (GV->getAlignment() == 16) {
355053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = Op0;
356053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Index = Zero;
357053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          return true;
358053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        }
359053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        break;
360053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
361053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
362053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    }
363053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    break;
364053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  }
365266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
366266bc8f7774b153401e54ed537db299159840981Scott Michel}
367266bc8f7774b153401e54ed537db299159840981Scott Michel
36802d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool
369eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
370475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                  SDValue &Base) {
371203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int minDForm2Offset = -(1 << 7);
372203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  const int maxDForm2Offset = (1 << 7) - 1;
373203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
374203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                               maxDForm2Offset);
3757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
3767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
377266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
378266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction (ignored)
379266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address to be tested
380266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base Base address register/pointer
381266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index Base address index
382266bc8f7774b153401e54ed537db299159840981Scott Michel
383266bc8f7774b153401e54ed537db299159840981Scott Michel  Examine the input address by a base register plus a signed 10-bit
384266bc8f7774b153401e54ed537db299159840981Scott Michel  displacement, [r+I10] (D-form address).
385266bc8f7774b153401e54ed537db299159840981Scott Michel
386266bc8f7774b153401e54ed537db299159840981Scott Michel  \return true if \a N is a D-form address with \a Base and \a Index set
387475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  to non-empty SDValue instances.
388266bc8f7774b153401e54ed537db299159840981Scott Michel*/
389266bc8f7774b153401e54ed537db299159840981Scott Michelbool
390eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
391475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
3927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  return DFormAddressPredicate(Op, N, Base, Index,
39316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                               SPUFrameLowering::minFrameOffset(),
39416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                               SPUFrameLowering::maxFrameOffset());
3957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel}
3967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
3977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool
398eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
399475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                      SDValue &Index, int minOffset,
4007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel                                      int maxOffset) {
401266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N.getOpcode();
402e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT PtrTy = SPUtli.getPointerTy();
403266bc8f7774b153401e54ed537db299159840981Scott Michel
404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  if (Opc == ISD::FrameIndex) {
405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Stack frame index must be less than 512 (divided by 16):
406b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman    FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N);
407203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    int FI = int(FIN->getIndex());
4084437ae213d5435390f0750213b53ec807c047f22Chris Lattner    DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = "
409203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel               << FI << "\n");
41016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
411266bc8f7774b153401e54ed537db299159840981Scott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
412203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
413266bc8f7774b153401e54ed537db299159840981Scott Michel      return true;
414266bc8f7774b153401e54ed537db299159840981Scott Michel    }
415266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == ISD::ADD) {
416266bc8f7774b153401e54ed537db299159840981Scott Michel    // Generated by getelementptr
417475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
418475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
419266bc8f7774b153401e54ed537db299159840981Scott Michel
420053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
422053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
423053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
424053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      return true;
425053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op1.getOpcode() == ISD::Constant
426053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op1.getOpcode() == ISD::TargetConstant) {
427b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4287810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
429266bc8f7774b153401e54ed537db299159840981Scott Michel
430053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op0.getOpcode() == ISD::FrameIndex) {
431b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0);
432203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4334437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
434203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
4359de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel
43616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
4379de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
438203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4399de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4409de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4417f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
4429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
443053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op0;
444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      }
446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    } else if (Op0.getOpcode() == ISD::Constant
447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel               || Op0.getOpcode() == ISD::TargetConstant) {
448b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman      ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4497810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman      int32_t offset = int32_t(CN->getSExtValue());
450053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
451053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      if (Op1.getOpcode() == ISD::FrameIndex) {
452b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman        FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1);
453203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel        int FI = int(FIN->getIndex());
4544437ae213d5435390f0750213b53ec807c047f22Chris Lattner        DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset
455203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel                   << " frame index = " << FI << "\n");
456053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
45716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov        if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) {
458053c1da8d956a794d158ac906b3927c923f97c4dScott Michel          Base = CurDAG->getTargetConstant(offset, PtrTy);
459203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
4609de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel          return true;
4619de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel        }
4627f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (offset > minOffset && offset < maxOffset) {
463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        Index = Op1;
465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel        return true;
466266bc8f7774b153401e54ed537db299159840981Scott Michel      }
467497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel    }
468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    // Indirect with constant offset -> D-Form address
470475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op0 = N.getOperand(0);
471475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    const SDValue Op1 = N.getOperand(1);
472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel
4737f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    if (Op0.getOpcode() == SPUISD::Hi
4747f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        && Op1.getOpcode() == SPUISD::Lo) {
475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
4769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      Base = CurDAG->getTargetConstant(0, PtrTy);
477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel      Index = N;
4789de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel      return true;
4797f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
4807f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      int32_t offset = 0;
481475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue idxOp;
4827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (isa<ConstantSDNode>(Op1)) {
4847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
4857810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4867f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op0;
4877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      } else if (isa<ConstantSDNode>(Op0)) {
4887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
4897810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman        offset = int32_t(CN->getSExtValue());
4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        idxOp = Op1;
49102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      }
4927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel
4937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      if (offset >= minOffset && offset <= maxOffset) {
4947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Base = CurDAG->getTargetConstant(offset, PtrTy);
4957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        Index = idxOp;
4967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel        return true;
4977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel      }
4989de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel    }
499053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::AFormAddr) {
500053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel    Index = N;
50258c5818c01e375a84dc601140470fa68638004cfScott Michel    return true;
5037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
5047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Base = CurDAG->getTargetConstant(0, N.getValueType());
5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    Index = N;
5067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel    return true;
507bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  } else if (Opc == ISD::Register
508bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck           ||Opc == ISD::CopyFromReg
509bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::UNDEF
510bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila           ||Opc == ISD::Constant) {
511eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    unsigned OpOpc = Op->getOpcode();
5129c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5139c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
5149c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      // Direct load/store without getelementptr
51511fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila      SDValue Offs;
5169c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
517eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
5189c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5199c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
5209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        if (Offs.getOpcode() == ISD::UNDEF)
5219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel          Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
5229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
5239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        Base = Offs;
52411fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila        Index = N;
5259c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel        return true;
5269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      }
527aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel    } else {
528aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      /* If otherwise unadorned, default to D-form address with 0 offset: */
529aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      if (Opc == ISD::CopyFromReg) {
53019c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N.getOperand(1);
531aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      } else {
53219c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel        Index = N;
533aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      }
534aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel
535aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      Base = CurDAG->getTargetConstant(0, Index.getValueType());
536aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel      return true;
5379c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel    }
538266bc8f7774b153401e54ed537db299159840981Scott Michel  }
5399c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel
540266bc8f7774b153401e54ed537db299159840981Scott Michel  return false;
541266bc8f7774b153401e54ed537db299159840981Scott Michel}
542266bc8f7774b153401e54ed537db299159840981Scott Michel
543266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
544266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Op The ISD instruction operand
545266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg N The address operand
546266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Base The base pointer operand
547266bc8f7774b153401e54ed537db299159840981Scott Michel  \arg Index The offset/index operand
548266bc8f7774b153401e54ed537db299159840981Scott Michel
5499c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  If the address \a N can be expressed as an A-form or D-form address, returns
5509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  false.  Otherwise, creates two operands, Base and Index that will become the
5519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  (r)(r) X-form address.
552266bc8f7774b153401e54ed537db299159840981Scott Michel*/
553266bc8f7774b153401e54ed537db299159840981Scott Michelbool
554eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
555475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                 SDValue &Index) {
5569c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  if (!SelectAFormAddr(Op, N, Base, Index)
5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel      && !SelectDFormAddr(Op, N, Base, Index)) {
55818fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // If the address is neither A-form or D-form, punt and use an X-form
55918fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel    // address:
5601a6cdb6b50f982122453babde406215e849bb021Scott Michel    Base = N.getOperand(1);
5611a6cdb6b50f982122453babde406215e849bb021Scott Michel    Index = N.getOperand(0);
56250843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel    return true;
5639c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  }
564266bc8f7774b153401e54ed537db299159840981Scott Michel
5659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel  return false;
56658c5818c01e375a84dc601140470fa68638004cfScott Michel}
56758c5818c01e375a84dc601140470fa68638004cfScott Michel
5681cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*!
569bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue
5701cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a
5711cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call
5721cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class
5731cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/
5741cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) {
5751cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  switch( VT.SimpleTy ) {
576218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i8:
577bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32);
578218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::i16:
579bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32);
5801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i32:
581bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32);
582218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::f32:
583bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32);
5841cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::i64:
585bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32);
58611edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila  case MVT::i128:
58711edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila    return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32);
588218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v16i8:
589218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v8i16:
590218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4i32:
591218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v4f32:
5921cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  case MVT::v2i64:
593218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila  case MVT::v2f64:
594bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32);
5951cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  default:
5961cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    assert( false && "add a new case here" );
5974d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    return SDValue();
5981cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  }
5991cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila}
6001cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila
601266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node
602266bc8f7774b153401e54ed537db299159840981Scott Michel/*!
603266bc8f7774b153401e54ed537db299159840981Scott Michel */
604266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode *
605eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) {
606266bc8f7774b153401e54ed537db299159840981Scott Michel  unsigned Opc = N->getOpcode();
60758c5818c01e375a84dc601140470fa68638004cfScott Michel  int n_ops = -1;
608584520e8e2c1f8cc04bc8dd4dc4ea6c390627317Ted Kremenek  unsigned NewOpc = 0;
609eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  EVT OpVT = N->getValueType(0);
610475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[8];
611ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen  DebugLoc dl = N->getDebugLoc();
612266bc8f7774b153401e54ed537db299159840981Scott Michel
613a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner  if (N->isMachineOpcode())
614266bc8f7774b153401e54ed537db299159840981Scott Michel    return NULL;   // Already selected.
615c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
616c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  if (Opc == ISD::FrameIndex) {
61702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    int FI = cast<FrameIndexSDNode>(N)->getIndex();
618eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
619eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
62002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
62102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (FI < 128) {
622203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::AIr32;
62302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[0] = TFI;
62402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Ops[1] = Imm0;
625203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
626203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    } else {
627203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      NewOpc = SPU::Ar32;
628eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
629602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
6307d17097e4a1f5d166a67a00670e8eca317a3a8acKalle Raiskila                                              N->getValueType(0), TFI),
631602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                       0);
632203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel      n_ops = 2;
633203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel    }
634825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::Constant && OpVT == MVT::i64) {
635c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // Catch the i64 constants that end up here. Note: The backend doesn't
636c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // attempt to legalize the constant (it's useless because DAGCombiner
637c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // will insert 64-bit constants and we can't stop it).
638eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectI64Constant(N, OpVT, N->getDebugLoc());
63994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel  } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
640825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && OpVT == MVT::i64) {
641eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
642e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT Op0VT = Op0.getValueType();
64323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson    EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
64423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                    Op0VT, (128 / Op0VT.getSizeInBits()));
645bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(),
64623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                                   OpVT, (128 / OpVT.getSizeInBits()));
64794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue shufMask;
64894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
649825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    switch (Op0VT.getSimpleVT().SimpleTy) {
65094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    default:
65175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner      report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT");
65294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      /*NOTREACHED*/
653825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i32:
654825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
655825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
656825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x00010203, MVT::i32),
657825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
658825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x08090a0b, MVT::i32));
65994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
66094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
661825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i16:
662825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
663825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
664825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800203, MVT::i32),
665825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
666825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80800a0b, MVT::i32));
66794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
66894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
669825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    case MVT::i8:
670825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
671825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
672825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808003, MVT::i32),
673825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x80808080, MVT::i32),
674825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                 CurDAG->getConstant(0x8080800b, MVT::i32));
67594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel      break;
67658c5818c01e375a84dc601140470fa68638004cfScott Michel    }
67794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
678eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
679bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
680a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
681a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                               Op0VecVT, Op0));
682bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
683a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDValue PromScalar;
684a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode()))
685a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = SDValue(N, 0);
686a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
687a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      PromScalar = PromoteScalar.getValue();
688bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
68994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDValue zextShuffle =
690ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
691bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                            PromScalar, PromScalar,
692d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel                            SDValue(shufMaskLoad, 0));
69394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel
694a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy2(zextShuffle);
695a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy2.getValue().getNode()))
696a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = SDValue(N, 0);
697a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    else
698a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      zextShuffle = Dummy2.getValue();
699a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
700a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       zextShuffle));
701bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
702a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
703a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SelectCode(Dummy.getValue().getNode());
704a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
705825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
70694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel    SDNode *CGLoad =
707eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
708d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
709a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
710a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
711a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
712bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
713a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
714a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
715a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
716a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
717825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
718d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
719eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
720d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
721a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
722a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
723a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
724bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
725a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
727a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
729825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
730d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel    SDNode *CGLoad =
731eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman            emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
732d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel
733a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
734a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       N->getOperand(0), N->getOperand(1),
735a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                       SDValue(CGLoad, 0)));
736a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode());
737a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SDNode *N = SelectCode(Dummy.getValue().getNode()))
738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner      return N;
739a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    return Dummy.getValue().getNode();
740c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (Opc == ISD::TRUNCATE) {
741eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
742c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
743825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && OpVT == MVT::i32
744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        && Op0.getValueType() == MVT::i64) {
7459de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
7469de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      //
7479de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // Take advantage of the fact that the upper 32 bits are in the
7489de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel      // i32 preferred slot and avoid shuffle gymnastics:
749c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
750c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      if (CN != 0) {
751c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        unsigned shift_amt = unsigned(CN->getZExtValue());
752c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
753c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        if (shift_amt >= 32) {
754c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          SDNode *hi32 =
7551cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                  CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
7561cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                         Op0.getOperand(0), getRC(MVT::i32));
757c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
758c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          shift_amt -= 32;
759c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          if (shift_amt > 0) {
760c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            // Take care of the additional shift, if present:
761825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson            SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
762c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            unsigned Opc = SPU::ROTMAIr32_i32;
7639de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
764c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel            if (Op0.getOpcode() == ISD::SRL)
765c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel              Opc = SPU::ROTMr32;
766c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
767602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman            hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0),
768602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                          shift);
769c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          }
770c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
771c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel          return hi32;
772c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel        }
773c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      }
774c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
77502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SHL) {
776a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
777eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSHLi64(N, OpVT);
77802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRL) {
779a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
780eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRLi64(N, OpVT);
78102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else if (Opc == ISD::SRA) {
782a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (OpVT == MVT::i64)
783eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      return SelectSRAi64(N, OpVT);
7847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FNEG
785825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
786eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    DebugLoc dl = N->getDebugLoc();
7877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // Check if the pattern is a special form of DFNMS:
7887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
789eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    SDValue Op0 = N->getOperand(0);
7907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    if (Op0.getOpcode() == ISD::FSUB) {
7917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      SDValue Op00 = Op0.getOperand(0);
7927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      if (Op00.getOpcode() == ISD::FMUL) {
7937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel        unsigned Opc = SPU::DFNMSf64;
794825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        if (OpVT == MVT::v2f64)
7957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          Opc = SPU::DFNMSv2f64;
7967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
797602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        return CurDAG->getMachineNode(Opc, dl, OpVT,
798602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(0),
799602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op00.getOperand(1),
800602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                      Op0.getOperand(1));
8017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      }
8027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
804825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64);
8057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    SDNode *signMask = 0;
806a82d3f7c57f03457c385add1687319d5c290f867Scott Michel    unsigned Opc = SPU::XORfneg64;
8077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
808825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
809eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
810825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
811a82d3f7c57f03457c385add1687319d5c290f867Scott Michel      Opc = SPU::XORfnegvec;
8127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel      signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
813825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                                 MVT::v2i64,
814eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                                 negConst, negConst).getNode());
8157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
8167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
817602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    return CurDAG->getMachineNode(Opc, dl, OpVT,
818eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                  N->getOperand(0), SDValue(signMask, 0));
8197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (Opc == ISD::FABS) {
820825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    if (OpVT == MVT::f64) {
821825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
822602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
823eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
824825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    } else if (OpVT == MVT::v2f64) {
825825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
826825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
8277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                       absConst, absConst);
828eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman      SDNode *signMask = emitBuildVector(absVec.getNode());
829602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
830eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                                    N->getOperand(0), SDValue(signMask, 0));
8317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel    }
832266bc8f7774b153401e54ed537db299159840981Scott Michel  } else if (Opc == SPUISD::LDRESULT) {
833266bc8f7774b153401e54ed537db299159840981Scott Michel    // Custom select instructions for LDRESULT
834e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    EVT VT = N->getValueType(0);
835475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Arg = N->getOperand(0);
836475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Chain = N->getOperand(1);
837266bc8f7774b153401e54ed537db299159840981Scott Michel    SDNode *Result;
838bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
8398258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila    Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT,
8408258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    MVT::Other, Arg,
8418258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila                                    getRC( VT.getSimpleVT()), Chain);
842266bc8f7774b153401e54ed537db299159840981Scott Michel    return Result;
843bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
844053c1da8d956a794d158ac906b3927c923f97c4dScott Michel  } else if (Opc == SPUISD::IndirectAddr) {
845f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // Look at the operands: SelectCode() will catch the cases that aren't
846f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // specifically handled here.
847f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    //
848f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // SPUInstrInfo catches the following patterns:
849f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect (SPUhi ...), (SPUlo ...))
850f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    // (SPUindirect $sp, imm)
851eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    EVT VT = N->getValueType(0);
852f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op0 = N->getOperand(0);
853f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    SDValue Op1 = N->getOperand(1);
854f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    RegisterSDNode *RN;
855f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel
856f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel    if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
857f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        || (Op0.getOpcode() == ISD::Register
858f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel            && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
859f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel                && RN->getReg() != SPU::R1))) {
860f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      NewOpc = SPU::Ar32;
861d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner      Ops[1] = Op1;
86258c5818c01e375a84dc601140470fa68638004cfScott Michel      if (Op1.getOpcode() == ISD::Constant) {
86358c5818c01e375a84dc601140470fa68638004cfScott Michel        ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
864f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel        Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
865d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        if (isInt<10>(CN->getSExtValue())) {
866d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          NewOpc = SPU::AIr32;
867d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner          Ops[1] = Op1;
868d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        } else {
869bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck          Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl,
870bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                                                  N->getValueType(0),
871d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner                                                  Op1),
872bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck                           0);
873d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner        }
87458c5818c01e375a84dc601140470fa68638004cfScott Michel      }
875f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      Ops[0] = Op0;
876f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel      n_ops = 2;
87758c5818c01e375a84dc601140470fa68638004cfScott Michel    }
878266bc8f7774b153401e54ed537db299159840981Scott Michel  }
87902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
88058c5818c01e375a84dc601140470fa68638004cfScott Michel  if (n_ops > 0) {
88158c5818c01e375a84dc601140470fa68638004cfScott Michel    if (N->hasOneUse())
88258c5818c01e375a84dc601140470fa68638004cfScott Michel      return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
88358c5818c01e375a84dc601140470fa68638004cfScott Michel    else
884602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
88558c5818c01e375a84dc601140470fa68638004cfScott Michel  } else
886eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman    return SelectCode(N);
887266bc8f7774b153401e54ed537db299159840981Scott Michel}
888266bc8f7774b153401e54ed537db299159840981Scott Michel
88902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
89002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm
89102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted
89202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left.
89302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
89402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl.
89502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
89602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
89702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
89802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
89902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
90002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
90102d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
902eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
903eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
904bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
90523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
906eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
907e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
90802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
90902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SelMaskVal;
910eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
91102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9121cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9131cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
914825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
915602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal);
916602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT,
917602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                    CurDAG->getTargetConstant(0, OpVT));
918602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman  VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
919602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(ZeroFill, 0),
920602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(VecOp0, 0),
921602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(SelMask, 0));
92202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
92302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
92402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
92502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
92602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
92702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
92802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
929602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT,
930602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
931602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
93202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
93302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
93402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
93502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
936602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT,
937602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
938602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
93902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
94002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
94102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
942602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
943602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
944602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
94502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
946602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
947602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
948602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
94902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
950602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT,
951602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
95202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
953602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT,
954602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
95502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
957bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
9581cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
95902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
96102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
96202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts.
96302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
96502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
96802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
96902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
970eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
971eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue Op0 = N->getOperand(0);
97223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
97323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
974eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
975e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
97602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0, *Shift = 0;
977eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
97802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
9791cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila  VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT,
9801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  Op0, getRC(MVT::v2i64) );
98102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
98402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
98502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
98602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
98702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
988602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT,
989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(VecOp0, 0),
990602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
99402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
995602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT,
996602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : VecOp0), 0),
997602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
100002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bytes =
1001602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT,
1002602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1003602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(3, ShiftAmtVT));
100402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *Bits =
1005602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT,
1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt,
1007602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             CurDAG->getTargetConstant(7, ShiftAmtVT));
100802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    // Ensure that the shift amounts are negated!
1010602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   SDValue(Bytes, 0),
1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                   CurDAG->getTargetConstant(0, ShiftAmtVT));
101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1014602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1015602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  SDValue(Bits, 0),
1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                                  CurDAG->getTargetConstant(0, ShiftAmtVT));
101702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
101802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1019602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT,
1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(VecOp0, 0), SDValue(Bytes, 0));
102102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1022602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT,
1023602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(Bits, 0));
102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1026bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10271cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
102902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
103002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*!
103102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts.
103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel *
103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand
103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but
103502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.)
103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence
103702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */
103802d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode *
1039eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  // Promote Op0 to vector
1041bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
104223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson                               OpVT, (128 / OpVT.getSizeInBits()));
1043eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  SDValue ShiftAmt = N->getOperand(1);
1044e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT ShiftAmtVT = ShiftAmt.getValueType();
1045eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  DebugLoc dl = N->getDebugLoc();
104602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *VecOp0 =
1048bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10491cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           VecVT, N->getOperand(0), getRC(MVT::v2i64));
105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *SignRot =
1053602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64,
1054602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0), SignRotAmt);
105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSign =
1056bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
10571cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                           MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32));
105802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
105902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperHalfSignMask =
1060602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0));
106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerMask =
1062602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT,
1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
106402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *UpperLowerSelect =
1065602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman    CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT,
1066602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperHalfSignMask, 0),
1067602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(VecOp0, 0),
1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                           SDValue(UpperLowerMask, 0));
106902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  SDNode *Shift = 0;
107102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
107302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
107402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    unsigned bits = unsigned(CN->getZExtValue()) & 7;
107502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bytes > 0) {
107702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bytes = 31 - bytes;
107802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1079602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT,
1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue(UpperLowerSelect, 0),
1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bytes, ShiftAmtVT));
108202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
108302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
108402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    if (bits > 0) {
108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      bits = 8 - bits;
108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel      Shift =
1087602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman        CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT,
1088602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
1089602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                               CurDAG->getTargetConstant(bits, ShiftAmtVT));
109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    }
109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  } else {
109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    SDNode *NegShift =
1093602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT,
1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
109602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1097602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT,
1098602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
109902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel    Shift =
1100602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman      CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT,
1101602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman                             SDValue(Shift, 0), SDValue(NegShift, 0));
110202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel  }
110302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1104bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11051cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                OpVT, SDValue(Shift, 0), getRC(MVT::i64));
110602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel}
110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel
1108c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*!
1109c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant
1110c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */
1111eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
11127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
1113eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman  ConstantSDNode *CN = cast<ConstantSDNode>(N);
11147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
11157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel}
11167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel
1117e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
11187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel                                           DebugLoc dl) {
111923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson  EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2);
1120c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  SDValue i64vec =
11217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel          SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl);
1122c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1123c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // Here's where it gets interesting, because we have to parse out the
1124c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  // subtree handed back in i64vec:
1125c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1126bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck  if (i64vec.getOpcode() == ISD::BITCAST) {
1127c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // The degenerate case where the upper and lower bits in the splat are
1128c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    // identical:
1129c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue Op0 = i64vec.getOperand(0);
1130c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
11319de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel    ReplaceUses(i64vec, Op0);
11321cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(Op0.getNode()), 0),
11341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1135c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else if (i64vec.getOpcode() == SPUISD::SHUFB) {
1136c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue lhs = i64vec.getOperand(0);
1137c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue rhs = i64vec.getOperand(1);
1138c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDValue shufmask = i64vec.getOperand(2);
1139c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1140bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (lhs.getOpcode() == ISD::BITCAST) {
1141c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(lhs, lhs.getOperand(0));
1142c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      lhs = lhs.getOperand(0);
1143c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1144c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1145c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
1146c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? lhs.getNode()
1147eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(lhs.getNode()));
1148c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1149bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (rhs.getOpcode() == ISD::BITCAST) {
1150c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(rhs, rhs.getOperand(0));
1151c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      rhs = rhs.getOperand(0);
1152c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1153c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1154c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
1155c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                       ? rhs.getNode()
1156eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                       : emitBuildVector(rhs.getNode()));
11579de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel
1158bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    if (shufmask.getOpcode() == ISD::BITCAST) {
1159c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      ReplaceUses(shufmask, shufmask.getOperand(0));
1160c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel      shufmask = shufmask.getOperand(0);
1161c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    }
1162c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1163c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel    SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
1164c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                            ? shufmask.getNode()
1165eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman                            : emitBuildVector(shufmask.getNode()));
1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
1167a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner   SDValue shufNode =
1168a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner            CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
1169c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel                                   SDValue(lhsNode, 0), SDValue(rhsNode, 0),
1170a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner                                   SDValue(shufMaskNode, 0));
1171a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    HandleSDNode Dummy(shufNode);
1172a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    SDNode *SN = SelectCode(Dummy.getValue().getNode());
1173a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner    if (SN == 0) SN = Dummy.getValue().getNode();
1174bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck
1175bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl,
11761cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  OpVT, SDValue(SN, 0), getRC(MVT::i64));
11777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel  } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
11781cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila    return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT,
11791cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  SDValue(emitBuildVector(i64vec.getNode()), 0),
11801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila                                  getRC(MVT::i64));
1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  } else {
118275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
1183dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin                      "condition");
1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel  }
1185c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel}
1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel
118702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a
1188266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling.
1189266bc8f7774b153401e54ed537db299159840981Scott Michel///
1190266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
1191266bc8f7774b153401e54ed537db299159840981Scott Michel  return new SPUDAGToDAGISel(TM);
1192266bc8f7774b153401e54ed537db299159840981Scott Michel}
1193