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