SPUISelDAGToDAG.cpp revision c23197a26f34f559ea9797de51e187087c039c42
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 "SPUISelLowering.h" 18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h" 19266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h" 20203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h" 2194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h" 22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h" 23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h" 24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h" 25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h" 26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h" 2794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h" 28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h" 29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h" 30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h" 31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h" 32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.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 isI64IntS10Immediate(ConstantSDNode *CN) 45266bc8f7774b153401e54ed537db299159840981Scott Michel { 467810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 47266bc8f7774b153401e54ed537db299159840981Scott Michel } 48266bc8f7774b153401e54ed537db299159840981Scott Michel 49266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 50266bc8f7774b153401e54ed537db299159840981Scott Michel bool 51266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 52266bc8f7774b153401e54ed537db299159840981Scott Michel { 537810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 54266bc8f7774b153401e54ed537db299159840981Scott Michel } 55266bc8f7774b153401e54ed537db299159840981Scott Michel 56504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 57504c369213efb263136bb048e79af3516511c040Scott Michel bool 58504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 59504c369213efb263136bb048e79af3516511c040Scott Michel { 607810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isU10Constant(CN->getSExtValue()); 61504c369213efb263136bb048e79af3516511c040Scott Michel } 62504c369213efb263136bb048e79af3516511c040Scott Michel 63266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 64266bc8f7774b153401e54ed537db299159840981Scott Michel bool 65266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 66266bc8f7774b153401e54ed537db299159840981Scott Michel { 677810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 68266bc8f7774b153401e54ed537db299159840981Scott Michel } 69266bc8f7774b153401e54ed537db299159840981Scott Michel 70266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 71266bc8f7774b153401e54ed537db299159840981Scott Michel bool 72266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(SDNode *N) 73266bc8f7774b153401e54ed537db299159840981Scott Michel { 749de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); 759de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel return (CN != 0 && isI16IntS10Immediate(CN)); 76266bc8f7774b153401e54ed537db299159840981Scott Michel } 77266bc8f7774b153401e54ed537db299159840981Scott Michel 78ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 79ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 80ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 81ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 82f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return isU10Constant((short) CN->getZExtValue()); 83ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 84ec2a08ff061af36b46160e475362959f21663e76Scott Michel 85ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 86ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 87ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(SDNode *N) 88ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 89ec2a08ff061af36b46160e475362959f21663e76Scott Michel return (N->getOpcode() == ISD::Constant 90ec2a08ff061af36b46160e475362959f21663e76Scott Michel && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 91ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 92ec2a08ff061af36b46160e475362959f21663e76Scott Michel 93266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 94266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 95266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 96266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 97266bc8f7774b153401e54ed537db299159840981Scott Michel 98266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 99266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 100266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 101266bc8f7774b153401e54ed537db299159840981Scott Michel */ 102266bc8f7774b153401e54ed537db299159840981Scott Michel bool 103266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 104266bc8f7774b153401e54ed537db299159840981Scott Michel { 10583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = CN->getValueType(0); 106f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 1078e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 108266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 109266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (vt == MVT::i32) { 110f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 111266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 112266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 113266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 114f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 115266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 116266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 117266bc8f7774b153401e54ed537db299159840981Scott Michel } 118266bc8f7774b153401e54ed537db299159840981Scott Michel 119266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 120266bc8f7774b153401e54ed537db299159840981Scott Michel } 121266bc8f7774b153401e54ed537db299159840981Scott Michel 122266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for signed 16-bit values. 123266bc8f7774b153401e54ed537db299159840981Scott Michel bool 124266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(SDNode *N, short &Imm) 125266bc8f7774b153401e54ed537db299159840981Scott Michel { 126266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 127266bc8f7774b153401e54ed537db299159840981Scott Michel && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 128266bc8f7774b153401e54ed537db299159840981Scott Michel } 129266bc8f7774b153401e54ed537db299159840981Scott Michel 130266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 131266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 132266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 133266bc8f7774b153401e54ed537db299159840981Scott Michel { 13483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = FPN->getValueType(0); 135266bc8f7774b153401e54ed537db299159840981Scott Michel if (vt == MVT::f32) { 136d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 137266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 138266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 139266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 140266bc8f7774b153401e54ed537db299159840981Scott Michel } 141266bc8f7774b153401e54ed537db299159840981Scott Michel 142266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 143266bc8f7774b153401e54ed537db299159840981Scott Michel } 144266bc8f7774b153401e54ed537db299159840981Scott Michel 145053c1da8d956a794d158ac906b3927c923f97c4dScott Michel bool 14602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel isHighLow(const SDValue &Op) 147053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { 148053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return (Op.getOpcode() == SPUISD::IndirectAddr 149053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 150053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Lo) 151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op.getOperand(0).getOpcode() == SPUISD::Lo 152053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 155266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 15683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands //! MVT to "useful stuff" mapping structure: 157266bc8f7774b153401e54ed537db299159840981Scott Michel 158266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 15983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT; 1607f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 161a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 162f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel unsigned lrinst; /// LR instruction 163266bc8f7774b153401e54ed537db299159840981Scott Michel }; 164266bc8f7774b153401e54ed537db299159840981Scott Michel 165266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 166f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, 167f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, 168f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, 169f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, 170f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, 171f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, 17258c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 173f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v16i8, 0, false, SPU::LRv16i8 }, 174f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v8i16, 0, false, SPU::LRv8i16 }, 175f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v4i32, 0, false, SPU::LRv4i32 }, 176f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v2i64, 0, false, SPU::LRv2i64 }, 177f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v4f32, 0, false, SPU::LRv4f32 }, 178f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v2f64, 0, false, SPU::LRv2f64 } 179266bc8f7774b153401e54ed537db299159840981Scott Michel }; 180266bc8f7774b153401e54ed537db299159840981Scott Michel 181266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 182266bc8f7774b153401e54ed537db299159840981Scott Michel 18383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const valtype_map_s *getValueTypeMapEntry(MVT VT) 184266bc8f7774b153401e54ed537db299159840981Scott Michel { 185266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 186266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 187266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 190266bc8f7774b153401e54ed537db299159840981Scott Michel } 191266bc8f7774b153401e54ed537db299159840981Scott Michel } 192266bc8f7774b153401e54ed537db299159840981Scott Michel 193266bc8f7774b153401e54ed537db299159840981Scott Michel 194266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 195266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 196dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin std::string msg; 197dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin raw_string_ostream Msg(msg); 198dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin Msg << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 199dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin << VT.getMVTString(); 200dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error(Msg.str()); 201266bc8f7774b153401e54ed537db299159840981Scott Michel } 202266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 203266bc8f7774b153401e54ed537db299159840981Scott Michel 204266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 205266bc8f7774b153401e54ed537db299159840981Scott Michel } 206266bc8f7774b153401e54ed537db299159840981Scott Michel 2077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the carry-generate shuffle mask. 2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 210844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 2117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 2147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 2157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 2167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 21702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 220266bc8f7774b153401e54ed537db299159840981Scott Michel } 221266bc8f7774b153401e54ed537db299159840981Scott Michel 2227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the borrow-generate shuffle mask 2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 2297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 2307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 2327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 235266bc8f7774b153401e54ed537db299159840981Scott Michel } 23602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //===------------------------------------------------------------------===// 2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// instructions for SelectionDAG operations. 2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// 2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel class SPUDAGToDAGISel : 2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public SelectionDAGISel 2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { 2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetMachine &TM; 2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetLowering &SPUtli; 2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned GlobalBaseReg; 2477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public: 2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel(tm), 2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel TM(tm), 2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli(*tm.getTargetLowering()) 2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { } 2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool runOnFunction(Function &Fn) { 2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Make sure we re-emit a set of the global base reg if necessary 2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel GlobalBaseReg = 0; 2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel::runOnFunction(Fn); 2597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return true; 260c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 261266bc8f7774b153401e54ed537db299159840981Scott Michel 2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i32. 2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI32Imm(uint32_t Imm) { 2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i32); 26694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } 26794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i64. 2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI64Imm(uint64_t Imm) { 2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i64); 2727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 27394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getSmallIPtrImm(unsigned Imm) { 2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 277266bc8f7774b153401e54ed537db299159840981Scott Michel } 2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *emitBuildVector(SDValue build_vec) { 2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel MVT vecVT = build_vec.getValueType(); 2817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel MVT eltVT = vecVT.getVectorElementType(); 2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *bvNode = build_vec.getNode(); 2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = bvNode->getDebugLoc(); 2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check to see if this vector can be represented as a CellSPU immediate 2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // constant by invoking all of the instruction selection predicates: 2877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (((vecVT == MVT::v8i16) && 2887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 2897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((vecVT == MVT::v4i32) && 2907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((vecVT == MVT::v2i64) && 2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) 2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return Select(build_vec); 2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // No, need to emit a constant pool spill: 3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<Constant*> CV; 3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { 3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i)); 3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue())); 3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Constant *CP = ConstantVector::get(CV); 3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CGPoolOffset = 3127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerConstantPool(CPIdx, *CurDAG, 3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli.getSPUTargetMachine()); 3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl, 3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CurDAG->getEntryNode(), CGPoolOffset, 3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel PseudoSourceValue::getConstantPool(), 0, 3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel false, Alignment)); 3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Select - Convert the specified operand from a target-independent to a 3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// target-specific node if it hasn't already been changed. 3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *Select(SDValue Op); 3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 shl 3257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSHLi64(SDValue &Op, MVT OpVT); 3267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 srl 3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSRLi64(SDValue &Op, MVT OpVT); 3297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 sra 3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSRAi64(SDValue &Op, MVT OpVT); 3327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the necessary sequence for loading i64 constants: 3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectI64Constant(SDValue &Op, MVT OpVT, DebugLoc dl); 3357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Alternate instruction emit sequence for loading i64 constants 3377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectI64Constant(uint64_t i64const, MVT OpVT, DebugLoc dl); 3387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Returns true if the address N is an A-form (local store) address 3407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! D-form address predicate 3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Alternate D-form address using i7 offset predicate 3487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base); 3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// D-form address selection workhorse 3527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base, int minOffset, int maxOffset); 3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 3607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// inline asm expressions. 3617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 3627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel char ConstraintCode, 3637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<SDValue> &OutOps) { 3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0, Op1; 3657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel switch (ConstraintCode) { 3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel default: return true; 3677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'm': // memory 3687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 3707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 3717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'o': // offsetable 3737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 3757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0 = Op; 3767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op1 = getSmallIPtrImm(0); 3777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'v': // not offsetable 380266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 381c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled."); 382266bc8f7774b153401e54ed537db299159840981Scott Michel#else 3837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 384266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 3857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 38702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op0); 3897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op1); 3907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return false; 3917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 392266bc8f7774b153401e54ed537db299159840981Scott Michel 3937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// InstructionSelect - This callback is invoked by 3947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 3957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual void InstructionSelect(); 396266bc8f7774b153401e54ed537db299159840981Scott Michel 3977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual const char *getPassName() const { 3987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 3997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 40002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 4017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 4027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// this target when scheduling the DAG. 4037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 4047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel const TargetInstrInfo *II = TM.getInstrInfo(); 4057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(II && "No InstrInfo?"); 4067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return new SPUHazardRecognizer(*II); 4077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 408266bc8f7774b153401e54ed537db299159840981Scott Michel 4097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Include the pieces autogenerated from the target description. 410266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 4117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel }; 412844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 413844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 414db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by 415266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 416266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 417f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect() 418266bc8f7774b153401e54ed537db299159840981Scott Michel{ 419266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 420266bc8f7774b153401e54ed537db299159840981Scott Michel 421266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 4228ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene SelectRoot(*CurDAG); 423f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman CurDAG->RemoveDeadNodes(); 424266bc8f7774b153401e54ed537db299159840981Scott Michel} 425266bc8f7774b153401e54ed537db299159840981Scott Michel 426266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 4279de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand 428266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 429266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 430266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 431266bc8f7774b153401e54ed537db299159840981Scott Michel */ 432266bc8f7774b153401e54ed537db299159840981Scott Michelbool 433475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 434475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 435266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 43683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OffsVT = MVT::i16; 437475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 438266bc8f7774b153401e54ed537db299159840981Scott Michel 439266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 440266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 4419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 4429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 443dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered."); 4449de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 4479de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 449dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPUSelectAFormAddr: Target Constant/Pool/Global " 450dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "not wrapped as A-form address."); 451053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 452266bc8f7774b153401e54ed537db299159840981Scott Michel 45302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel case SPUISD::AFormAddr: 454053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 456053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 457475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 458053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 474053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 479266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 480266bc8f7774b153401e54ed537db299159840981Scott Michel} 481266bc8f7774b153401e54ed537db299159840981Scott Michel 48202d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool 483475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 484475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 485203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 486203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 487203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 488203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 491266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 492266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 493266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 494266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 495266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 496266bc8f7774b153401e54ed537db299159840981Scott Michel 497266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 498266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 499266bc8f7774b153401e54ed537db299159840981Scott Michel 500266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 501475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 502266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 503266bc8f7774b153401e54ed537db299159840981Scott Michelbool 504475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 505475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 5067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 5079c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 5089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 5097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 5107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 512475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 513475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 5147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 515266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 51683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrTy = SPUtli.getPointerTy(); 517266bc8f7774b153401e54ed537db299159840981Scott Michel 518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 520203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 521203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 522266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 523203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 524203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 525266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 526203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 527266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 528266bc8f7774b153401e54ed537db299159840981Scott Michel } 529266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 530266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 531475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 532475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 533266bc8f7774b153401e54ed537db299159840981Scott Michel 534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 5419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 5427810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 543266bc8f7774b153401e54ed537db299159840981Scott Michel 544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 545203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 546203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5479de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 548203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 5499de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 550203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 5519de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 552203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5539de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5549de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5557f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 5569de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 562053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 5637810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 564053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 565053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 566203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 567203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 568053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 569203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 570053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 571203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 572053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 573203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5749de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 577053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 578053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 579053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 580266bc8f7774b153401e54ed537db299159840981Scott Michel } 581497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 582053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 583053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 584475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 585475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 586053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 589053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5909de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 591053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 595475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 5997810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 6007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 6017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 6027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 6037810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 6047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 60502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 6067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 6077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 6087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 6097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 6107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 6129de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 613053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 614053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 615053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 61658c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 6177f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 6187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 6197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 6207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { 6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel unsigned OpOpc = Op.getOpcode(); 6239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 6259c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 6269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SDValue Addr, Offs; 6279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Get the register from CopyFromReg 6299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Opc == ISD::CopyFromReg) 6309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N.getOperand(1); 6319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel else 6329c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N; // Register 6339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 634aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); 6359c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6369c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 6379c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 6389c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 6399c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6409c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 6419c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Index = Addr; 6429c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 6439c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 644aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 645aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 646aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 64719c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N.getOperand(1); 648aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 64919c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N; 650aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 651aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 652aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 653aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 6549c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 655266bc8f7774b153401e54ed537db299159840981Scott Michel } 6569c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 657266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 658266bc8f7774b153401e54ed537db299159840981Scott Michel} 659266bc8f7774b153401e54ed537db299159840981Scott Michel 660266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 661266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 662266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 663266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 664266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 665266bc8f7774b153401e54ed537db299159840981Scott Michel 6669c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 6679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 6689c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 669266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 670266bc8f7774b153401e54ed537db299159840981Scott Michelbool 671475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 672475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 6739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 6749c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 67518fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 67618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 6771a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 6781a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 67950843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 6809c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 681266bc8f7774b153401e54ed537db299159840981Scott Michel 6829c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 68358c5818c01e375a84dc601140470fa68638004cfScott Michel} 68458c5818c01e375a84dc601140470fa68638004cfScott Michel 685266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 686266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 687266bc8f7774b153401e54ed537db299159840981Scott Michel */ 688266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 689475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) { 690ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *N = Op.getNode(); 691266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 69258c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 69358c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 69483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OpVT = Op.getValueType(); 695475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 696ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = N->getDebugLoc(); 697266bc8f7774b153401e54ed537db299159840981Scott Michel 698e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman if (N->isMachineOpcode()) { 699266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 700c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 701c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 702c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Opc == ISD::FrameIndex) { 70302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 70402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); 70502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); 70602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 70702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (FI < 128) { 708203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 70902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = TFI; 71002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[1] = Imm0; 711203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 712203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 713203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 71402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType()); 715ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Ops[1] = SDValue(CurDAG->getTargetNode(SPU::ILAr32, dl, Op.getValueType(), 71602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel TFI, Imm0), 0); 717203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 718203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 719c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 720c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Catch the i64 constants that end up here. Note: The backend doesn't 721c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // attempt to legalize the constant (it's useless because DAGCombiner 722c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // will insert 64-bit constants and we can't stop it). 7237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(Op, OpVT, Op.getDebugLoc()); 72494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 72594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel && OpVT == MVT::i64) { 72694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue Op0 = Op.getOperand(0); 72794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT Op0VT = Op0.getValueType(); 72894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits())); 72994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT OpVecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 73094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue shufMask; 73194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 73294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel switch (Op0VT.getSimpleVT()) { 73394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel default: 734dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("CellSPU Select: Unhandled zero/any extend MVT"); 73594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel /*NOTREACHED*/ 73694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i32: 737a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 738d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 739d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x00010203, MVT::i32), 740d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 741d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x08090a0b, MVT::i32)); 74294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 74394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 74494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i16: 745a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 746d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 747d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80800203, MVT::i32), 748d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 749d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80800a0b, MVT::i32)); 75094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 75194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 75294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i8: 753a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 754d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 755d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808003, MVT::i32), 756d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 757d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x8080800b, MVT::i32)); 75894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 75958c5818c01e375a84dc601140470fa68638004cfScott Michel } 76094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *shufMaskLoad = emitBuildVector(shufMask); 76294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *PromoteScalar = 763ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0)); 76494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue zextShuffle = 766ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 767d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 768d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 769d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(shufMaskLoad, 0)); 77094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 77194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we 77294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // re-use it in the VEC2PREFSLOT selection without needing to explicitly 77394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // call SelectCode (it's already done for us.) 774046928077645f6ddad839e85dd03ab11e5b22cbcDale Johannesen SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle)); 775ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 77694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel zextShuffle)); 77794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 77894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *CGLoad = 7797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 780d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 781ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 782d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 783d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 784d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 785d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl)); 787d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 788ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 789d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 790d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 791d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 792d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 794d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 795ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 796d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 797d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 798c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::TRUNCATE) { 799c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = Op.getOperand(0); 800c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 801c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel && OpVT == MVT::i32 802c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel && Op0.getValueType() == MVT::i64) { 8039de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 8049de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // 8059de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Take advantage of the fact that the upper 32 bits are in the 8069de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // i32 preferred slot and avoid shuffle gymnastics: 807c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 808c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (CN != 0) { 809c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned shift_amt = unsigned(CN->getZExtValue()); 810c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt >= 32) { 812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *hi32 = 813ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ORr32_r64, dl, OpVT, 814ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Op0.getOperand(0)); 815c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shift_amt -= 32; 817c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt > 0) { 818c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Take care of the additional shift, if present: 819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned Opc = SPU::ROTMAIr32_i32; 8219de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 822c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Op0.getOpcode() == ISD::SRL) 823c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Opc = SPU::ROTMr32; 824c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 825ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen hi32 = CurDAG->getTargetNode(Opc, dl, OpVT, SDValue(hi32, 0), 826ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen shift); 827c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 828c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 829c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel return hi32; 830c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 831c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 832c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 83302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SHL) { 83402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 83502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSHLi64(Op, OpVT); 83602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 83702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRL) { 83802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 83902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRLi64(Op, OpVT); 84002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 84102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRA) { 84202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 84302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRAi64(Op, OpVT); 84402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 8457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FNEG 8467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 8477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = Op.getDebugLoc(); 8487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check if the pattern is a special form of DFNMS: 8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 8507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0 = Op.getOperand(0); 8517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op0.getOpcode() == ISD::FSUB) { 8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op00 = Op0.getOperand(0); 8537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op00.getOpcode() == ISD::FMUL) { 8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Opc = SPU::DFNMSf64; 8557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::v2f64) 8567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Opc = SPU::DFNMSv2f64; 8577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(Opc, dl, OpVT, 8597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op00.getOperand(0), 8607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op00.getOperand(1), 8617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0.getOperand(1)); 8627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = 0; 867a82d3f7c57f03457c385add1687319d5c290f867Scott Michel unsigned Opc = SPU::XORfneg64; 8687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::f64) { 8707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = SelectI64Constant(negConst, MVT::i64, dl); 8717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (OpVT == MVT::v2f64) { 872a82d3f7c57f03457c385add1687319d5c290f867Scott Michel Opc = SPU::XORfnegvec; 8737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 87451b16f473759c1546acbf308a5d3f3e7bf3ea23cBill Wendling MVT::v2i64, 8757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel negConst, negConst)); 8767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(Opc, dl, OpVT, 87951b16f473759c1546acbf308a5d3f3e7bf3ea23cBill Wendling Op.getOperand(0), SDValue(signMask, 0)); 8807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FABS) { 8817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::f64) { 8827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 8837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ANDfabs64, dl, OpVT, 8847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op.getOperand(0), SDValue(signMask, 0)); 8857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (OpVT == MVT::v2f64) { 8867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 8877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 8887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel absConst, absConst); 8897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = emitBuildVector(absVec); 8907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ANDfabsvec, dl, OpVT, 8917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op.getOperand(0), SDValue(signMask, 0)); 8927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 893266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 894266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 89583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = N->getValueType(0); 896475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 897475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 898266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 899a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 900a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 901a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 902dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin std::string msg; 903dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin raw_string_ostream Msg(msg); 904dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin Msg << "LDRESULT for unsupported type: " 905dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin << VT.getMVTString(); 906dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error(Msg.str()); 907a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel } 908266bc8f7774b153401e54ed537db299159840981Scott Michel 909a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel Opc = vtm->ldresult_ins; 910a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_imm) { 911475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, VT); 91286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 913ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Result = CurDAG->getTargetNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain); 91486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 915ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Result = CurDAG->getTargetNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain); 91686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 91786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 918266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 919053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 920f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // Look at the operands: SelectCode() will catch the cases that aren't 921f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // specifically handled here. 922f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // 923f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // SPUInstrInfo catches the following patterns: 924f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect (SPUhi ...), (SPUlo ...)) 925f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect $sp, imm) 926f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel MVT VT = Op.getValueType(); 927f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op0 = N->getOperand(0); 928f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op1 = N->getOperand(1); 929f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel RegisterSDNode *RN; 930f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel 931f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 932f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel || (Op0.getOpcode() == ISD::Register 933f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 934f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && RN->getReg() != SPU::R1))) { 935f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel NewOpc = SPU::Ar32; 93658c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 93758c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 938f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 9397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); 94058c5818c01e375a84dc601140470fa68638004cfScott Michel } 941f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[0] = Op0; 942f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[1] = Op1; 943f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel n_ops = 2; 94458c5818c01e375a84dc601140470fa68638004cfScott Michel } 945266bc8f7774b153401e54ed537db299159840981Scott Michel } 94602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 94758c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 94858c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 94958c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 95058c5818c01e375a84dc601140470fa68638004cfScott Michel else 951ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return CurDAG->getTargetNode(NewOpc, dl, OpVT, Ops, n_ops); 95258c5818c01e375a84dc601140470fa68638004cfScott Michel } else 95358c5818c01e375a84dc601140470fa68638004cfScott Michel return SelectCode(Op); 954266bc8f7774b153401e54ed537db299159840981Scott Michel} 955266bc8f7774b153401e54ed537db299159840981Scott Michel 95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 95702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm 95802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted 95902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left. 96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 96102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl. 96202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 96302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 96502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 96802d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 96902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSPUDAGToDAGISel::SelectSHLi64(SDValue &Op, MVT OpVT) { 97002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Op0 = Op.getOperand(0); 97102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 97202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 97302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT ShiftAmtVT = ShiftAmt.getValueType(); 97402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 97502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SelMaskVal; 976ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 978ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, dl, VecVT, Op0); 97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 980ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen SelMask = CurDAG->getTargetNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); 981ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen ZeroFill = CurDAG->getTargetNode(SPU::ILv2i64, dl, VecVT, 98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(0, OpVT)); 983ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen VecOp0 = CurDAG->getTargetNode(SPU::SELBv2i64, dl, VecVT, 98402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(ZeroFill, 0), 98502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), 98602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(SelMask, 0)); 98702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 98802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 98902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 99002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 994ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SHLQBYIv2i64, dl, VecVT, 99502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), 99602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 100002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1001ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SHLQBIIv2i64, dl, VecVT, 100202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue((Shift != 0 ? Shift : VecOp0), 0), 100302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bits, ShiftAmtVT)); 100402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 100502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 100602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1007ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTMIr32, dl, ShiftAmtVT, 100802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel ShiftAmt, 100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(3, ShiftAmtVT)); 101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1011ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ANDIr32, dl, ShiftAmtVT, 101202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel ShiftAmt, 101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(7, ShiftAmtVT)); 101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1015ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SHLQBYv2i64, dl, VecVT, 101602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), SDValue(Bytes, 0)); 101702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1018ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SHLQBIv2i64, dl, VecVT, 101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(Shift, 0), SDValue(Bits, 0)); 102002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 102102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1022ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 102302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts. 102702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 102902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 103002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 103102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 103302d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 103402d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSPUDAGToDAGISel::SelectSRLi64(SDValue &Op, MVT OpVT) { 103502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Op0 = Op.getOperand(0); 103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 103702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 103802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT ShiftAmtVT = ShiftAmt.getValueType(); 103902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *Shift = 0; 1040ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 104102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1042ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, dl, VecVT, Op0); 104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 104402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 104602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 104802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1050ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQMBYIv2i64, dl, VecVT, 105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), 105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 105302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 105402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 105602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1057ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQMBIIv2i64, dl, VecVT, 105802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue((Shift != 0 ? Shift : VecOp0), 0), 105902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bits, ShiftAmtVT)); 106002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1063ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTMIr32, dl, ShiftAmtVT, 106402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel ShiftAmt, 106502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(3, ShiftAmtVT)); 106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1067ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ANDIr32, dl, ShiftAmtVT, 106802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel ShiftAmt, 106902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(7, ShiftAmtVT)); 107002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 107102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Ensure that the shift amounts are negated! 1072ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Bytes = CurDAG->getTargetNode(SPU::SFIr32, dl, ShiftAmtVT, 107302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(Bytes, 0), 107402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(0, ShiftAmtVT)); 107502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1076ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Bits = CurDAG->getTargetNode(SPU::SFIr32, dl, ShiftAmtVT, 107702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(Bits, 0), 107802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(0, ShiftAmtVT)); 107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 108002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1081ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQMBYv2i64, dl, VecVT, 108202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), SDValue(Bytes, 0)); 108302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1084ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQMBIv2i64, dl, VecVT, 108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(Shift, 0), SDValue(Bits, 0)); 108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1088ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts. 109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 109402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 109602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 109902d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 110002d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSPUDAGToDAGISel::SelectSRAi64(SDValue &Op, MVT OpVT) { 110102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Promote Op0 to vector 110202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 110302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel MVT ShiftAmtVT = ShiftAmt.getValueType(); 1105ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 110602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0 = 1108ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ORv2i64_i64, dl, VecVT, Op.getOperand(0)); 110902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 111102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *SignRot = 1112ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, 111302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), SignRotAmt); 111402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSign = 1115ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ORi32_v4i32, dl, MVT::i32, SDValue(SignRot, 0)); 111602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSignMask = 1118ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); 111902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerMask = 1120ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::FSMBIv2i64, dl, VecVT, 112102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 112202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerSelect = 1123ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SELBv2i64, dl, VecVT, 112402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(UpperHalfSignMask, 0), 112502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(VecOp0, 0), 112602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 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 = 1137ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQBYIv2i64, dl, VecVT, 113802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(UpperLowerSelect, 0), 113902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 114002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 114102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 114202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 114302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bits = 8 - bits; 114402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1145ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQBIIv2i64, dl, VecVT, 114602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 114702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel CurDAG->getTargetConstant(bits, ShiftAmtVT)); 114802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 114902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 115002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *NegShift = 1151ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::SFIr32, dl, ShiftAmtVT, 115202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 115302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 115402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1155ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT, 115602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 115702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1158ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ROTQBIv2i64, dl, VecVT, 115902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue(Shift, 0), SDValue(NegShift, 0)); 116002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 116102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1162ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 116302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 116402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1165c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*! 1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant 1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */ 11687ea02ffe918baff29a39981276e83b0e845ede03Scott MichelSDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT, 11697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 1170c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode()); 11717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(CN->getZExtValue(), OpVT, dl); 11727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel} 11737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 11747ea02ffe918baff29a39981276e83b0e845ede03Scott MichelSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, MVT OpVT, 11757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 1176c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel MVT OpVecVT = MVT::getVectorVT(OpVT, 2); 1177c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue i64vec = 11787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl); 1179c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1180c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Here's where it gets interesting, because we have to parse out the 1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // subtree handed back in i64vec: 1182c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1183c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (i64vec.getOpcode() == ISD::BIT_CONVERT) { 1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // The degenerate case where the upper and lower bits in the splat are 1185c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // identical: 1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = i64vec.getOperand(0); 1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 11889de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ReplaceUses(i64vec, Op0); 1189ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, 1190c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(emitBuildVector(Op0), 0)); 1191c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 1192c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue lhs = i64vec.getOperand(0); 1193c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue rhs = i64vec.getOperand(1); 1194c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shufmask = i64vec.getOperand(2); 1195c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1196c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (lhs.getOpcode() == ISD::BIT_CONVERT) { 1197c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(lhs, lhs.getOperand(0)); 1198c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel lhs = lhs.getOperand(0); 1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 1202c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? lhs.getNode() 1203c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(lhs)); 1204c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1205c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (rhs.getOpcode() == ISD::BIT_CONVERT) { 1206c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(rhs, rhs.getOperand(0)); 1207c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel rhs = rhs.getOperand(0); 1208c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1209c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1210c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 1211c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? rhs.getNode() 1212c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(rhs)); 12139de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 1214c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shufmask.getOpcode() == ISD::BIT_CONVERT) { 1215c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(shufmask, shufmask.getOperand(0)); 1216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shufmask = shufmask.getOperand(0); 1217c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1218c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1219c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 1220c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? shufmask.getNode() 1221c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(shufmask)); 1222c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1223c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufNode = 1224ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 1225c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(lhsNode, 0), SDValue(rhsNode, 0), 1226c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(shufMaskNode, 0))); 1227c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 12287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, 1229ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen SDValue(shufNode, 0)); 12307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { 12317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ORi64_v2i64, dl, OpVT, 12327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue(emitBuildVector(i64vec), 0)); 1233c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else { 1234dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" 1235dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "condition"); 1236c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1237c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel} 1238c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 123902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a 1240266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 1241266bc8f7774b153401e54ed537db299159840981Scott Michel/// 1242266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 1243266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 1244266bc8f7774b153401e54ed537db299159840981Scott Michel} 1245