SPUISelDAGToDAG.cpp revision a82d3f7c57f03457c385add1687319d5c290f867
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" 34266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 35266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 36266bc8f7774b153401e54ed537db299159840981Scott Michel 37266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 38266bc8f7774b153401e54ed537db299159840981Scott Michel 39266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 40266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 41266bc8f7774b153401e54ed537db299159840981Scott Michel bool 42266bc8f7774b153401e54ed537db299159840981Scott Michel isI64IntS10Immediate(ConstantSDNode *CN) 43266bc8f7774b153401e54ed537db299159840981Scott Michel { 447810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 45266bc8f7774b153401e54ed537db299159840981Scott Michel } 46266bc8f7774b153401e54ed537db299159840981Scott Michel 47266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 48266bc8f7774b153401e54ed537db299159840981Scott Michel bool 49266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 50266bc8f7774b153401e54ed537db299159840981Scott Michel { 517810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 52266bc8f7774b153401e54ed537db299159840981Scott Michel } 53266bc8f7774b153401e54ed537db299159840981Scott Michel 54504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 55504c369213efb263136bb048e79af3516511c040Scott Michel bool 56504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 57504c369213efb263136bb048e79af3516511c040Scott Michel { 587810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isU10Constant(CN->getSExtValue()); 59504c369213efb263136bb048e79af3516511c040Scott Michel } 60504c369213efb263136bb048e79af3516511c040Scott Michel 61266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 62266bc8f7774b153401e54ed537db299159840981Scott Michel bool 63266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 64266bc8f7774b153401e54ed537db299159840981Scott Michel { 657810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 66266bc8f7774b153401e54ed537db299159840981Scott Michel } 67266bc8f7774b153401e54ed537db299159840981Scott Michel 68266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 69266bc8f7774b153401e54ed537db299159840981Scott Michel bool 70266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(SDNode *N) 71266bc8f7774b153401e54ed537db299159840981Scott Michel { 729de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); 739de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel return (CN != 0 && isI16IntS10Immediate(CN)); 74266bc8f7774b153401e54ed537db299159840981Scott Michel } 75266bc8f7774b153401e54ed537db299159840981Scott Michel 76ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 77ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 78ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 79ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 80f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return isU10Constant((short) CN->getZExtValue()); 81ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 82ec2a08ff061af36b46160e475362959f21663e76Scott Michel 83ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 84ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 85ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(SDNode *N) 86ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 87ec2a08ff061af36b46160e475362959f21663e76Scott Michel return (N->getOpcode() == ISD::Constant 88ec2a08ff061af36b46160e475362959f21663e76Scott Michel && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 89ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 90ec2a08ff061af36b46160e475362959f21663e76Scott Michel 91266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 92266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 93266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 94266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 95266bc8f7774b153401e54ed537db299159840981Scott Michel 96266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 97266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 98266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 99266bc8f7774b153401e54ed537db299159840981Scott Michel */ 100266bc8f7774b153401e54ed537db299159840981Scott Michel bool 101266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 102266bc8f7774b153401e54ed537db299159840981Scott Michel { 10383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = CN->getValueType(0); 104f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 1058e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 106266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 107266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (vt == MVT::i32) { 108f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 109266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 110266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 111266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 112f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 113266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 114266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 115266bc8f7774b153401e54ed537db299159840981Scott Michel } 116266bc8f7774b153401e54ed537db299159840981Scott Michel 117266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 118266bc8f7774b153401e54ed537db299159840981Scott Michel } 119266bc8f7774b153401e54ed537db299159840981Scott Michel 120266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for signed 16-bit values. 121266bc8f7774b153401e54ed537db299159840981Scott Michel bool 122266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(SDNode *N, short &Imm) 123266bc8f7774b153401e54ed537db299159840981Scott Michel { 124266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 125266bc8f7774b153401e54ed537db299159840981Scott Michel && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 126266bc8f7774b153401e54ed537db299159840981Scott Michel } 127266bc8f7774b153401e54ed537db299159840981Scott Michel 128266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 129266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 130266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 131266bc8f7774b153401e54ed537db299159840981Scott Michel { 13283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = FPN->getValueType(0); 133266bc8f7774b153401e54ed537db299159840981Scott Michel if (vt == MVT::f32) { 134d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 135266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 136266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 137266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 138266bc8f7774b153401e54ed537db299159840981Scott Michel } 139266bc8f7774b153401e54ed537db299159840981Scott Michel 140266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 141266bc8f7774b153401e54ed537db299159840981Scott Michel } 142266bc8f7774b153401e54ed537db299159840981Scott Michel 143053c1da8d956a794d158ac906b3927c923f97c4dScott Michel bool 14402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel isHighLow(const SDValue &Op) 145053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { 146053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return (Op.getOpcode() == SPUISD::IndirectAddr 147053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 148053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Lo) 149053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op.getOperand(0).getOpcode() == SPUISD::Lo 150053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 152053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 153266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 15483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands //! MVT to "useful stuff" mapping structure: 155266bc8f7774b153401e54ed537db299159840981Scott Michel 156266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 15783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT; 1587f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 159a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 160f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel unsigned lrinst; /// LR instruction 161266bc8f7774b153401e54ed537db299159840981Scott Michel }; 162266bc8f7774b153401e54ed537db299159840981Scott Michel 163266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 164f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, 165f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, 166f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, 167f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, 168f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, 169f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, 17058c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 171f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v16i8, 0, false, SPU::LRv16i8 }, 172f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v8i16, 0, false, SPU::LRv8i16 }, 173f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v4i32, 0, false, SPU::LRv4i32 }, 174f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v2i64, 0, false, SPU::LRv2i64 }, 175f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v4f32, 0, false, SPU::LRv4f32 }, 176f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel { MVT::v2f64, 0, false, SPU::LRv2f64 } 177266bc8f7774b153401e54ed537db299159840981Scott Michel }; 178266bc8f7774b153401e54ed537db299159840981Scott Michel 179266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 180266bc8f7774b153401e54ed537db299159840981Scott Michel 18183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const valtype_map_s *getValueTypeMapEntry(MVT VT) 182266bc8f7774b153401e54ed537db299159840981Scott Michel { 183266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 184266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 185266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1867f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 188266bc8f7774b153401e54ed537db299159840981Scott Michel } 189266bc8f7774b153401e54ed537db299159840981Scott Michel } 190266bc8f7774b153401e54ed537db299159840981Scott Michel 191266bc8f7774b153401e54ed537db299159840981Scott Michel 192266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 193266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 194266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 19583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 1967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel << "\n"; 197266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 198266bc8f7774b153401e54ed537db299159840981Scott Michel } 199266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 200266bc8f7774b153401e54ed537db299159840981Scott Michel 201266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 202266bc8f7774b153401e54ed537db299159840981Scott Michel } 203266bc8f7774b153401e54ed537db299159840981Scott Michel 2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the carry-generate shuffle mask. 2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 207844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 2117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 21402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 217266bc8f7774b153401e54ed537db299159840981Scott Michel } 218266bc8f7774b153401e54ed537db299159840981Scott Michel 2197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the borrow-generate shuffle mask 2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 2227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 2297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 232266bc8f7774b153401e54ed537db299159840981Scott Michel } 23302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //===------------------------------------------------------------------===// 2357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 2367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// instructions for SelectionDAG operations. 2377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// 2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel class SPUDAGToDAGISel : 2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public SelectionDAGISel 2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { 2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetMachine &TM; 2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetLowering &SPUtli; 2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned GlobalBaseReg; 2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public: 2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 2477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel(tm), 2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel TM(tm), 2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli(*tm.getTargetLowering()) 2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { } 2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool runOnFunction(Function &Fn) { 2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Make sure we re-emit a set of the global base reg if necessary 2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel GlobalBaseReg = 0; 2557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel::runOnFunction(Fn); 2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return true; 257c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 258266bc8f7774b153401e54ed537db299159840981Scott Michel 2597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i32. 2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI32Imm(uint32_t Imm) { 2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i32); 26394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } 26494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 2667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i64. 2677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI64Imm(uint64_t Imm) { 2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i64); 2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 27094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 2727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getSmallIPtrImm(unsigned Imm) { 2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 274266bc8f7774b153401e54ed537db299159840981Scott Michel } 2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *emitBuildVector(SDValue build_vec) { 2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel MVT vecVT = build_vec.getValueType(); 2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel MVT eltVT = vecVT.getVectorElementType(); 2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *bvNode = build_vec.getNode(); 2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = bvNode->getDebugLoc(); 2817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check to see if this vector can be represented as a CellSPU immediate 2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // constant by invoking all of the instruction selection predicates: 2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (((vecVT == MVT::v8i16) && 2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((vecVT == MVT::v4i32) && 2877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 2917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((vecVT == MVT::v2i64) && 2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) 2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return Select(build_vec); 2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // No, need to emit a constant pool spill: 2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<Constant*> CV; 2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { 3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i)); 3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue())); 3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Constant *CP = ConstantVector::get(CV); 3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CGPoolOffset = 3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerConstantPool(CPIdx, *CurDAG, 3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli.getSPUTargetMachine()); 3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl, 3127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CurDAG->getEntryNode(), CGPoolOffset, 3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel PseudoSourceValue::getConstantPool(), 0, 3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel false, Alignment)); 3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Select - Convert the specified operand from a target-independent to a 3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// target-specific node if it hasn't already been changed. 3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *Select(SDValue Op); 3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 shl 3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSHLi64(SDValue &Op, MVT OpVT); 3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 srl 3257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSRLi64(SDValue &Op, MVT OpVT); 3267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 sra 3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectSRAi64(SDValue &Op, MVT OpVT); 3297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the necessary sequence for loading i64 constants: 3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectI64Constant(SDValue &Op, MVT OpVT, DebugLoc dl); 3327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Alternate instruction emit sequence for loading i64 constants 3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *SelectI64Constant(uint64_t i64const, MVT OpVT, DebugLoc dl); 3357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Returns true if the address N is an A-form (local store) address 3377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 3387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! D-form address predicate 3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Alternate D-form address using i7 offset predicate 3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base); 3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// D-form address selection workhorse 3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base, int minOffset, int maxOffset); 3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// inline asm expressions. 3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel char ConstraintCode, 3607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<SDValue> &OutOps) { 3617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0, Op1; 3627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel switch (ConstraintCode) { 3637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel default: return true; 3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'm': // memory 3657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 3677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 3687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'o': // offsetable 3707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 3727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0 = Op; 3737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op1 = getSmallIPtrImm(0); 3747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'v': // not offsetable 377266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 3787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 379266bc8f7774b153401e54ed537db299159840981Scott Michel#else 3807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 381266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 3827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 38402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op0); 3867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op1); 3877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return false; 3887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 389266bc8f7774b153401e54ed537db299159840981Scott Michel 3907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// InstructionSelect - This callback is invoked by 3917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 3927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual void InstructionSelect(); 393266bc8f7774b153401e54ed537db299159840981Scott Michel 3947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual const char *getPassName() const { 3957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 3967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 39702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 3997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// this target when scheduling the DAG. 4007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 4017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel const TargetInstrInfo *II = TM.getInstrInfo(); 4027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(II && "No InstrInfo?"); 4037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return new SPUHazardRecognizer(*II); 4047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 405266bc8f7774b153401e54ed537db299159840981Scott Michel 4067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Include the pieces autogenerated from the target description. 407266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 4087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel }; 409844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 410844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 411db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by 412266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 413266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 414f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect() 415266bc8f7774b153401e54ed537db299159840981Scott Michel{ 416266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 417266bc8f7774b153401e54ed537db299159840981Scott Michel 418266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 4198ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene SelectRoot(*CurDAG); 420f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman CurDAG->RemoveDeadNodes(); 421266bc8f7774b153401e54ed537db299159840981Scott Michel} 422266bc8f7774b153401e54ed537db299159840981Scott Michel 423266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 4249de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand 425266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 426266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 427266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 428266bc8f7774b153401e54ed537db299159840981Scott Michel */ 429266bc8f7774b153401e54ed537db299159840981Scott Michelbool 430475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 431475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 432266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 43383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OffsVT = MVT::i16; 434475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 435266bc8f7774b153401e54ed537db299159840981Scott Michel 436266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 437266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 4389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 4399de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 4409de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 4419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel abort(); 4429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as " 448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << "A-form address.\n"; 449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel abort(); 450053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 451266bc8f7774b153401e54ed537db299159840981Scott Michel 45202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel case SPUISD::AFormAddr: 453053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 454053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 456475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 457053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 458053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 474053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 478266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 479266bc8f7774b153401e54ed537db299159840981Scott Michel} 480266bc8f7774b153401e54ed537db299159840981Scott Michel 48102d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool 482475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 483475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 484203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 485203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 486203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 487203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 490266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 491266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 492266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 493266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 494266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 495266bc8f7774b153401e54ed537db299159840981Scott Michel 496266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 497266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 498266bc8f7774b153401e54ed537db299159840981Scott Michel 499266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 500475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 501266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 502266bc8f7774b153401e54ed537db299159840981Scott Michelbool 503475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 504475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 5069c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 5079c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 5087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 5097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 511475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 512475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 5137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 514266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 51583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrTy = SPUtli.getPointerTy(); 516266bc8f7774b153401e54ed537db299159840981Scott Michel 517053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 519203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 520203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 521266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 522203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 523203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 524266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 525203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 526266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 527266bc8f7774b153401e54ed537db299159840981Scott Michel } 528266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 529266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 530475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 531475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 532266bc8f7774b153401e54ed537db299159840981Scott Michel 533053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 5409de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 5417810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 542266bc8f7774b153401e54ed537db299159840981Scott Michel 543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 544203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 545203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5469de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 547203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 5489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 549203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 5509de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 551203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5529de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5539de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5547f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 5559de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 556053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 5627810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 563053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 564053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 565203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 566203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 567053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 568203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 569053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 570203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 571053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 572203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5749de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 576053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 577053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 578053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 579266bc8f7774b153401e54ed537db299159840981Scott Michel } 580497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 581053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 582053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 583475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 584475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 585053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5867f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 588053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5899de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 590053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5919de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 594475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 5987810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 6007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 6017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 6027810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 6037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 60402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 6057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 6067f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 6077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 6087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 6097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 6119de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 612053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 613053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 614053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 61558c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 6167f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 6177f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 6187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 6197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { 6219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel unsigned OpOpc = Op.getOpcode(); 6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 6249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 6259c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SDValue Addr, Offs; 6269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Get the register from CopyFromReg 6289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Opc == ISD::CopyFromReg) 6299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N.getOperand(1); 6309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel else 6319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N; // Register 6329c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 633aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); 6349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6359c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 6369c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 6379c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 6389c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6399c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 6409c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Index = Addr; 6419c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 6429c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 643aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 644aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 645aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 64619c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N.getOperand(1); 647aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 64819c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N; 649aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 650aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 651aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 652aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 6539c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 654266bc8f7774b153401e54ed537db299159840981Scott Michel } 6559c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 656266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 657266bc8f7774b153401e54ed537db299159840981Scott Michel} 658266bc8f7774b153401e54ed537db299159840981Scott Michel 659266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 660266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 661266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 662266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 663266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 664266bc8f7774b153401e54ed537db299159840981Scott Michel 6659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 6669c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 6679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 668266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 669266bc8f7774b153401e54ed537db299159840981Scott Michelbool 670475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 671475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 6729c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 6739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 67418fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 67518fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 6761a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 6771a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 67850843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 6799c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 680266bc8f7774b153401e54ed537db299159840981Scott Michel 6819c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 68258c5818c01e375a84dc601140470fa68638004cfScott Michel} 68358c5818c01e375a84dc601140470fa68638004cfScott Michel 684266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 685266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 686266bc8f7774b153401e54ed537db299159840981Scott Michel */ 687266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 688475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) { 689ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *N = Op.getNode(); 690266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 69158c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 69258c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 69383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OpVT = Op.getValueType(); 694475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 695ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = N->getDebugLoc(); 696266bc8f7774b153401e54ed537db299159840981Scott Michel 697e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman if (N->isMachineOpcode()) { 698266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 699c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 700c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 701c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Opc == ISD::FrameIndex) { 70202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 70302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); 70402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); 70502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 70602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (FI < 128) { 707203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 70802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = TFI; 70902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[1] = Imm0; 710203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 711203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 712203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 71302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType()); 714ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Ops[1] = SDValue(CurDAG->getTargetNode(SPU::ILAr32, dl, Op.getValueType(), 71502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel TFI, Imm0), 0); 716203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 717203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 718c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 719c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Catch the i64 constants that end up here. Note: The backend doesn't 720c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // attempt to legalize the constant (it's useless because DAGCombiner 721c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // will insert 64-bit constants and we can't stop it). 7227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(Op, OpVT, Op.getDebugLoc()); 72394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 72494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel && OpVT == MVT::i64) { 72594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue Op0 = Op.getOperand(0); 72694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT Op0VT = Op0.getValueType(); 72794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits())); 72894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel MVT OpVecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 72994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue shufMask; 73094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 73194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel switch (Op0VT.getSimpleVT()) { 73294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel default: 73394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel cerr << "CellSPU Select: Unhandled zero/any extend MVT\n"; 73494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel abort(); 73594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel /*NOTREACHED*/ 73694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 73794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i32: 738a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 739d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 740d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x00010203, MVT::i32), 741d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 742d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x08090a0b, MVT::i32)); 74394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 74494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 74594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i16: 746a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 747d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 748d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80800203, MVT::i32), 749d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 750d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80800a0b, MVT::i32)); 75194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 75294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 75394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel case MVT::i8: 754a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 755d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 756d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808003, MVT::i32), 757d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x80808080, MVT::i32), 758d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel CurDAG->getConstant(0x8080800b, MVT::i32)); 75994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 76058c5818c01e375a84dc601140470fa68638004cfScott Michel } 76194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *shufMaskLoad = emitBuildVector(shufMask); 76394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *PromoteScalar = 764ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0)); 76594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue zextShuffle = 767ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 768d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 769d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 770d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(shufMaskLoad, 0)); 77194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 77294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we 77394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // re-use it in the VEC2PREFSLOT selection without needing to explicitly 77494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // call SelectCode (it's already done for us.) 775046928077645f6ddad839e85dd03ab11e5b22cbcDale Johannesen SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle)); 776ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 77794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel zextShuffle)); 77894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 77994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *CGLoad = 7807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 781d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 782ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 783d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 784d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 785d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 786d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl)); 788d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 789ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 790d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 791d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 792d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 793d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 795d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 796ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 797d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 798d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 799c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::TRUNCATE) { 800c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = Op.getOperand(0); 801c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 802c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel && OpVT == MVT::i32 803c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel && Op0.getValueType() == MVT::i64) { 8049de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 8059de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // 8069de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Take advantage of the fact that the upper 32 bits are in the 8079de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // i32 preferred slot and avoid shuffle gymnastics: 808c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 809c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (CN != 0) { 810c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned shift_amt = unsigned(CN->getZExtValue()); 811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt >= 32) { 813c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *hi32 = 814ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getTargetNode(SPU::ORr32_r64, dl, OpVT, 815ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Op0.getOperand(0)); 816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 817c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shift_amt -= 32; 818c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt > 0) { 819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Take care of the additional shift, if present: 820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 821c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned Opc = SPU::ROTMAIr32_i32; 8229de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 823c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Op0.getOpcode() == ISD::SRL) 824c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Opc = SPU::ROTMr32; 825c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 826ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen hi32 = CurDAG->getTargetNode(Opc, dl, OpVT, SDValue(hi32, 0), 827ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen shift); 828c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 829c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 830c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel return hi32; 831c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 832c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 833c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 83402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SHL) { 83502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 83602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSHLi64(Op, OpVT); 83702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 83802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRL) { 83902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 84002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRLi64(Op, OpVT); 84102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 84202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRA) { 84302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (OpVT == MVT::i64) { 84402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRAi64(Op, OpVT); 84502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 8467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FNEG 8477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 8487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = Op.getDebugLoc(); 8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check if the pattern is a special form of DFNMS: 8507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 8517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0 = Op.getOperand(0); 8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op0.getOpcode() == ISD::FSUB) { 8537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op00 = Op0.getOperand(0); 8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op00.getOpcode() == ISD::FMUL) { 8557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Opc = SPU::DFNMSf64; 8567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::v2f64) 8577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Opc = SPU::DFNMSv2f64; 8587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(Opc, dl, OpVT, 8607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op00.getOperand(0), 8617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op00.getOperand(1), 8627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0.getOperand(1)); 8637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 8677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = 0; 868a82d3f7c57f03457c385add1687319d5c290f867Scott Michel unsigned Opc = SPU::XORfneg64; 8697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::f64) { 8717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = SelectI64Constant(negConst, MVT::i64, dl); 8727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (OpVT == MVT::v2f64) { 873a82d3f7c57f03457c385add1687319d5c290f867Scott Michel Opc = SPU::XORfnegvec; 8747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 8757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel MVT::v2i64, 8767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel negConst, negConst)); 8777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 8797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(Opc, dl, OpVT, 8807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op.getOperand(0), SDValue(signMask, 0)); 8817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FABS) { 8827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (OpVT == MVT::f64) { 8837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 8847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ANDfabs64, dl, OpVT, 8857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op.getOperand(0), SDValue(signMask, 0)); 8867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (OpVT == MVT::v2f64) { 8877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 8887ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 8897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel absConst, absConst); 8907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = emitBuildVector(absVec); 8917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetNode(SPU::ANDfabsvec, dl, OpVT, 8927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op.getOperand(0), SDValue(signMask, 0)); 8937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 894266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 895266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 89683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = N->getValueType(0); 897475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 898475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 899266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 900a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 901a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 902a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 903a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel cerr << "LDRESULT for unsupported type: " 90483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 905a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel << "\n"; 906a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel abort(); 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 { 1234c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel cerr << "SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec condition\n"; 1235c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel abort(); 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