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