SPUISelDAGToDAG.cpp revision 7810bfed5570c192e0714a8fd0e5130a0c38dd2e
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" 21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h" 22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h" 23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h" 24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h" 25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h" 26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h" 27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h" 28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h" 29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h" 30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h" 31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h" 32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 34266bc8f7774b153401e54ed537db299159840981Scott Michel#include <queue> 35266bc8f7774b153401e54ed537db299159840981Scott Michel#include <set> 36266bc8f7774b153401e54ed537db299159840981Scott Michel 37266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 38266bc8f7774b153401e54ed537db299159840981Scott Michel 39266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 40266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 41266bc8f7774b153401e54ed537db299159840981Scott Michel bool 42266bc8f7774b153401e54ed537db299159840981Scott Michel isI64IntS10Immediate(ConstantSDNode *CN) 43266bc8f7774b153401e54ed537db299159840981Scott Michel { 447810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 45266bc8f7774b153401e54ed537db299159840981Scott Michel } 46266bc8f7774b153401e54ed537db299159840981Scott Michel 47266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 48266bc8f7774b153401e54ed537db299159840981Scott Michel bool 49266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 50266bc8f7774b153401e54ed537db299159840981Scott Michel { 517810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 52266bc8f7774b153401e54ed537db299159840981Scott Michel } 53266bc8f7774b153401e54ed537db299159840981Scott Michel 54266bc8f7774b153401e54ed537db299159840981Scott Michel#if 0 55266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for sign-extended, 10-bit immediate values 56266bc8f7774b153401e54ed537db299159840981Scott Michel bool 57266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(SDNode *N) 58266bc8f7774b153401e54ed537db299159840981Scott Michel { 59266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 60266bc8f7774b153401e54ed537db299159840981Scott Michel && isI32IntS10Immediate(cast<ConstantSDNode>(N))); 61266bc8f7774b153401e54ed537db299159840981Scott Michel } 62266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 63266bc8f7774b153401e54ed537db299159840981Scott Michel 64504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 65504c369213efb263136bb048e79af3516511c040Scott Michel bool 66504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 67504c369213efb263136bb048e79af3516511c040Scott Michel { 687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isU10Constant(CN->getSExtValue()); 69504c369213efb263136bb048e79af3516511c040Scott Michel } 70504c369213efb263136bb048e79af3516511c040Scott Michel 71266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 72266bc8f7774b153401e54ed537db299159840981Scott Michel bool 73266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 74266bc8f7774b153401e54ed537db299159840981Scott Michel { 757810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 76266bc8f7774b153401e54ed537db299159840981Scott Michel } 77266bc8f7774b153401e54ed537db299159840981Scott Michel 78266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 79266bc8f7774b153401e54ed537db299159840981Scott Michel bool 80266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(SDNode *N) 81266bc8f7774b153401e54ed537db299159840981Scott Michel { 82266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 83266bc8f7774b153401e54ed537db299159840981Scott Michel && isI16IntS10Immediate(cast<ConstantSDNode>(N))); 84266bc8f7774b153401e54ed537db299159840981Scott Michel } 85266bc8f7774b153401e54ed537db299159840981Scott Michel 86ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 87ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 88ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 89ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 90f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return isU10Constant((short) CN->getZExtValue()); 91ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 92ec2a08ff061af36b46160e475362959f21663e76Scott Michel 93ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 94ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 95ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(SDNode *N) 96ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 97ec2a08ff061af36b46160e475362959f21663e76Scott Michel return (N->getOpcode() == ISD::Constant 98ec2a08ff061af36b46160e475362959f21663e76Scott Michel && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 99ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 100ec2a08ff061af36b46160e475362959f21663e76Scott Michel 101266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 102266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 103266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 104266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 105266bc8f7774b153401e54ed537db299159840981Scott Michel 106266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 107266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 108266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 109266bc8f7774b153401e54ed537db299159840981Scott Michel */ 110266bc8f7774b153401e54ed537db299159840981Scott Michel bool 111266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 112266bc8f7774b153401e54ed537db299159840981Scott Michel { 11383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = CN->getValueType(0); 114f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 1158e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 116266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 117266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (vt == MVT::i32) { 118f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 119266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 120266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 121266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 122f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 123266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 124266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 125266bc8f7774b153401e54ed537db299159840981Scott Michel } 126266bc8f7774b153401e54ed537db299159840981Scott Michel 127266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 128266bc8f7774b153401e54ed537db299159840981Scott Michel } 129266bc8f7774b153401e54ed537db299159840981Scott Michel 130266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for signed 16-bit values. 131266bc8f7774b153401e54ed537db299159840981Scott Michel bool 132266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(SDNode *N, short &Imm) 133266bc8f7774b153401e54ed537db299159840981Scott Michel { 134266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 135266bc8f7774b153401e54ed537db299159840981Scott Michel && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 136266bc8f7774b153401e54ed537db299159840981Scott Michel } 137266bc8f7774b153401e54ed537db299159840981Scott Michel 138266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 139266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 140266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 141266bc8f7774b153401e54ed537db299159840981Scott Michel { 14283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = FPN->getValueType(0); 143266bc8f7774b153401e54ed537db299159840981Scott Michel if (vt == MVT::f32) { 144d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 145266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 146266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 147266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 148266bc8f7774b153401e54ed537db299159840981Scott Michel } 149266bc8f7774b153401e54ed537db299159840981Scott Michel 150266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 151266bc8f7774b153401e54ed537db299159840981Scott Michel } 152266bc8f7774b153401e54ed537db299159840981Scott Michel 153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel bool 154475871a144eb604ddaf37503397ba0941442e5fbDan Gohman isHighLow(const SDValue &Op) 155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { 156053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return (Op.getOpcode() == SPUISD::IndirectAddr 157053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 158053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Lo) 159053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op.getOperand(0).getOpcode() == SPUISD::Lo 160053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 161053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 162053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 163266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 16483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands //! MVT to "useful stuff" mapping structure: 165266bc8f7774b153401e54ed537db299159840981Scott Michel 166266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 16783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT; 1687f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 169a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 1707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int prefslot_byte; /// Byte offset of the "preferred" slot 171266bc8f7774b153401e54ed537db299159840981Scott Michel }; 172266bc8f7774b153401e54ed537db299159840981Scott Michel 173266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 174a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i1, 0, false, 3 }, 175a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i8, SPU::ORBIr8, true, 3 }, 176a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i16, SPU::ORHIr16, true, 2 }, 177a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i32, SPU::ORIr32, true, 0 }, 178a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i64, SPU::ORr64, false, 0 }, 179a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::f32, SPU::ORf32, false, 0 }, 180a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::f64, SPU::ORf64, false, 0 }, 18158c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 182a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v16i8, 0, false, 0 }, 183a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v8i16, 0, false, 0 }, 184a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v4i32, 0, false, 0 }, 185a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v2i64, 0, false, 0 }, 186a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v4f32, 0, false, 0 }, 187a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v2f64, 0, false, 0 } 188266bc8f7774b153401e54ed537db299159840981Scott Michel }; 189266bc8f7774b153401e54ed537db299159840981Scott Michel 190266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 191266bc8f7774b153401e54ed537db299159840981Scott Michel 19283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const valtype_map_s *getValueTypeMapEntry(MVT VT) 193266bc8f7774b153401e54ed537db299159840981Scott Michel { 194266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 195266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 196266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 199266bc8f7774b153401e54ed537db299159840981Scott Michel } 200266bc8f7774b153401e54ed537db299159840981Scott Michel } 201266bc8f7774b153401e54ed537db299159840981Scott Michel 202266bc8f7774b153401e54ed537db299159840981Scott Michel 203266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 204266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 205266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 20683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 2077f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel << "\n"; 208266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 209266bc8f7774b153401e54ed537db299159840981Scott Michel } 210266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 211266bc8f7774b153401e54ed537db299159840981Scott Michel 212266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 213266bc8f7774b153401e54ed537db299159840981Scott Michel } 214266bc8f7774b153401e54ed537db299159840981Scott Michel} 215266bc8f7774b153401e54ed537db299159840981Scott Michel 216844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace { 217844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 218266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===// 219266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 220266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations. 221266bc8f7774b153401e54ed537db299159840981Scott Michel/// 222266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel : 223266bc8f7774b153401e54ed537db299159840981Scott Michel public SelectionDAGISel 224266bc8f7774b153401e54ed537db299159840981Scott Michel{ 225266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetMachine &TM; 226266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetLowering &SPUtli; 227266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned GlobalBaseReg; 228266bc8f7774b153401e54ed537db299159840981Scott Michel 229266bc8f7774b153401e54ed537db299159840981Scott Michelpublic: 2301002c0203450620594a85454c6a095ca94b87cb2Dan Gohman explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 231266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel(*tm.getTargetLowering()), 232266bc8f7774b153401e54ed537db299159840981Scott Michel TM(tm), 233266bc8f7774b153401e54ed537db299159840981Scott Michel SPUtli(*tm.getTargetLowering()) 234266bc8f7774b153401e54ed537db299159840981Scott Michel {} 235266bc8f7774b153401e54ed537db299159840981Scott Michel 236266bc8f7774b153401e54ed537db299159840981Scott Michel virtual bool runOnFunction(Function &Fn) { 237266bc8f7774b153401e54ed537db299159840981Scott Michel // Make sure we re-emit a set of the global base reg if necessary 238266bc8f7774b153401e54ed537db299159840981Scott Michel GlobalBaseReg = 0; 239266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel::runOnFunction(Fn); 240266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 241266bc8f7774b153401e54ed537db299159840981Scott Michel } 242266bc8f7774b153401e54ed537db299159840981Scott Michel 243266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 244266bc8f7774b153401e54ed537db299159840981Scott Michel /// i32. 245475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getI32Imm(uint32_t Imm) { 246266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i32); 247266bc8f7774b153401e54ed537db299159840981Scott Michel } 248266bc8f7774b153401e54ed537db299159840981Scott Michel 249266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 250266bc8f7774b153401e54ed537db299159840981Scott Michel /// i64. 251475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getI64Imm(uint64_t Imm) { 252266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i64); 253266bc8f7774b153401e54ed537db299159840981Scott Michel } 254266bc8f7774b153401e54ed537db299159840981Scott Michel 255266bc8f7774b153401e54ed537db299159840981Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 256475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getSmallIPtrImm(unsigned Imm) { 257266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 258266bc8f7774b153401e54ed537db299159840981Scott Michel } 259266bc8f7774b153401e54ed537db299159840981Scott Michel 260266bc8f7774b153401e54ed537db299159840981Scott Michel /// Select - Convert the specified operand from a target-independent to a 261266bc8f7774b153401e54ed537db299159840981Scott Michel /// target-specific node if it hasn't already been changed. 262475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDNode *Select(SDValue Op); 263266bc8f7774b153401e54ed537db299159840981Scott Michel 264266bc8f7774b153401e54ed537db299159840981Scott Michel //! Returns true if the address N is an A-form (local store) address 265475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 266475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 267266bc8f7774b153401e54ed537db299159840981Scott Michel 268266bc8f7774b153401e54ed537db299159840981Scott Michel //! D-form address predicate 269475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 270475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 2717f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 2727f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /// Alternate D-form address using i7 offset predicate 273475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 274475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base); 2757f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 2767f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /// D-form address selection workhorse 277475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 278475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base, int minOffset, int maxOffset); 279266bc8f7774b153401e54ed537db299159840981Scott Michel 280266bc8f7774b153401e54ed537db299159840981Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 281475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 282475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 283266bc8f7774b153401e54ed537db299159840981Scott Michel 284266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 285266bc8f7774b153401e54ed537db299159840981Scott Michel /// inline asm expressions. 286475871a144eb604ddaf37503397ba0941442e5fbDan Gohman virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 2877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel char ConstraintCode, 288f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman std::vector<SDValue> &OutOps) { 289475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0, Op1; 290266bc8f7774b153401e54ed537db299159840981Scott Michel switch (ConstraintCode) { 291266bc8f7774b153401e54ed537db299159840981Scott Michel default: return true; 292266bc8f7774b153401e54ed537db299159840981Scott Michel case 'm': // memory 293266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 2947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 2957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 296266bc8f7774b153401e54ed537db299159840981Scott Michel break; 297266bc8f7774b153401e54ed537db299159840981Scott Michel case 'o': // offsetable 298266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 2997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 3007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Op0 = Op; 3017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel AddToISelQueue(Op0); // r+0. 3027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Op1 = getSmallIPtrImm(0); 303266bc8f7774b153401e54ed537db299159840981Scott Michel } 304266bc8f7774b153401e54ed537db299159840981Scott Michel break; 305266bc8f7774b153401e54ed537db299159840981Scott Michel case 'v': // not offsetable 306266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 307266bc8f7774b153401e54ed537db299159840981Scott Michel assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 308266bc8f7774b153401e54ed537db299159840981Scott Michel#else 309266bc8f7774b153401e54ed537db299159840981Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 310266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 311266bc8f7774b153401e54ed537db299159840981Scott Michel break; 312266bc8f7774b153401e54ed537db299159840981Scott Michel } 313266bc8f7774b153401e54ed537db299159840981Scott Michel 314266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op0); 315266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op1); 316266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 317266bc8f7774b153401e54ed537db299159840981Scott Michel } 318266bc8f7774b153401e54ed537db299159840981Scott Michel 319db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng /// InstructionSelect - This callback is invoked by 320266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 321f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman virtual void InstructionSelect(); 322266bc8f7774b153401e54ed537db299159840981Scott Michel 323266bc8f7774b153401e54ed537db299159840981Scott Michel virtual const char *getPassName() const { 324266bc8f7774b153401e54ed537db299159840981Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 325266bc8f7774b153401e54ed537db299159840981Scott Michel } 326266bc8f7774b153401e54ed537db299159840981Scott Michel 327266bc8f7774b153401e54ed537db299159840981Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 328266bc8f7774b153401e54ed537db299159840981Scott Michel /// this target when scheduling the DAG. 329266bc8f7774b153401e54ed537db299159840981Scott Michel virtual HazardRecognizer *CreateTargetHazardRecognizer() { 3306448d91ad1e5497fe2f7015d61b57cb5f3040879Dan Gohman const TargetInstrInfo *II = TM.getInstrInfo(); 331266bc8f7774b153401e54ed537db299159840981Scott Michel assert(II && "No InstrInfo?"); 332266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUHazardRecognizer(*II); 333266bc8f7774b153401e54ed537db299159840981Scott Michel } 334266bc8f7774b153401e54ed537db299159840981Scott Michel 335266bc8f7774b153401e54ed537db299159840981Scott Michel // Include the pieces autogenerated from the target description. 336266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 337266bc8f7774b153401e54ed537db299159840981Scott Michel}; 338266bc8f7774b153401e54ed537db299159840981Scott Michel 339844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 340844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 341db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by 342266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 343266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 344f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect() 345266bc8f7774b153401e54ed537db299159840981Scott Michel{ 346266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 347266bc8f7774b153401e54ed537db299159840981Scott Michel 348266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 349ad3460c3c968e33c5b9a07104b9fe5a5c27ff55bDan Gohman SelectRoot(); 350f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman CurDAG->RemoveDeadNodes(); 351266bc8f7774b153401e54ed537db299159840981Scott Michel} 352266bc8f7774b153401e54ed537db299159840981Scott Michel 353266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 354266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand 355266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 356266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 357266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 358266bc8f7774b153401e54ed537db299159840981Scott Michel */ 359266bc8f7774b153401e54ed537db299159840981Scott Michelbool 360475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 361475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 362266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 36383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OffsVT = MVT::i16; 364475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 365266bc8f7774b153401e54ed537db299159840981Scott Michel 366266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 367266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 3689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 3699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 3709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 3719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel abort(); 3729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 3739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 374053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 3759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 376053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 377053c1da8d956a794d158ac906b3927c923f97c4dScott Michel cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as " 378053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << "A-form address.\n"; 379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel abort(); 380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 381266bc8f7774b153401e54ed537db299159840981Scott Michel 382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case SPUISD::AFormAddr: 383053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 386475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 390053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 392053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 393053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 395053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 396053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 400053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 405053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 407053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 408266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 409266bc8f7774b153401e54ed537db299159840981Scott Michel} 410266bc8f7774b153401e54ed537db299159840981Scott Michel 4117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 412475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 413475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 414203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 415203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 416203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 417203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4187f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 420266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 421266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 422266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 423266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 424266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 425266bc8f7774b153401e54ed537db299159840981Scott Michel 426266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 427266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 428266bc8f7774b153401e54ed537db299159840981Scott Michel 429266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 430475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 431266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 432266bc8f7774b153401e54ed537db299159840981Scott Michelbool 433475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 434475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 4357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 4367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel SPUFrameInfo::minFrameOffset(), 4377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel SPUFrameInfo::maxFrameOffset()); 4387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 4407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 441475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 442475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 4437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 444266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 44583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrTy = SPUtli.getPointerTy(); 446266bc8f7774b153401e54ed537db299159840981Scott Michel 447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 449203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 450203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 451266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 452203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 453203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 454266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 455203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 456266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 457266bc8f7774b153401e54ed537db299159840981Scott Michel } 458266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 459266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 460475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 461475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 462266bc8f7774b153401e54ed537db299159840981Scott Michel 463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 467053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 468053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 469053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 4709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 4717810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 472266bc8f7774b153401e54ed537db299159840981Scott Michel 473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 474203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 475203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 477203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 4789de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 479203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 481203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4839de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 4859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 489053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 4927810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 493053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 496203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 497053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 498203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 499053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 500203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 501053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 502203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5039de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5049de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 506053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 509266bc8f7774b153401e54ed537db299159840981Scott Michel } 510497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 511053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 513475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 514475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5167f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5177f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5199de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5219de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5227f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5237f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 524475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5257f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5267f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5277f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 5287810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5297f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 5327810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 5347f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 5387f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 5397f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 5407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 542053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 54558c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 5467f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 5477f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 5487f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 5497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 550266bc8f7774b153401e54ed537db299159840981Scott Michel } 551266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 552266bc8f7774b153401e54ed537db299159840981Scott Michel} 553266bc8f7774b153401e54ed537db299159840981Scott Michel 554266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 555266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 556266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 557266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 558266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 559266bc8f7774b153401e54ed537db299159840981Scott Michel 560266bc8f7774b153401e54ed537db299159840981Scott Michel If the address \a N can be expressed as a [r + s10imm] address, returns false. 561266bc8f7774b153401e54ed537db299159840981Scott Michel Otherwise, creates two operands, Base and Index that will become the [r+r] 562266bc8f7774b153401e54ed537db299159840981Scott Michel address. 563266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 564266bc8f7774b153401e54ed537db299159840981Scott Michelbool 565475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 566475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 567266bc8f7774b153401e54ed537db299159840981Scott Michel if (SelectAFormAddr(Op, N, Base, Index) 568266bc8f7774b153401e54ed537db299159840981Scott Michel || SelectDFormAddr(Op, N, Base, Index)) 569266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 570266bc8f7774b153401e54ed537db299159840981Scott Michel 571053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // All else fails, punt and use an X-form address: 572053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = N.getOperand(0); 573053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N.getOperand(1); 574053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 57558c5818c01e375a84dc601140470fa68638004cfScott Michel} 57658c5818c01e375a84dc601140470fa68638004cfScott Michel 577266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 578266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 579266bc8f7774b153401e54ed537db299159840981Scott Michel */ 580266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 581475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) { 582ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *N = Op.getNode(); 583266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 58458c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 58558c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 58683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OpVT = Op.getValueType(); 587475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 588266bc8f7774b153401e54ed537db299159840981Scott Michel 589e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman if (N->isMachineOpcode()) { 590266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 591266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::FrameIndex) { 592203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel // Selects to (add $sp, FI * stackSlotSize) 593203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = 594203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex()); 59583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrVT = SPUtli.getPointerTy(); 596203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel 597203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel // Adjust stack slot to actual offset in frame: 598203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (isS10Constant(FI)) { 599203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, " 600203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI 601203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << "\n"); 602203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 603203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT); 604203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[1] = CurDAG->getTargetConstant(FI, PtrVT); 605203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 606203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 607203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, " 608203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI 609203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << "\n"); 610203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 611203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT); 612203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[1] = CurDAG->getConstant(FI, PtrVT); 613203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 614203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel 615203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel AddToISelQueue(Ops[1]); 616203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 61758c5818c01e375a84dc601140470fa68638004cfScott Michel } else if (Opc == ISD::ZERO_EXTEND) { 61858c5818c01e375a84dc601140470fa68638004cfScott Michel // (zero_extend:i16 (and:i8 <arg>, <const>)) 619475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue &Op1 = N->getOperand(0); 62058c5818c01e375a84dc601140470fa68638004cfScott Michel 62158c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) { 62258c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::AND) { 62358c5818c01e375a84dc601140470fa68638004cfScott Michel // Fold this into a single ANDHI. This is often seen in expansions of i1 62458c5818c01e375a84dc601140470fa68638004cfScott Michel // to i8, then i8 to i16 in logical/branching operations. 62558c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 " 62658c5818c01e375a84dc601140470fa68638004cfScott Michel "<arg>, <const>))\n"); 627a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel NewOpc = SPU::ANDHIi8i16; 62858c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[0] = Op1.getOperand(0); 62958c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[1] = Op1.getOperand(1); 63058c5818c01e375a84dc601140470fa68638004cfScott Michel n_ops = 2; 63158c5818c01e375a84dc601140470fa68638004cfScott Michel } 63258c5818c01e375a84dc601140470fa68638004cfScott Michel } 633266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 634266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 63583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = N->getValueType(0); 636475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 637475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 638266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 639a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 640a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 641a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 642a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel cerr << "LDRESULT for unsupported type: " 64383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 644a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel << "\n"; 645a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel abort(); 646a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel } 647266bc8f7774b153401e54ed537db299159840981Scott Michel 648266bc8f7774b153401e54ed537db299159840981Scott Michel AddToISelQueue(Arg); 649a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel Opc = vtm->ldresult_ins; 650a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_imm) { 651475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, VT); 65286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 65386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Zero); 65458c5818c01e375a84dc601140470fa68638004cfScott Michel Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain); 65586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 65658c5818c01e375a84dc601140470fa68638004cfScott Michel Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain); 65786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 65886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 659475871a144eb604ddaf37503397ba0941442e5fbDan Gohman Chain = SDValue(Result, 1); 66086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Chain); 66186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 662266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 663053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 664475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = Op.getOperand(0); 6657f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::LDRESULT) { 6667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /* || Op0.getOpcode() == SPUISD::AFormAddr) */ 6677f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel // (IndirectAddr (LDRESULT, imm)) 668475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op1 = Op.getOperand(1); 66983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 67058c5818c01e375a84dc601140470fa68638004cfScott Michel 6717f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = "); 672ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif DEBUG(Op.getOperand(0).getNode()->dump(CurDAG)); 67358c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\nOp1 = "); 674ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif DEBUG(Op.getOperand(1).getNode()->dump(CurDAG)); 67558c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\n"); 67658c5818c01e375a84dc601140470fa68638004cfScott Michel 67758c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 67858c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 679f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Op1 = CurDAG->getTargetConstant(CN->getZExtValue(), VT); 6807f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); 6817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel AddToISelQueue(Op0); 6827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel AddToISelQueue(Op1); 6837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Ops[0] = Op0; 6847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Ops[1] = Op1; 6857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel n_ops = 2; 68658c5818c01e375a84dc601140470fa68638004cfScott Michel } 68758c5818c01e375a84dc601140470fa68638004cfScott Michel } 688266bc8f7774b153401e54ed537db299159840981Scott Michel } 689266bc8f7774b153401e54ed537db299159840981Scott Michel 69058c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 69158c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 69258c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 69358c5818c01e375a84dc601140470fa68638004cfScott Michel else 69458c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops); 69558c5818c01e375a84dc601140470fa68638004cfScott Michel } else 69658c5818c01e375a84dc601140470fa68638004cfScott Michel return SelectCode(Op); 697266bc8f7774b153401e54ed537db299159840981Scott Michel} 698266bc8f7774b153401e54ed537db299159840981Scott Michel 699266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a 700266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 701266bc8f7774b153401e54ed537db299159840981Scott Michel/// 702266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 703266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 704266bc8f7774b153401e54ed537db299159840981Scott Michel} 705