SPUISelDAGToDAG.cpp revision 1cd1b0b283079b5a8c54759983e9e70845971b2c
14ee451de366474b9c228b4e5fa573795a715216dChris Lattner//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===// 2266bc8f7774b153401e54ed537db299159840981Scott Michel// 3266bc8f7774b153401e54ed537db299159840981Scott Michel// The LLVM Compiler Infrastructure 4266bc8f7774b153401e54ed537db299159840981Scott Michel// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7266bc8f7774b153401e54ed537db299159840981Scott Michel// 8266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===// 9266bc8f7774b153401e54ed537db299159840981Scott Michel// 10266bc8f7774b153401e54ed537db299159840981Scott Michel// This file defines a pattern matching instruction selector for the Cell SPU, 11266bc8f7774b153401e54ed537db299159840981Scott Michel// converting from a legalized dag to a SPU-target dag. 12266bc8f7774b153401e54ed537db299159840981Scott Michel// 13266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===// 14266bc8f7774b153401e54ed537db299159840981Scott Michel 15266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPU.h" 16266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUTargetMachine.h" 17266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h" 18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h" 19203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h" 2094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h" 21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h" 22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h" 23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h" 24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h" 25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h" 2694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h" 27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h" 28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h" 29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h" 30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h" 31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h" 32a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h" 33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h" 34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 35266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 37dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 38266bc8f7774b153401e54ed537db299159840981Scott Michel 39266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 40266bc8f7774b153401e54ed537db299159840981Scott Michel 41266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 42266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 43266bc8f7774b153401e54ed537db299159840981Scott Michel bool 44266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 45266bc8f7774b153401e54ed537db299159840981Scott Michel { 467e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer return isInt<10>(CN->getSExtValue()); 47266bc8f7774b153401e54ed537db299159840981Scott Michel } 48266bc8f7774b153401e54ed537db299159840981Scott Michel 49504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 50504c369213efb263136bb048e79af3516511c040Scott Michel bool 51504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 52504c369213efb263136bb048e79af3516511c040Scott Michel { 5334247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer return isUInt<10>(CN->getSExtValue()); 54504c369213efb263136bb048e79af3516511c040Scott Michel } 55504c369213efb263136bb048e79af3516511c040Scott Michel 56266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 57266bc8f7774b153401e54ed537db299159840981Scott Michel bool 58266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 59266bc8f7774b153401e54ed537db299159840981Scott Michel { 607e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer return isInt<10>(CN->getSExtValue()); 61266bc8f7774b153401e54ed537db299159840981Scott Michel } 62266bc8f7774b153401e54ed537db299159840981Scott Michel 63ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 64ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 65ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 66ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 6734247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer return isUInt<10>((short) CN->getZExtValue()); 68ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 69ec2a08ff061af36b46160e475362959f21663e76Scott Michel 70266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 71266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 72266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 73266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 74266bc8f7774b153401e54ed537db299159840981Scott Michel 75266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 76266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 77266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 78266bc8f7774b153401e54ed537db299159840981Scott Michel */ 79266bc8f7774b153401e54ed537db299159840981Scott Michel bool 80266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 81266bc8f7774b153401e54ed537db299159840981Scott Michel { 82e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = CN->getValueType(0); 83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 85266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 86825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (vt == MVT::i32) { 87f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 88266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 89266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 90266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 91f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 92266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 93266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 94266bc8f7774b153401e54ed537db299159840981Scott Michel } 95266bc8f7774b153401e54ed537db299159840981Scott Michel 96266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 97266bc8f7774b153401e54ed537db299159840981Scott Michel } 98266bc8f7774b153401e54ed537db299159840981Scott Michel 99266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 100266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 101266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 102266bc8f7774b153401e54ed537db299159840981Scott Michel { 103e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = FPN->getValueType(0); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt == MVT::f32) { 105d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 106266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 107266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 108266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 109266bc8f7774b153401e54ed537db299159840981Scott Michel } 110266bc8f7774b153401e54ed537db299159840981Scott Michel 111266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 112266bc8f7774b153401e54ed537db299159840981Scott Michel } 113266bc8f7774b153401e54ed537db299159840981Scott Michel 114266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 115e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson //! EVT to "useful stuff" mapping structure: 116266bc8f7774b153401e54ed537db299159840981Scott Michel 117266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 118e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT; 1197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 120a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 121f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel unsigned lrinst; /// LR instruction 122266bc8f7774b153401e54ed537db299159840981Scott Michel }; 123266bc8f7774b153401e54ed537db299159840981Scott Michel 124266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, 126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, 13158c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v16i8, 0, false, SPU::LRv16i8 }, 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v8i16, 0, false, SPU::LRv8i16 }, 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v4i32, 0, false, SPU::LRv4i32 }, 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v2i64, 0, false, SPU::LRv2i64 }, 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v4f32, 0, false, SPU::LRv4f32 }, 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v2f64, 0, false, SPU::LRv2f64 } 138266bc8f7774b153401e54ed537db299159840981Scott Michel }; 139266bc8f7774b153401e54ed537db299159840981Scott Michel 140266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 141266bc8f7774b153401e54ed537db299159840981Scott Michel 142e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson const valtype_map_s *getValueTypeMapEntry(EVT VT) 143266bc8f7774b153401e54ed537db299159840981Scott Michel { 144266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 145266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 146266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1487f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 149266bc8f7774b153401e54ed537db299159840981Scott Michel } 150266bc8f7774b153401e54ed537db299159840981Scott Michel } 151266bc8f7774b153401e54ed537db299159840981Scott Michel 152266bc8f7774b153401e54ed537db299159840981Scott Michel 153266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 154266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 1551bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer report_fatal_error("SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns" 1561bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer "NULL for " + Twine(VT.getEVTString())); 157266bc8f7774b153401e54ed537db299159840981Scott Michel } 158266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 159266bc8f7774b153401e54ed537db299159840981Scott Michel 160266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 161266bc8f7774b153401e54ed537db299159840981Scott Michel } 162266bc8f7774b153401e54ed537db299159840981Scott Michel 1637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the carry-generate shuffle mask. 1647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 1657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 166844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 1677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 1687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 169825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 170825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 171825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 17302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 176266bc8f7774b153401e54ed537db299159840981Scott Michel } 177266bc8f7774b153401e54ed537db299159840981Scott Michel 1787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the borrow-generate shuffle mask 1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 1807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 1817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 1837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 1887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 191266bc8f7774b153401e54ed537db299159840981Scott Michel } 19202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //===------------------------------------------------------------------===// 1947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 1957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// instructions for SelectionDAG operations. 1967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// 1977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel class SPUDAGToDAGISel : 1987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public SelectionDAGISel 1997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { 200d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SPUTargetMachine &TM; 201d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SPUTargetLowering &SPUtli; 2027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned GlobalBaseReg; 2037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public: 2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 2067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel(tm), 2077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel TM(tm), 2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli(*tm.getTargetLowering()) 2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { } 2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 211ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman virtual bool runOnMachineFunction(MachineFunction &MF) { 2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Make sure we re-emit a set of the global base reg if necessary 2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel GlobalBaseReg = 0; 214ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman SelectionDAGISel::runOnMachineFunction(MF); 2157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return true; 216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 217266bc8f7774b153401e54ed537db299159840981Scott Michel 2187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 2197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i32. 2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI32Imm(uint32_t Imm) { 221825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return CurDAG->getTargetConstant(Imm, MVT::i32); 22294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } 22394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getSmallIPtrImm(unsigned Imm) { 2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 22717aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner } 2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 229eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *emitBuildVector(SDNode *bvNode) { 230eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT vecVT = bvNode->getValueType(0); 2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = bvNode->getDebugLoc(); 2327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check to see if this vector can be represented as a CellSPU immediate 2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // constant by invoking all of the instruction selection predicates: 235825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (((vecVT == MVT::v8i16) && 236825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 237825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v4i32) && 238825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 239825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 240825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 242825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v2i64) && 243825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 244825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 245a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) { 246a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(SDValue(bvNode, 0)); 247a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = Select(bvNode)) 248a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 249a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 250a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner } 2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // No, need to emit a constant pool spill: 2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<Constant*> CV; 2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 255eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman for (size_t i = 0; i < bvNode->getNumOperands(); ++i) { 256b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i)); 257a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 2597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 26046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Constant *CP = ConstantVector::get(CV); 2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CGPoolOffset = 264d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SPU::LowerConstantPool(CPIdx, *CurDAG, TM); 265a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 266a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl, 267a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->getEntryNode(), CGPoolOffset, 268a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PseudoSourceValue::getConstantPool(),0, 269a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner false, false, Alignment)); 270a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue()); 271a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 272a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 273a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Select - Convert the specified operand from a target-independent to a 2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// target-specific node if it hasn't already been changed. 278eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *Select(SDNode *N); 2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 shl 281eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSHLi64(SDNode *N, EVT OpVT); 2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 srl 284eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSRLi64(SDNode *N, EVT OpVT); 2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 sra 287eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSRAi64(SDNode *N, EVT OpVT); 2887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the necessary sequence for loading i64 constants: 290eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl); 2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Alternate instruction emit sequence for loading i64 constants 293e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl); 2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Returns true if the address N is an A-form (local store) address 296eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! D-form address predicate 300eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Alternate D-form address using i7 offset predicate 304eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base); 3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// D-form address selection workhorse 308eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp, 3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base, int minOffset, int maxOffset); 3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 312eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// inline asm expressions. 3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel char ConstraintCode, 3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<SDValue> &OutOps) { 3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0, Op1; 3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel switch (ConstraintCode) { 3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel default: return true; 3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'm': // memory 324eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 325eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) 326eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SelectXFormAddr(Op.getNode(), Op, Op0, Op1); 3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'o': // offsetable 329eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 330eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) { 3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0 = Op; 3327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op1 = getSmallIPtrImm(0); 3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'v': // not offsetable 336266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 337c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled."); 338266bc8f7774b153401e54ed537db299159840981Scott Michel#else 3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 340266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 34302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op0); 3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op1); 3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return false; 3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 348266bc8f7774b153401e54ed537db299159840981Scott Michel 3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual const char *getPassName() const { 3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 35202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// this target when scheduling the DAG. 3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel const TargetInstrInfo *II = TM.getInstrInfo(); 3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(II && "No InstrInfo?"); 3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return new SPUHazardRecognizer(*II); 3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3601cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila 3611cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila private: 3621cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila SDValue getRC( MVT ); 363266bc8f7774b153401e54ed537db299159840981Scott Michel 3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Include the pieces autogenerated from the target description. 365266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel }; 367844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 368844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 369266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 3709de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand 371266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 372266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 373266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 374266bc8f7774b153401e54ed537db299159840981Scott Michel */ 375266bc8f7774b153401e54ed537db299159840981Scott Michelbool 376eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 377475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 378266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 379825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EVT OffsVT = MVT::i16; 380475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 381266bc8f7774b153401e54ed537db299159840981Scott Michel 382266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 383266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 3849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 3859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 38675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered."); 3879de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 3889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 3909de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 39275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global " 393dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "not wrapped as A-form address."); 394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 395266bc8f7774b153401e54ed537db299159840981Scott Michel 39602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel case SPUISD::AFormAddr: 397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 400475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 407053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 408053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 409053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 41046510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = GSDN->getGlobal(); 411053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 412053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 413053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 414053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 415053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 416053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 417053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 418053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 419053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 420053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 422266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 423266bc8f7774b153401e54ed537db299159840981Scott Michel} 424266bc8f7774b153401e54ed537db299159840981Scott Michel 42502d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool 426eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 427475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 428203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 429203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 430203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 431203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 434266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 435266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 436266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 437266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 438266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 439266bc8f7774b153401e54ed537db299159840981Scott Michel 440266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 441266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 442266bc8f7774b153401e54ed537db299159840981Scott Michel 443266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 444475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 445266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 446266bc8f7774b153401e54ed537db299159840981Scott Michelbool 447eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 448475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 4497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 4509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 4519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 4527f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4537f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 4547f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 455eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, 456475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 4577f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 458266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 459e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PtrTy = SPUtli.getPointerTy(); 460266bc8f7774b153401e54ed537db299159840981Scott Michel 461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 463b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N); 464203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4654437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = " 466203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 467203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 468266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 469203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 470266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 471266bc8f7774b153401e54ed537db299159840981Scott Michel } 472266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 473266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 474475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 475475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 476266bc8f7774b153401e54ed537db299159840981Scott Michel 477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 479053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 480053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 481053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 482053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 484b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 4857810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 486266bc8f7774b153401e54ed537db299159840981Scott Michel 487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 488b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0); 489203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4904437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 491203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 4929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 493203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 4949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 4969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 4999de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 500053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 502053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 503053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 504053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 505b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 5067810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 509b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1); 510203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5114437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 512203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 513053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 514203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 516203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 521053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 522053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 523266bc8f7774b153401e54ed537db299159840981Scott Michel } 524497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 525053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 526053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 527475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 528475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 529053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 532053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5339de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5359de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 538475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5417f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 5427810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 5447f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 5457f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 5467810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 54802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 5497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5507f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 5517f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 5527f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 5537f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 5547f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5559de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 556053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 55958c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 5607f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 5617f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 5627f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 5637f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 564c6166c6bcaf41acab5f14aa267acec3214b75127Kalle Raiskila } else if (Opc == ISD::Register 565c6166c6bcaf41acab5f14aa267acec3214b75127Kalle Raiskila ||Opc == ISD::CopyFromReg 566bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila ||Opc == ISD::UNDEF 567bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila ||Opc == ISD::Constant) { 568eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman unsigned OpOpc = Op->getOpcode(); 5699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5709c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 5719c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 57211fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila SDValue Offs; 5739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 574eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2)); 5759c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5769c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 5779c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 5789c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 5799c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5809c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 58111fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila Index = N; 5829c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 5839c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 584aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 585aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 586aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 58719c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N.getOperand(1); 588aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 58919c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N; 590aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 591aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 592aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 593aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 5949c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 595266bc8f7774b153401e54ed537db299159840981Scott Michel } 5969c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 597266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 598266bc8f7774b153401e54ed537db299159840981Scott Michel} 599266bc8f7774b153401e54ed537db299159840981Scott Michel 600266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 601266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 602266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 603266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 604266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 605266bc8f7774b153401e54ed537db299159840981Scott Michel 6069c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 6079c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 6089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 609266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 610266bc8f7774b153401e54ed537db299159840981Scott Michelbool 611eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 612475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 6139c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 6149c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 61518fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 61618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 6171a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 6181a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 61950843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 6209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 621266bc8f7774b153401e54ed537db299159840981Scott Michel 6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 62358c5818c01e375a84dc601140470fa68638004cfScott Michel} 62458c5818c01e375a84dc601140470fa68638004cfScott Michel 6251cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*! 6261cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue 6271cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a 6281cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call 6291cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class 6301cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/ 6311cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) { 6321cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila switch( VT.SimpleTy ) { 6331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::i32: 6341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32); 6351cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila break; 6361cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::i64: 6371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32); 6381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila break; 6391cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::v2i64: 6401cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32); 6411cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila break; 6421cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila default: 6431cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila assert( false && "add a new case here" ); 6441cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila } 6451cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return SDValue(); 6461cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila} 6471cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila 648266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 649266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 650266bc8f7774b153401e54ed537db299159840981Scott Michel */ 651266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 652eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) { 653266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 65458c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 65558c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 656eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT OpVT = N->getValueType(0); 657475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 658ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = N->getDebugLoc(); 659266bc8f7774b153401e54ed537db299159840981Scott Michel 660a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (N->isMachineOpcode()) 661266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 662c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 663c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Opc == ISD::FrameIndex) { 66402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 665eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); 666eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0)); 66702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 66802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (FI < 128) { 669203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 67002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = TFI; 67102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[1] = Imm0; 672203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 673203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 674203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 675eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0)); 676602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, 677eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getValueType(0), TFI, Imm0), 678602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman 0); 679203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 680203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 682c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Catch the i64 constants that end up here. Note: The backend doesn't 683c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // attempt to legalize the constant (it's useless because DAGCombiner 684c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // will insert 64-bit constants and we can't stop it). 685eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectI64Constant(N, OpVT, N->getDebugLoc()); 68694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 687825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i64) { 688eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 689e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT Op0VT = Op0.getValueType(); 69023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), 69123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson Op0VT, (128 / Op0VT.getSizeInBits())); 69223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), 69323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 69494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue shufMask; 69594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 696825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Op0VT.getSimpleVT().SimpleTy) { 69794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel default: 69875361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT"); 69994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel /*NOTREACHED*/ 700825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 701825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 702825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 703825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x00010203, MVT::i32), 704825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 705825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x08090a0b, MVT::i32)); 70694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 70794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 708825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 709825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 710825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 711825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800203, MVT::i32), 712825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 713825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800a0b, MVT::i32)); 71494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 71594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 716825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: 717825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 718825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 719825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808003, MVT::i32), 720825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 721825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x8080800b, MVT::i32)); 72294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 72358c5818c01e375a84dc601140470fa68638004cfScott Michel } 72494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 725eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode()); 726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 727a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, 728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner Op0VecVT, Op0)); 729a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 730a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue PromScalar; 731a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode())) 732a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PromScalar = SDValue(N, 0); 733a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner else 734a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PromScalar = PromoteScalar.getValue(); 735a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 73694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue zextShuffle = 737ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PromScalar, PromScalar, 739d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(shufMaskLoad, 0)); 74094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 741a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy2(zextShuffle); 742a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy2.getValue().getNode())) 743a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle = SDValue(N, 0); 744a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner else 745a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle = Dummy2.getValue(); 746a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 747a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle)); 748a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 749a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 750a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SelectCode(Dummy.getValue().getNode()); 751a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 752825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 75394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *CGLoad = 754eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 755d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 756a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 757a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 758a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 759a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 760a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 761a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 762a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 763a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 764825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 765d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 766eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode()); 767d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 768a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 769a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 770a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 771a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 772a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 773a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 774a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 775a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 776825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 777d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 778eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 779d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 780a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 781a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 782a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 783a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 784a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 785a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 786a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 787c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::TRUNCATE) { 788eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 789c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 790825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i32 791825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && Op0.getValueType() == MVT::i64) { 7929de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 7939de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // 7949de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Take advantage of the fact that the upper 32 bits are in the 7959de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // i32 preferred slot and avoid shuffle gymnastics: 796c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 797c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (CN != 0) { 798c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned shift_amt = unsigned(CN->getZExtValue()); 799c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 800c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt >= 32) { 801c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *hi32 = 8021cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 8031cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0.getOperand(0), getRC(MVT::i32)); 804c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 805c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shift_amt -= 32; 806c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt > 0) { 807c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Take care of the additional shift, if present: 808825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 809c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned Opc = SPU::ROTMAIr32_i32; 8109de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Op0.getOpcode() == ISD::SRL) 812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Opc = SPU::ROTMr32; 813c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 814602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0), 815602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman shift); 816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 817c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 818c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel return hi32; 819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 821c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 82202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SHL) { 823a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 824eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSHLi64(N, OpVT); 82502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRL) { 826a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 827eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSRLi64(N, OpVT); 82802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRA) { 829a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 830eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSRAi64(N, OpVT); 8317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FNEG 832825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 833eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 8347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check if the pattern is a special form of DFNMS: 8357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 836eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 8377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op0.getOpcode() == ISD::FSUB) { 8387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op00 = Op0.getOperand(0); 8397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op00.getOpcode() == ISD::FMUL) { 8407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Opc = SPU::DFNMSf64; 841825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::v2f64) 8427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Opc = SPU::DFNMSv2f64; 8437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 844602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 845602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(0), 846602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(1), 847602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op0.getOperand(1)); 8487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 851825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = 0; 853a82d3f7c57f03457c385add1687319d5c290f867Scott Michel unsigned Opc = SPU::XORfneg64; 8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 855825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 856eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl); 857825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 858a82d3f7c57f03457c385add1687319d5c290f867Scott Michel Opc = SPU::XORfnegvec; 8597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 860825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::v2i64, 861eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman negConst, negConst).getNode()); 8627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 864602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 865eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FABS) { 867825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 868825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 869602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT, 870eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 871825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 872825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 873825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 8747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel absConst, absConst); 875eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *signMask = emitBuildVector(absVec.getNode()); 876602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT, 877eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 8787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 879266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 880266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 881e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = N->getValueType(0); 882475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 883475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 884266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 885a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 886a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 887a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 8881bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer report_fatal_error("LDRESULT for unsupported type: " + 8891bd7335a17010bd4d8f86736cf73cac9f3fb80a5Benjamin Kramer Twine(VT.getEVTString())); 890a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel } 891266bc8f7774b153401e54ed537db299159840981Scott Michel 892a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel Opc = vtm->ldresult_ins; 893a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_imm) { 894475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, VT); 89586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 896602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain); 89786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 898602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain); 89986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 90086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 901266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 902053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 903f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // Look at the operands: SelectCode() will catch the cases that aren't 904f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // specifically handled here. 905f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // 906f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // SPUInstrInfo catches the following patterns: 907f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect (SPUhi ...), (SPUlo ...)) 908f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect $sp, imm) 909eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT VT = N->getValueType(0); 910f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op0 = N->getOperand(0); 911f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op1 = N->getOperand(1); 912f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel RegisterSDNode *RN; 913f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel 914f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 915f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel || (Op0.getOpcode() == ISD::Register 916f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 917f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && RN->getReg() != SPU::R1))) { 918f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel NewOpc = SPU::Ar32; 919d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Ops[1] = Op1; 92058c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 92158c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 922f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 923d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner if (isInt<10>(CN->getSExtValue())) { 924d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner NewOpc = SPU::AIr32; 925d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Ops[1] = Op1; 926d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner } else { 927d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, 928d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner N->getValueType(0), 929d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Op1), 930d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner 0); 931d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner } 93258c5818c01e375a84dc601140470fa68638004cfScott Michel } 933f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[0] = Op0; 934f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel n_ops = 2; 93558c5818c01e375a84dc601140470fa68638004cfScott Michel } 936266bc8f7774b153401e54ed537db299159840981Scott Michel } 93702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 93858c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 93958c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 94058c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 94158c5818c01e375a84dc601140470fa68638004cfScott Michel else 942602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops); 94358c5818c01e375a84dc601140470fa68638004cfScott Michel } else 944eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectCode(N); 945266bc8f7774b153401e54ed537db299159840981Scott Michel} 946266bc8f7774b153401e54ed537db299159840981Scott Michel 94702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 94802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm 94902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted 95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left. 95102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 95202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl. 95302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 95402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 95502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 95702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 95802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 95902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 960eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { 961eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 96223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 96323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 964eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 965e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SelMaskVal; 968eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 96902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 9701cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 9711cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0, getRC(MVT::v2i64) ); 972825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 973602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); 974602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT, 975602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, OpVT)); 976602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 977602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(ZeroFill, 0), 978602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 979602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(SelMask, 0)); 98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 98102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 98402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 98502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 98602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 987602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT, 988602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 99002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 994602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT, 995602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 996602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1000602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1001602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1002602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 100302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1004602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1005602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 100702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1008602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT, 1009602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT, 1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 10151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 10161cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 101702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 101802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 102002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts. 102102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 102202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 102302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 102702d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 1028eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { 1029eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 103023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 103123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 1032eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 1033e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *Shift = 0; 1035eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 10371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 10381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0, getRC(MVT::v2i64) ); 103902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 104102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 104202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 104402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1046602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT, 1047602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1048602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1053602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT, 1054602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 1055602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 105602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 105702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 105802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1059602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1060602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1061602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1064602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1065602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Ensure that the shift amounts are negated! 1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bytes, 0), 1070602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 107102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1072602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1073602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bits, 0), 1074602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 107502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1077602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT, 1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT, 1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 108202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 108302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 10841cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 10851cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 108802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts. 109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 109402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 109602d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 1097eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { 109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Promote Op0 to vector 109923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 110023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 1101eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 1102e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 1103eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 110502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0 = 11061cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 11071cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecVT, N->getOperand(0), getRC(MVT::v2i64)); 110802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 110902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *SignRot = 1111602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, 1112602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SignRotAmt); 111302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSign = 11141cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 11151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32)); 111602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSignMask = 1118602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); 111902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerMask = 1120602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, 1121602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 112202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerSelect = 1123602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 1124602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperHalfSignMask, 0), 1125602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1126602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerMask, 0)); 112702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 112802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Shift = 0; 112902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 113002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 113102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 113202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 113302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 113402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 113502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bytes = 31 - bytes; 113602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1137602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT, 1138602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), 1139602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 114002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 114102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 114202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 114302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bits = 8 - bits; 114402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1145602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT, 1146602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 1147602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 114802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 114902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 115002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *NegShift = 1151602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1152602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 115302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 115402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1155602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT, 1156602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 115702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1158602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT, 1159602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(NegShift, 0)); 116002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 116102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 11621cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 11631cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 116402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 116502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*! 1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant 1168c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */ 1169eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT, 11707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 1171eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(N); 11727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(CN->getZExtValue(), OpVT, dl); 11737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel} 11747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1175e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, 11767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 117723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2); 1178c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue i64vec = 11797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl); 1180c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Here's where it gets interesting, because we have to parse out the 1182c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // subtree handed back in i64vec: 1183c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (i64vec.getOpcode() == ISD::BIT_CONVERT) { 1185c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // The degenerate case where the upper and lower bits in the splat are 1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // identical: 1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = i64vec.getOperand(0); 1188c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 11899de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ReplaceUses(i64vec, Op0); 11901cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 11911cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila SDValue(emitBuildVector(Op0.getNode()), 0), 11921cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila getRC(MVT::i64)); 1193c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 1194c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue lhs = i64vec.getOperand(0); 1195c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue rhs = i64vec.getOperand(1); 1196c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shufmask = i64vec.getOperand(2); 1197c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1198c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (lhs.getOpcode() == ISD::BIT_CONVERT) { 1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(lhs, lhs.getOperand(0)); 1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel lhs = lhs.getOperand(0); 1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1202c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1203c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 1204c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? lhs.getNode() 1205eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(lhs.getNode())); 1206c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1207c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (rhs.getOpcode() == ISD::BIT_CONVERT) { 1208c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(rhs, rhs.getOperand(0)); 1209c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel rhs = rhs.getOperand(0); 1210c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1211c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1212c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 1213c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? rhs.getNode() 1214eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(rhs.getNode())); 12159de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 1216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shufmask.getOpcode() == ISD::BIT_CONVERT) { 1217c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(shufmask, shufmask.getOperand(0)); 1218c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shufmask = shufmask.getOperand(0); 1219c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1220c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1221c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 1222c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? shufmask.getNode() 1223eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(shufmask.getNode())); 1224c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1225a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue shufNode = 1226a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 1227c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(lhsNode, 0), SDValue(rhsNode, 0), 1228a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(shufMaskNode, 0)); 1229a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(shufNode); 1230a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDNode *SN = SelectCode(Dummy.getValue().getNode()); 1231a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SN == 0) SN = Dummy.getValue().getNode(); 1232a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner 12331cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 12341cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(SN, 0), getRC(MVT::i64)); 12357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { 12361cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 12371cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila SDValue(emitBuildVector(i64vec.getNode()), 0), 12381cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila getRC(MVT::i64)); 1239c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else { 124075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" 1241dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "condition"); 1242c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1243c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel} 1244c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 124502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a 1246266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 1247266bc8f7774b153401e54ed537db299159840981Scott Michel/// 1248266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 1249266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 1250266bc8f7774b153401e54ed537db299159840981Scott Michel} 1251