SPUISelDAGToDAG.cpp revision 602b0c8c17f458d2c80f2deb3c8e554d516ee316
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" 33a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h" 34266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h" 35dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 37266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 38dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 39266bc8f7774b153401e54ed537db299159840981Scott Michel 40266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 41266bc8f7774b153401e54ed537db299159840981Scott Michel 42266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 43266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 44266bc8f7774b153401e54ed537db299159840981Scott Michel bool 45266bc8f7774b153401e54ed537db299159840981Scott Michel isI64IntS10Immediate(ConstantSDNode *CN) 46266bc8f7774b153401e54ed537db299159840981Scott Michel { 477810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 48266bc8f7774b153401e54ed537db299159840981Scott Michel } 49266bc8f7774b153401e54ed537db299159840981Scott Michel 50266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 51266bc8f7774b153401e54ed537db299159840981Scott Michel bool 52266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 53266bc8f7774b153401e54ed537db299159840981Scott Michel { 547810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 55266bc8f7774b153401e54ed537db299159840981Scott Michel } 56266bc8f7774b153401e54ed537db299159840981Scott Michel 57504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 58504c369213efb263136bb048e79af3516511c040Scott Michel bool 59504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 60504c369213efb263136bb048e79af3516511c040Scott Michel { 617810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isU10Constant(CN->getSExtValue()); 62504c369213efb263136bb048e79af3516511c040Scott Michel } 63504c369213efb263136bb048e79af3516511c040Scott Michel 64266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 65266bc8f7774b153401e54ed537db299159840981Scott Michel bool 66266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 67266bc8f7774b153401e54ed537db299159840981Scott Michel { 687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 69266bc8f7774b153401e54ed537db299159840981Scott Michel } 70266bc8f7774b153401e54ed537db299159840981Scott Michel 71266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 72266bc8f7774b153401e54ed537db299159840981Scott Michel bool 73266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(SDNode *N) 74266bc8f7774b153401e54ed537db299159840981Scott Michel { 759de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); 769de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel return (CN != 0 && isI16IntS10Immediate(CN)); 77266bc8f7774b153401e54ed537db299159840981Scott Michel } 78266bc8f7774b153401e54ed537db299159840981Scott Michel 79ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 80ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 81ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 82ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return isU10Constant((short) CN->getZExtValue()); 84ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 85ec2a08ff061af36b46160e475362959f21663e76Scott Michel 86ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 87ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 88ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(SDNode *N) 89ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 90ec2a08ff061af36b46160e475362959f21663e76Scott Michel return (N->getOpcode() == ISD::Constant 91ec2a08ff061af36b46160e475362959f21663e76Scott Michel && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 92ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 93ec2a08ff061af36b46160e475362959f21663e76Scott Michel 94266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 95266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 96266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 97266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 98266bc8f7774b153401e54ed537db299159840981Scott Michel 99266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 100266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 101266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 102266bc8f7774b153401e54ed537db299159840981Scott Michel */ 103266bc8f7774b153401e54ed537db299159840981Scott Michel bool 104266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 105266bc8f7774b153401e54ed537db299159840981Scott Michel { 106e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = CN->getValueType(0); 107f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 109266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (vt == MVT::i32) { 111f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 112266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 113266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 114266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 115f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 116266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 117266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 118266bc8f7774b153401e54ed537db299159840981Scott Michel } 119266bc8f7774b153401e54ed537db299159840981Scott Michel 120266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 121266bc8f7774b153401e54ed537db299159840981Scott Michel } 122266bc8f7774b153401e54ed537db299159840981Scott Michel 123266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for signed 16-bit values. 124266bc8f7774b153401e54ed537db299159840981Scott Michel bool 125266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(SDNode *N, short &Imm) 126266bc8f7774b153401e54ed537db299159840981Scott Michel { 127266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 128266bc8f7774b153401e54ed537db299159840981Scott Michel && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 129266bc8f7774b153401e54ed537db299159840981Scott Michel } 130266bc8f7774b153401e54ed537db299159840981Scott Michel 131266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 132266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 133266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 134266bc8f7774b153401e54ed537db299159840981Scott Michel { 135e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = FPN->getValueType(0); 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt == MVT::f32) { 137d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 138266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 139266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 140266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 141266bc8f7774b153401e54ed537db299159840981Scott Michel } 142266bc8f7774b153401e54ed537db299159840981Scott Michel 143266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 144266bc8f7774b153401e54ed537db299159840981Scott Michel } 145266bc8f7774b153401e54ed537db299159840981Scott Michel 146053c1da8d956a794d158ac906b3927c923f97c4dScott Michel bool 14702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel isHighLow(const SDValue &Op) 148053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { 149053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return (Op.getOpcode() == SPUISD::IndirectAddr 150053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Lo) 152053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op.getOperand(0).getOpcode() == SPUISD::Lo 153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 156266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 157e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson //! EVT to "useful stuff" mapping structure: 158266bc8f7774b153401e54ed537db299159840981Scott Michel 159266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 160e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT; 1617f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 162a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 163f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel unsigned lrinst; /// LR instruction 164266bc8f7774b153401e54ed537db299159840981Scott Michel }; 165266bc8f7774b153401e54ed537db299159840981Scott Michel 166266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, 168825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, 169825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, 170825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, 171825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, 172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, 17358c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v16i8, 0, false, SPU::LRv16i8 }, 175825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v8i16, 0, false, SPU::LRv8i16 }, 176825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v4i32, 0, false, SPU::LRv4i32 }, 177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v2i64, 0, false, SPU::LRv2i64 }, 178825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v4f32, 0, false, SPU::LRv4f32 }, 179825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { MVT::v2f64, 0, false, SPU::LRv2f64 } 180266bc8f7774b153401e54ed537db299159840981Scott Michel }; 181266bc8f7774b153401e54ed537db299159840981Scott Michel 182266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 183266bc8f7774b153401e54ed537db299159840981Scott Michel 184e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson const valtype_map_s *getValueTypeMapEntry(EVT VT) 185266bc8f7774b153401e54ed537db299159840981Scott Michel { 186266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 187266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 188266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 191266bc8f7774b153401e54ed537db299159840981Scott Michel } 192266bc8f7774b153401e54ed537db299159840981Scott Michel } 193266bc8f7774b153401e54ed537db299159840981Scott Michel 194266bc8f7774b153401e54ed537db299159840981Scott Michel 195266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 196266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 197dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin std::string msg; 198dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin raw_string_ostream Msg(msg); 199dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin Msg << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 200e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson << VT.getEVTString(); 201dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error(Msg.str()); 202266bc8f7774b153401e54ed537db299159840981Scott Michel } 203266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 204266bc8f7774b153401e54ed537db299159840981Scott Michel 205266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 206266bc8f7774b153401e54ed537db299159840981Scott Michel } 207266bc8f7774b153401e54ed537db299159840981Scott Michel 2087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the carry-generate shuffle mask. 2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 211844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 214825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 215825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 216825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 217825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 21802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 219825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 221266bc8f7774b153401e54ed537db299159840981Scott Michel } 222266bc8f7774b153401e54ed537db299159840981Scott Michel 2237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the borrow-generate shuffle mask 2247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 229825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 230825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 231825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 232825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 234825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 2357ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 236266bc8f7774b153401e54ed537db299159840981Scott Michel } 23702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2387ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //===------------------------------------------------------------------===// 2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// instructions for SelectionDAG operations. 2417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// 2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel class SPUDAGToDAGISel : 2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public SelectionDAGISel 2447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { 2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetMachine &TM; 2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUTargetLowering &SPUtli; 2477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned GlobalBaseReg; 2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public: 2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 2517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel(tm), 2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel TM(tm), 2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli(*tm.getTargetLowering()) 2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { } 2557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 256ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman virtual bool runOnMachineFunction(MachineFunction &MF) { 2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Make sure we re-emit a set of the global base reg if necessary 2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel GlobalBaseReg = 0; 259ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman SelectionDAGISel::runOnMachineFunction(MF); 2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return true; 261c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 262266bc8f7774b153401e54ed537db299159840981Scott Michel 2637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i32. 2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI32Imm(uint32_t Imm) { 266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return CurDAG->getTargetConstant(Imm, MVT::i32); 26794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } 26894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i64. 2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI64Imm(uint64_t Imm) { 272825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return CurDAG->getTargetConstant(Imm, MVT::i64); 2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 27494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 2757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 2767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getSmallIPtrImm(unsigned Imm) { 2777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 278266bc8f7774b153401e54ed537db299159840981Scott Michel } 2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *emitBuildVector(SDValue build_vec) { 281e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vecVT = build_vec.getValueType(); 282e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT eltVT = vecVT.getVectorElementType(); 2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *bvNode = build_vec.getNode(); 2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = bvNode->getDebugLoc(); 2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check to see if this vector can be represented as a CellSPU immediate 2877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // constant by invoking all of the instruction selection predicates: 288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (((vecVT == MVT::v8i16) && 289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 290825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v4i32) && 291825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 292825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 293825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 2947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 295825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v2i64) && 296825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 297825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 298825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) 2997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return Select(build_vec); 3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // No, need to emit a constant pool spill: 3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<Constant*> CV; 3037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { 3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i)); 3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue())); 3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 309af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Constant *CP = ConstantVector::get(CV); 3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 3117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 3127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CGPoolOffset = 3137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerConstantPool(CPIdx, *CurDAG, 3147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli.getSPUTargetMachine()); 3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl, 3167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel CurDAG->getEntryNode(), CGPoolOffset, 3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel PseudoSourceValue::getConstantPool(), 0, 3187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel false, Alignment)); 3197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3217ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Select - Convert the specified operand from a target-independent to a 3227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// target-specific node if it hasn't already been changed. 3237ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *Select(SDValue Op); 3247ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 shl 326e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectSHLi64(SDValue &Op, EVT OpVT); 3277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 srl 329e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectSRLi64(SDValue &Op, EVT OpVT); 3307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 sra 332e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectSRAi64(SDValue &Op, EVT OpVT); 3337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the necessary sequence for loading i64 constants: 335e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectI64Constant(SDValue &Op, EVT OpVT, DebugLoc dl); 3367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Alternate instruction emit sequence for loading i64 constants 338e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl); 3397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Returns true if the address N is an A-form (local store) address 3417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 3427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! D-form address predicate 3457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 3467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Alternate D-form address using i7 offset predicate 3497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 3507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base); 3517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// D-form address selection workhorse 3537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 3547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base, int minOffset, int maxOffset); 3557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 3577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 3587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 3597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 3607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 3617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// inline asm expressions. 3627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 3637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel char ConstraintCode, 3647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<SDValue> &OutOps) { 3657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0, Op1; 3667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel switch (ConstraintCode) { 3677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel default: return true; 3687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'm': // memory 3697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 3717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 3727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'o': // offsetable 3747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 3757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 3767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0 = Op; 3777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op1 = getSmallIPtrImm(0); 3787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 3797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'v': // not offsetable 381266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 382c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled."); 383266bc8f7774b153401e54ed537db299159840981Scott Michel#else 3847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 385266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 3867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 3877ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 38802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3897ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op0); 3907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op1); 3917ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return false; 3927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 393266bc8f7774b153401e54ed537db299159840981Scott Michel 3947ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// InstructionSelect - This callback is invoked by 3957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 3967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual void InstructionSelect(); 397266bc8f7774b153401e54ed537db299159840981Scott Michel 3987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual const char *getPassName() const { 3997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 4007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 40102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 4027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 4037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// this target when scheduling the DAG. 4047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 4057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel const TargetInstrInfo *II = TM.getInstrInfo(); 4067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(II && "No InstrInfo?"); 4077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return new SPUHazardRecognizer(*II); 4087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 409266bc8f7774b153401e54ed537db299159840981Scott Michel 4107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Include the pieces autogenerated from the target description. 411266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 4127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel }; 413844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 414844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 415db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by 416266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 417266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 418f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect() 419266bc8f7774b153401e54ed537db299159840981Scott Michel{ 420266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 421266bc8f7774b153401e54ed537db299159840981Scott Michel 422266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 4238ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene SelectRoot(*CurDAG); 424f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman CurDAG->RemoveDeadNodes(); 425266bc8f7774b153401e54ed537db299159840981Scott Michel} 426266bc8f7774b153401e54ed537db299159840981Scott Michel 427266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 4289de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand 429266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 430266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 431266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 432266bc8f7774b153401e54ed537db299159840981Scott Michel */ 433266bc8f7774b153401e54ed537db299159840981Scott Michelbool 434475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 435475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 436266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 437825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EVT OffsVT = MVT::i16; 438475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 439266bc8f7774b153401e54ed537db299159840981Scott Michel 440266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 441266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 4429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 444dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered."); 4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 4469de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 450dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPUSelectAFormAddr: Target Constant/Pool/Global " 451dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "not wrapped as A-form address."); 452053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 453266bc8f7774b153401e54ed537db299159840981Scott Michel 45402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel case SPUISD::AFormAddr: 455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 456053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 457053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 458475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 474053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 478053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 479053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 480266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 481266bc8f7774b153401e54ed537db299159840981Scott Michel} 482266bc8f7774b153401e54ed537db299159840981Scott Michel 48302d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool 484475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 485475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 486203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 487203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 488203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 489203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4917f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 492266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 493266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 494266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 495266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 496266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 497266bc8f7774b153401e54ed537db299159840981Scott Michel 498266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 499266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 500266bc8f7774b153401e54ed537db299159840981Scott Michel 501266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 502475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 503266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 504266bc8f7774b153401e54ed537db299159840981Scott Michelbool 505475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 506475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 5077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 5089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 5099c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 5107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 5117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 513475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 514475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 5157f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 516266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 517e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PtrTy = SPUtli.getPointerTy(); 518266bc8f7774b153401e54ed537db299159840981Scott Michel 519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 521203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 522203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5234437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = " 524203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 525203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 526266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 527203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 528266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 529266bc8f7774b153401e54ed537db299159840981Scott Michel } 530266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 531266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 532475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 533475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 534266bc8f7774b153401e54ed537db299159840981Scott Michel 535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 5429de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 5437810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 544266bc8f7774b153401e54ed537db299159840981Scott Michel 545053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 546203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 547203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5484437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 549203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 5509de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 551203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 5529de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 553203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5549de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5559de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5567f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 5579de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 562053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 563053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 5647810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 565053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 566053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 567203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 568203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 5694437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 570203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 571053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 572203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 573053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 574203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5777f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 578053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 579053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 580053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 581266bc8f7774b153401e54ed537db299159840981Scott Michel } 582497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 583053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 584053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 585475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 586475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 587053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5897f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 590053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5919de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 592053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 596475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 6007810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 6017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 6027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 6037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 6047810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 6057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 60602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 6077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 6087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 6097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 6107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 6117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 6139de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 614053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 615053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 616053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 61758c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 6187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 6197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 6207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 6217f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 6229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { 6239c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel unsigned OpOpc = Op.getOpcode(); 6249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6259c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 6269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 6279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SDValue Addr, Offs; 6289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Get the register from CopyFromReg 6309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Opc == ISD::CopyFromReg) 6319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N.getOperand(1); 6329c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel else 6339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N; // Register 6349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 635aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); 6369c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6379c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 6389c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 6399c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 6409c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 6419c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 6429c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Index = Addr; 6439c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 6449c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 645aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 646aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 647aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 64819c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N.getOperand(1); 649aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 65019c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N; 651aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 652aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 653aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 654aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 6559c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 656266bc8f7774b153401e54ed537db299159840981Scott Michel } 6579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 658266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 659266bc8f7774b153401e54ed537db299159840981Scott Michel} 660266bc8f7774b153401e54ed537db299159840981Scott Michel 661266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 662266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 663266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 664266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 665266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 666266bc8f7774b153401e54ed537db299159840981Scott Michel 6679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 6689c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 6699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 670266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 671266bc8f7774b153401e54ed537db299159840981Scott Michelbool 672475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 673475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 6749c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 6759c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 67618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 67718fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 6781a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 6791a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 68050843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 6819c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 682266bc8f7774b153401e54ed537db299159840981Scott Michel 6839c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 68458c5818c01e375a84dc601140470fa68638004cfScott Michel} 68558c5818c01e375a84dc601140470fa68638004cfScott Michel 686266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 687266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 688266bc8f7774b153401e54ed537db299159840981Scott Michel */ 689266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 690475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) { 691ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *N = Op.getNode(); 692266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 69358c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 69458c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 695e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = Op.getValueType(); 696475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 697ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = N->getDebugLoc(); 698266bc8f7774b153401e54ed537db299159840981Scott Michel 699e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman if (N->isMachineOpcode()) { 700266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 701c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 702c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 703c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Opc == ISD::FrameIndex) { 70402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 70502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); 70602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); 70702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 70802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (FI < 128) { 709203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 71002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = TFI; 71102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[1] = Imm0; 712203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 713203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 714203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 71502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType()); 716602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, 717602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op.getValueType(), TFI, Imm0), 718602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman 0); 719203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 720203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 721825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 722c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Catch the i64 constants that end up here. Note: The backend doesn't 723c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // attempt to legalize the constant (it's useless because DAGCombiner 724c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // will insert 64-bit constants and we can't stop it). 7257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(Op, OpVT, Op.getDebugLoc()); 72694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 727825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i64) { 72894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue Op0 = Op.getOperand(0); 729e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT Op0VT = Op0.getValueType(); 73023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), 73123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson Op0VT, (128 / Op0VT.getSizeInBits())); 73223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), 73323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 73494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue shufMask; 73594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 736825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Op0VT.getSimpleVT().SimpleTy) { 73794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel default: 738e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson llvm_report_error("CellSPU Select: Unhandled zero/any extend EVT"); 73994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel /*NOTREACHED*/ 740825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 741825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 742825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 743825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x00010203, MVT::i32), 744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 745825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x08090a0b, MVT::i32)); 74694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 74794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 748825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 749825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 750825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 751825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800203, MVT::i32), 752825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 753825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800a0b, MVT::i32)); 75494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 75594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 756825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: 757825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 758825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 759825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808003, MVT::i32), 760825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 761825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x8080800b, MVT::i32)); 76294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 76358c5818c01e375a84dc601140470fa68638004cfScott Michel } 76494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *shufMaskLoad = emitBuildVector(shufMask); 76694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *PromoteScalar = 767ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0)); 76894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 76994bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue zextShuffle = 770ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 771d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 772d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(PromoteScalar, 0), 773d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(shufMaskLoad, 0)); 77494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 77594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we 77694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // re-use it in the VEC2PREFSLOT selection without needing to explicitly 77794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel // call SelectCode (it's already done for us.) 778046928077645f6ddad839e85dd03ab11e5b22cbcDale Johannesen SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle)); 779ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 78094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel zextShuffle)); 781825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 78294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *CGLoad = 7837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 784d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 785ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 786d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 787d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 788825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 789d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl)); 791d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 792ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 793d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 794d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 795825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 796d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 7977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); 798d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 799ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 800d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel Op.getOperand(0), Op.getOperand(1), 801d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(CGLoad, 0))); 802c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::TRUNCATE) { 803c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = Op.getOperand(0); 804c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 805825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i32 806825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && Op0.getValueType() == MVT::i64) { 8079de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 8089de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // 8099de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Take advantage of the fact that the upper 32 bits are in the 8109de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // i32 preferred slot and avoid shuffle gymnastics: 811c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 812c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (CN != 0) { 813c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned shift_amt = unsigned(CN->getZExtValue()); 814c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 815c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt >= 32) { 816c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *hi32 = 817602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ORr32_r64, dl, OpVT, 818602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op0.getOperand(0)); 819c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 820c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shift_amt -= 32; 821c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt > 0) { 822c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Take care of the additional shift, if present: 823825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 824c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned Opc = SPU::ROTMAIr32_i32; 8259de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 826c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Op0.getOpcode() == ISD::SRL) 827c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Opc = SPU::ROTMr32; 828c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 829602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0), 830602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman shift); 831c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 832c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 833c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel return hi32; 834c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 835c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 836c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 83702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SHL) { 838825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::i64) { 83902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSHLi64(Op, OpVT); 84002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 84102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRL) { 842825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::i64) { 84302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRLi64(Op, OpVT); 84402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 84502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRA) { 846825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::i64) { 84702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel return SelectSRAi64(Op, OpVT); 84802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 8497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FNEG 850825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 8517ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = Op.getDebugLoc(); 8527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check if the pattern is a special form of DFNMS: 8537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 8547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0 = Op.getOperand(0); 8557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op0.getOpcode() == ISD::FSUB) { 8567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op00 = Op0.getOperand(0); 8577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op00.getOpcode() == ISD::FMUL) { 8587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Opc = SPU::DFNMSf64; 859825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::v2f64) 8607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Opc = SPU::DFNMSv2f64; 8617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 862602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 863602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(0), 864602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(1), 865602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op0.getOperand(1)); 8667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 869825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 8707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = 0; 871a82d3f7c57f03457c385add1687319d5c290f867Scott Michel unsigned Opc = SPU::XORfneg64; 8727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 873825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 874825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson signMask = SelectI64Constant(negConst, MVT::i64, dl); 875825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 876a82d3f7c57f03457c385add1687319d5c290f867Scott Michel Opc = SPU::XORfnegvec; 8777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 878825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::v2i64, 8797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel negConst, negConst)); 8807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8817ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 882602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 883602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op.getOperand(0), SDValue(signMask, 0)); 8847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FABS) { 885825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 886825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 887602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT, 888602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op.getOperand(0), SDValue(signMask, 0)); 889825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 890825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 891825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 8927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel absConst, absConst); 8937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = emitBuildVector(absVec); 894602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT, 895602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op.getOperand(0), SDValue(signMask, 0)); 8967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 897266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 898266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 899e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = N->getValueType(0); 900475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 901475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 902266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 903a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 904a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 905a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 906dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin std::string msg; 907dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin raw_string_ostream Msg(msg); 908dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin Msg << "LDRESULT for unsupported type: " 909e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson << VT.getEVTString(); 910dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error(Msg.str()); 911a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel } 912266bc8f7774b153401e54ed537db299159840981Scott Michel 913a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel Opc = vtm->ldresult_ins; 914a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_imm) { 915475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, VT); 91686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 917602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain); 91886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 919602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain); 92086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 92186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 922266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 923053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 924f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // Look at the operands: SelectCode() will catch the cases that aren't 925f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // specifically handled here. 926f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // 927f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // SPUInstrInfo catches the following patterns: 928f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect (SPUhi ...), (SPUlo ...)) 929f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect $sp, imm) 930e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 931f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op0 = N->getOperand(0); 932f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op1 = N->getOperand(1); 933f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel RegisterSDNode *RN; 934f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel 935f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 936f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel || (Op0.getOpcode() == ISD::Register 937f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 938f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && RN->getReg() != SPU::R1))) { 939f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel NewOpc = SPU::Ar32; 94058c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 94158c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 942f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 9437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); 94458c5818c01e375a84dc601140470fa68638004cfScott Michel } 945f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[0] = Op0; 946f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[1] = Op1; 947f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel n_ops = 2; 94858c5818c01e375a84dc601140470fa68638004cfScott Michel } 949266bc8f7774b153401e54ed537db299159840981Scott Michel } 95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 95158c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 95258c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 95358c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 95458c5818c01e375a84dc601140470fa68638004cfScott Michel else 955602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops); 95658c5818c01e375a84dc601140470fa68638004cfScott Michel } else 95758c5818c01e375a84dc601140470fa68638004cfScott Michel return SelectCode(Op); 958266bc8f7774b153401e54ed537db299159840981Scott Michel} 959266bc8f7774b153401e54ed537db299159840981Scott Michel 96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 96102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm 96202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted 96302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left. 96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 96502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl. 96602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 96802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 96902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 97002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 97102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 97202d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 973e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) { 97402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Op0 = Op.getOperand(0); 97523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 97623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 978e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SelMaskVal; 981ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 983602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); 984825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 985602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); 986602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT, 987602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, OpVT)); 988602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 989602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(ZeroFill, 0), 990602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 991602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(SelMask, 0)); 99202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 99402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 99502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 99602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 999602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT, 1000602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1001602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 100202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 100302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 100402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 100502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1006602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT, 1007602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 1008602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 101002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 101102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1013602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1014602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 101502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1017602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1018602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT, 1021602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 102202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1023602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT, 1024602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 102502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 102602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1027602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 102902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 103002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 103102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts. 103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 103402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 103502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 103702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 103802d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 1039e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) { 104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue Op0 = Op.getOperand(0); 104123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 104223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 1044e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *Shift = 0; 1046ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1048602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); 104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 105302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 105402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1056602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT, 1057602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1058602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 105902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 106002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1063602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT, 1064602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 1065602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 106802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1070602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1071602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 107202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1073602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1074602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1075602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 107702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Ensure that the shift amounts are negated! 1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1079602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bytes, 0), 1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 108102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1082602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1083602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bits, 0), 1084602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1087602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT, 1088602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1090602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT, 1091602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 109502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 109602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts. 109902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 110002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 110102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 110202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 110302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 110402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 110502d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 1106e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) { 110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Promote Op0 to vector 110823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 110923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue ShiftAmt = Op.getOperand(1); 1111e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 1112ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = Op.getDebugLoc(); 111302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0 = 1115602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op.getOperand(0)); 111602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 111802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *SignRot = 1119602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, 1120602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SignRotAmt); 112102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSign = 1122602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ORi32_v4i32, dl, MVT::i32, SDValue(SignRot, 0)); 112302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 112402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSignMask = 1125602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); 112602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerMask = 1127602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, 1128602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 112902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerSelect = 1130602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 1131602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperHalfSignMask, 0), 1132602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1133602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerMask, 0)); 113402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 113502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Shift = 0; 113602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 113702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 113802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 113902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 114002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 114102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 114202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bytes = 31 - bytes; 114302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1144602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT, 1145602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), 1146602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 114702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 114802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 114902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 115002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bits = 8 - bits; 115102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1152602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT, 1153602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 1154602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 115502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 115602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 115702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *NegShift = 1158602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1159602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 116002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 116102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1162602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT, 1163602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 116402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1165602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT, 1166602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(NegShift, 0)); 116702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 116802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1169602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); 117002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 117102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1172c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*! 1173c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant 1174c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */ 1175e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, EVT OpVT, 11767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 1177c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode()); 11787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(CN->getZExtValue(), OpVT, dl); 11797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel} 11807ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1181e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, 11827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 118323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2); 1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue i64vec = 11857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl); 1186c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1187c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Here's where it gets interesting, because we have to parse out the 1188c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // subtree handed back in i64vec: 1189c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1190c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (i64vec.getOpcode() == ISD::BIT_CONVERT) { 1191c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // The degenerate case where the upper and lower bits in the splat are 1192c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // identical: 1193c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = i64vec.getOperand(0); 1194c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 11959de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ReplaceUses(i64vec, Op0); 1196602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, 1197602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(emitBuildVector(Op0), 0)); 1198c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue lhs = i64vec.getOperand(0); 1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue rhs = i64vec.getOperand(1); 1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shufmask = i64vec.getOperand(2); 1202c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1203c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (lhs.getOpcode() == ISD::BIT_CONVERT) { 1204c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(lhs, lhs.getOperand(0)); 1205c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel lhs = lhs.getOperand(0); 1206c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1207c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1208c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 1209c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? lhs.getNode() 1210c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(lhs)); 1211c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1212c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (rhs.getOpcode() == ISD::BIT_CONVERT) { 1213c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(rhs, rhs.getOperand(0)); 1214c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel rhs = rhs.getOperand(0); 1215c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1216c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1217c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 1218c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? rhs.getNode() 1219c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(rhs)); 12209de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 1221c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shufmask.getOpcode() == ISD::BIT_CONVERT) { 1222c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(shufmask, shufmask.getOperand(0)); 1223c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shufmask = shufmask.getOperand(0); 1224c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1225c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1226c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 1227c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? shufmask.getNode() 1228c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel : emitBuildVector(shufmask)); 1229c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1230c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufNode = 1231ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 1232c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(lhsNode, 0), SDValue(rhsNode, 0), 1233c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(shufMaskNode, 0))); 1234c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1235602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, 1236602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(shufNode, 0)); 12377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { 1238602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, 1239602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(emitBuildVector(i64vec), 0)); 1240c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else { 1241dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin llvm_report_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" 1242dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "condition"); 1243c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1244c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel} 1245c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 124602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a 1247266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 1248266bc8f7774b153401e54ed537db299159840981Scott Michel/// 1249266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 1250266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 1251266bc8f7774b153401e54ed537db299159840981Scott Michel} 1252