SPUISelDAGToDAG.cpp revision aedc637c966b6eaa3ca33e9220efe5ec34517de7
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 35266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 36266bc8f7774b153401e54ed537db299159840981Scott Michel 37266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 38266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 39266bc8f7774b153401e54ed537db299159840981Scott Michel bool 40266bc8f7774b153401e54ed537db299159840981Scott Michel isI64IntS10Immediate(ConstantSDNode *CN) 41266bc8f7774b153401e54ed537db299159840981Scott Michel { 427810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 43266bc8f7774b153401e54ed537db299159840981Scott Michel } 44266bc8f7774b153401e54ed537db299159840981Scott Michel 45266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 46266bc8f7774b153401e54ed537db299159840981Scott Michel bool 47266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 48266bc8f7774b153401e54ed537db299159840981Scott Michel { 497810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 50266bc8f7774b153401e54ed537db299159840981Scott Michel } 51266bc8f7774b153401e54ed537db299159840981Scott Michel 52266bc8f7774b153401e54ed537db299159840981Scott Michel#if 0 53266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for sign-extended, 10-bit immediate values 54266bc8f7774b153401e54ed537db299159840981Scott Michel bool 55266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(SDNode *N) 56266bc8f7774b153401e54ed537db299159840981Scott Michel { 57266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 58266bc8f7774b153401e54ed537db299159840981Scott Michel && isI32IntS10Immediate(cast<ConstantSDNode>(N))); 59266bc8f7774b153401e54ed537db299159840981Scott Michel } 60266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 61266bc8f7774b153401e54ed537db299159840981Scott Michel 62504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 63504c369213efb263136bb048e79af3516511c040Scott Michel bool 64504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 65504c369213efb263136bb048e79af3516511c040Scott Michel { 667810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isU10Constant(CN->getSExtValue()); 67504c369213efb263136bb048e79af3516511c040Scott Michel } 68504c369213efb263136bb048e79af3516511c040Scott Michel 69266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 70266bc8f7774b153401e54ed537db299159840981Scott Michel bool 71266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 72266bc8f7774b153401e54ed537db299159840981Scott Michel { 737810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman return isS10Constant(CN->getSExtValue()); 74266bc8f7774b153401e54ed537db299159840981Scott Michel } 75266bc8f7774b153401e54ed537db299159840981Scott Michel 76266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 77266bc8f7774b153401e54ed537db299159840981Scott Michel bool 78266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(SDNode *N) 79266bc8f7774b153401e54ed537db299159840981Scott Michel { 80266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 81266bc8f7774b153401e54ed537db299159840981Scott Michel && isI16IntS10Immediate(cast<ConstantSDNode>(N))); 82266bc8f7774b153401e54ed537db299159840981Scott Michel } 83266bc8f7774b153401e54ed537db299159840981Scott Michel 84ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 85ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 86ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 87ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 88f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return isU10Constant((short) CN->getZExtValue()); 89ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 90ec2a08ff061af36b46160e475362959f21663e76Scott Michel 91ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! SDNode predicate for i16 sign-extended, 10-bit immediate values 92ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 93ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(SDNode *N) 94ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 95ec2a08ff061af36b46160e475362959f21663e76Scott Michel return (N->getOpcode() == ISD::Constant 96ec2a08ff061af36b46160e475362959f21663e76Scott Michel && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 97ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 98ec2a08ff061af36b46160e475362959f21663e76Scott Michel 99266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 100266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 101266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 102266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 103266bc8f7774b153401e54ed537db299159840981Scott Michel 104266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 105266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 106266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 107266bc8f7774b153401e54ed537db299159840981Scott Michel */ 108266bc8f7774b153401e54ed537db299159840981Scott Michel bool 109266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 110266bc8f7774b153401e54ed537db299159840981Scott Michel { 11183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = CN->getValueType(0); 112f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 1138e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 114266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 115266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (vt == MVT::i32) { 116f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 117266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 118266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 119266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 120f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 121266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 122266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 123266bc8f7774b153401e54ed537db299159840981Scott Michel } 124266bc8f7774b153401e54ed537db299159840981Scott Michel 125266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 126266bc8f7774b153401e54ed537db299159840981Scott Michel } 127266bc8f7774b153401e54ed537db299159840981Scott Michel 128266bc8f7774b153401e54ed537db299159840981Scott Michel //! SDNode predicate for signed 16-bit values. 129266bc8f7774b153401e54ed537db299159840981Scott Michel bool 130266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(SDNode *N, short &Imm) 131266bc8f7774b153401e54ed537db299159840981Scott Michel { 132266bc8f7774b153401e54ed537db299159840981Scott Michel return (N->getOpcode() == ISD::Constant 133266bc8f7774b153401e54ed537db299159840981Scott Michel && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 134266bc8f7774b153401e54ed537db299159840981Scott Michel } 135266bc8f7774b153401e54ed537db299159840981Scott Michel 136266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 137266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 138266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 139266bc8f7774b153401e54ed537db299159840981Scott Michel { 14083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT vt = FPN->getValueType(0); 141266bc8f7774b153401e54ed537db299159840981Scott Michel if (vt == MVT::f32) { 142d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 143266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 144266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 145266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 146266bc8f7774b153401e54ed537db299159840981Scott Michel } 147266bc8f7774b153401e54ed537db299159840981Scott Michel 148266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 149266bc8f7774b153401e54ed537db299159840981Scott Michel } 150266bc8f7774b153401e54ed537db299159840981Scott Michel 151053c1da8d956a794d158ac906b3927c923f97c4dScott Michel bool 152475871a144eb604ddaf37503397ba0941442e5fbDan Gohman isHighLow(const SDValue &Op) 153053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { 154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return (Op.getOpcode() == SPUISD::IndirectAddr 155053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 156053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Lo) 157053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op.getOperand(0).getOpcode() == SPUISD::Lo 158053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 159053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 160053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 161266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 16283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands //! MVT to "useful stuff" mapping structure: 163266bc8f7774b153401e54ed537db299159840981Scott Michel 164266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 16583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT; 1667f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 167a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel bool ldresult_imm; /// LDRESULT instruction requires immediate? 1687f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int prefslot_byte; /// Byte offset of the "preferred" slot 169266bc8f7774b153401e54ed537db299159840981Scott Michel }; 170266bc8f7774b153401e54ed537db299159840981Scott Michel 171266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 172a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i1, 0, false, 3 }, 173a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i8, SPU::ORBIr8, true, 3 }, 174a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i16, SPU::ORHIr16, true, 2 }, 175a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i32, SPU::ORIr32, true, 0 }, 176a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::i64, SPU::ORr64, false, 0 }, 177a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::f32, SPU::ORf32, false, 0 }, 178a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::f64, SPU::ORf64, false, 0 }, 17958c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 180a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v16i8, 0, false, 0 }, 181a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v8i16, 0, false, 0 }, 182a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v4i32, 0, false, 0 }, 183a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v2i64, 0, false, 0 }, 184a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v4f32, 0, false, 0 }, 185a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel { MVT::v2f64, 0, false, 0 } 186266bc8f7774b153401e54ed537db299159840981Scott Michel }; 187266bc8f7774b153401e54ed537db299159840981Scott Michel 188266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 189266bc8f7774b153401e54ed537db299159840981Scott Michel 19083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const valtype_map_s *getValueTypeMapEntry(MVT VT) 191266bc8f7774b153401e54ed537db299159840981Scott Michel { 192266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 193266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 194266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 1957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel retval = valtype_map + i; 1967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel break; 197266bc8f7774b153401e54ed537db299159840981Scott Michel } 198266bc8f7774b153401e54ed537db299159840981Scott Michel } 199266bc8f7774b153401e54ed537db299159840981Scott Michel 200266bc8f7774b153401e54ed537db299159840981Scott Michel 201266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 202266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 203266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 20483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 2057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel << "\n"; 206266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 207266bc8f7774b153401e54ed537db299159840981Scott Michel } 208266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 209266bc8f7774b153401e54ed537db299159840981Scott Michel 210266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 211266bc8f7774b153401e54ed537db299159840981Scott Michel } 212266bc8f7774b153401e54ed537db299159840981Scott Michel} 213266bc8f7774b153401e54ed537db299159840981Scott Michel 214844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace { 215844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 216266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===// 217266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 218266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations. 219266bc8f7774b153401e54ed537db299159840981Scott Michel/// 220266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel : 221266bc8f7774b153401e54ed537db299159840981Scott Michel public SelectionDAGISel 222266bc8f7774b153401e54ed537db299159840981Scott Michel{ 223266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetMachine &TM; 224266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetLowering &SPUtli; 225266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned GlobalBaseReg; 226266bc8f7774b153401e54ed537db299159840981Scott Michel 227266bc8f7774b153401e54ed537db299159840981Scott Michelpublic: 2281002c0203450620594a85454c6a095ca94b87cb2Dan Gohman explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 229266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel(*tm.getTargetLowering()), 230266bc8f7774b153401e54ed537db299159840981Scott Michel TM(tm), 231266bc8f7774b153401e54ed537db299159840981Scott Michel SPUtli(*tm.getTargetLowering()) 232266bc8f7774b153401e54ed537db299159840981Scott Michel {} 233266bc8f7774b153401e54ed537db299159840981Scott Michel 234266bc8f7774b153401e54ed537db299159840981Scott Michel virtual bool runOnFunction(Function &Fn) { 235266bc8f7774b153401e54ed537db299159840981Scott Michel // Make sure we re-emit a set of the global base reg if necessary 236266bc8f7774b153401e54ed537db299159840981Scott Michel GlobalBaseReg = 0; 237266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel::runOnFunction(Fn); 238266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 239266bc8f7774b153401e54ed537db299159840981Scott Michel } 240266bc8f7774b153401e54ed537db299159840981Scott Michel 241266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 242266bc8f7774b153401e54ed537db299159840981Scott Michel /// i32. 243475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getI32Imm(uint32_t Imm) { 244266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i32); 245266bc8f7774b153401e54ed537db299159840981Scott Michel } 246266bc8f7774b153401e54ed537db299159840981Scott Michel 247266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 248266bc8f7774b153401e54ed537db299159840981Scott Michel /// i64. 249475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getI64Imm(uint64_t Imm) { 250266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i64); 251266bc8f7774b153401e54ed537db299159840981Scott Michel } 252266bc8f7774b153401e54ed537db299159840981Scott Michel 253266bc8f7774b153401e54ed537db299159840981Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 254475871a144eb604ddaf37503397ba0941442e5fbDan Gohman inline SDValue getSmallIPtrImm(unsigned Imm) { 255266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 256266bc8f7774b153401e54ed537db299159840981Scott Michel } 257266bc8f7774b153401e54ed537db299159840981Scott Michel 258266bc8f7774b153401e54ed537db299159840981Scott Michel /// Select - Convert the specified operand from a target-independent to a 259266bc8f7774b153401e54ed537db299159840981Scott Michel /// target-specific node if it hasn't already been changed. 260475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDNode *Select(SDValue Op); 261266bc8f7774b153401e54ed537db299159840981Scott Michel 262266bc8f7774b153401e54ed537db299159840981Scott Michel //! Returns true if the address N is an A-form (local store) address 263475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 264475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 265266bc8f7774b153401e54ed537db299159840981Scott Michel 266266bc8f7774b153401e54ed537db299159840981Scott Michel //! D-form address predicate 267475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 268475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 2697f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 2707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /// Alternate D-form address using i7 offset predicate 271475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 272475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base); 2737f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 2747f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /// D-form address selection workhorse 275475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 276475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base, int minOffset, int maxOffset); 277266bc8f7774b153401e54ed537db299159840981Scott Michel 278266bc8f7774b153401e54ed537db299159840981Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 279475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 280475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index); 281266bc8f7774b153401e54ed537db299159840981Scott Michel 282266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 283266bc8f7774b153401e54ed537db299159840981Scott Michel /// inline asm expressions. 284475871a144eb604ddaf37503397ba0941442e5fbDan Gohman virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 2857f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel char ConstraintCode, 286f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman std::vector<SDValue> &OutOps) { 287475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0, Op1; 288266bc8f7774b153401e54ed537db299159840981Scott Michel switch (ConstraintCode) { 289266bc8f7774b153401e54ed537db299159840981Scott Michel default: return true; 290266bc8f7774b153401e54ed537db299159840981Scott Michel case 'm': // memory 291266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 2927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 2937f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 294266bc8f7774b153401e54ed537db299159840981Scott Michel break; 295266bc8f7774b153401e54ed537db299159840981Scott Michel case 'o': // offsetable 296266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 2977f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 2987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Op0 = Op; 2997f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Op1 = getSmallIPtrImm(0); 300266bc8f7774b153401e54ed537db299159840981Scott Michel } 301266bc8f7774b153401e54ed537db299159840981Scott Michel break; 302266bc8f7774b153401e54ed537db299159840981Scott Michel case 'v': // not offsetable 303266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 304266bc8f7774b153401e54ed537db299159840981Scott Michel assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 305266bc8f7774b153401e54ed537db299159840981Scott Michel#else 306266bc8f7774b153401e54ed537db299159840981Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 307266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 308266bc8f7774b153401e54ed537db299159840981Scott Michel break; 309266bc8f7774b153401e54ed537db299159840981Scott Michel } 310266bc8f7774b153401e54ed537db299159840981Scott Michel 311266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op0); 312266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op1); 313266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 314266bc8f7774b153401e54ed537db299159840981Scott Michel } 315266bc8f7774b153401e54ed537db299159840981Scott Michel 316db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng /// InstructionSelect - This callback is invoked by 317266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 318f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman virtual void InstructionSelect(); 319266bc8f7774b153401e54ed537db299159840981Scott Michel 320266bc8f7774b153401e54ed537db299159840981Scott Michel virtual const char *getPassName() const { 321266bc8f7774b153401e54ed537db299159840981Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 322266bc8f7774b153401e54ed537db299159840981Scott Michel } 323266bc8f7774b153401e54ed537db299159840981Scott Michel 324266bc8f7774b153401e54ed537db299159840981Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 325266bc8f7774b153401e54ed537db299159840981Scott Michel /// this target when scheduling the DAG. 326266bc8f7774b153401e54ed537db299159840981Scott Michel virtual HazardRecognizer *CreateTargetHazardRecognizer() { 3276448d91ad1e5497fe2f7015d61b57cb5f3040879Dan Gohman const TargetInstrInfo *II = TM.getInstrInfo(); 328266bc8f7774b153401e54ed537db299159840981Scott Michel assert(II && "No InstrInfo?"); 329266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUHazardRecognizer(*II); 330266bc8f7774b153401e54ed537db299159840981Scott Michel } 331266bc8f7774b153401e54ed537db299159840981Scott Michel 332266bc8f7774b153401e54ed537db299159840981Scott Michel // Include the pieces autogenerated from the target description. 333266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 334266bc8f7774b153401e54ed537db299159840981Scott Michel}; 335266bc8f7774b153401e54ed537db299159840981Scott Michel 336844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 337844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 338db8d56b825efeb576d67b9dbe39d736d93306222Evan Cheng/// InstructionSelect - This callback is invoked by 339266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 340266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 341f350b277f32d7d47f86c0e54f4aec4d470500618Dan GohmanSPUDAGToDAGISel::InstructionSelect() 342266bc8f7774b153401e54ed537db299159840981Scott Michel{ 343266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 344266bc8f7774b153401e54ed537db299159840981Scott Michel 345266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 3468ad4c00c00233acb8a3395098e2b575cc34de46bDavid Greene SelectRoot(*CurDAG); 347f350b277f32d7d47f86c0e54f4aec4d470500618Dan Gohman CurDAG->RemoveDeadNodes(); 348266bc8f7774b153401e54ed537db299159840981Scott Michel} 349266bc8f7774b153401e54ed537db299159840981Scott Michel 350266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 351266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand 352266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 353266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 354266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 355266bc8f7774b153401e54ed537db299159840981Scott Michel */ 356266bc8f7774b153401e54ed537db299159840981Scott Michelbool 357475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 358475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 359266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 36083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OffsVT = MVT::i16; 361475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 362266bc8f7774b153401e54ed537db299159840981Scott Michel 363266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 364266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 3659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 3669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 3679de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 3689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel abort(); 3699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 3709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 371053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 3729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 373053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 374053c1da8d956a794d158ac906b3927c923f97c4dScott Michel cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as " 375053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << "A-form address.\n"; 376053c1da8d956a794d158ac906b3927c923f97c4dScott Michel abort(); 377053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 378266bc8f7774b153401e54ed537db299159840981Scott Michel 379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case SPUISD::AFormAddr: 380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 381053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 383475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 386053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 390053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 391053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 392053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 393053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 394053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 395053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 396053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 397053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 398053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 399053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 400053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 401053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 402053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 403053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 404053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 405266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 406266bc8f7774b153401e54ed537db299159840981Scott Michel} 407266bc8f7774b153401e54ed537db299159840981Scott Michel 4087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 409475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 410475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 411203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 412203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 413203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 414203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 4157f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4167f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 417266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 418266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 419266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 420266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 421266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 422266bc8f7774b153401e54ed537db299159840981Scott Michel 423266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 424266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 425266bc8f7774b153401e54ed537db299159840981Scott Michel 426266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 427475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 428266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 429266bc8f7774b153401e54ed537db299159840981Scott Michelbool 430475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 431475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 4327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 4339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 4349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 4357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 4377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 438475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 439475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 4407f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 441266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 44283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrTy = SPUtli.getPointerTy(); 443266bc8f7774b153401e54ed537db299159840981Scott Michel 444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 446203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 447203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 448266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 449203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 450203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 451266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 452203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 453266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 454266bc8f7774b153401e54ed537db299159840981Scott Michel } 455266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 456266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 457475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 458475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 459266bc8f7774b153401e54ed537db299159840981Scott Michel 460053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 461053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 462053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 463053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 465053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 4679de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 4687810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 469266bc8f7774b153401e54ed537db299159840981Scott Michel 470053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 471203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 472203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 474203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 4759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 476203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 478203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 484053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 485053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 4897810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 492203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 493203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 495203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 496053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 497203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 498053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 499203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 503053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 504053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 505053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 506266bc8f7774b153401e54ed537db299159840981Scott Michel } 507497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 510475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 511475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 5137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 5147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 517053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5197f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 5207f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 521475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 5227f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5237f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 5247f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 5257810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5267f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 5277f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 5287f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 5297810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 5307f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 5317f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5327f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5337f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 5347f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 5357f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 5367f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 5377f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 54258c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 5437f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 5447f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 5457f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 5467f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 5479c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { 5489c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel unsigned OpOpc = Op.getOpcode(); 5499c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5509c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 5519c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 5529c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SDValue Addr, Offs; 5539c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5549c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Get the register from CopyFromReg 5559c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Opc == ISD::CopyFromReg) 5569c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N.getOperand(1); 5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel else 5589c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Addr = N; // Register 5599c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 560aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); 5619c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5629c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 5639c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 5649c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 5659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5669c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 5679c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Index = Addr; 5689c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 5699c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 570aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 571aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 572aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 573aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Index = N.getOperand(1); 574aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 575aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Index = N; 576aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 577aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 578aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 579aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 5809c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 581266bc8f7774b153401e54ed537db299159840981Scott Michel } 5829c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 583266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 584266bc8f7774b153401e54ed537db299159840981Scott Michel} 585266bc8f7774b153401e54ed537db299159840981Scott Michel 586266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 587266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 588266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 589266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 590266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 591266bc8f7774b153401e54ed537db299159840981Scott Michel 5929c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 5939c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 5949c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 595266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 596266bc8f7774b153401e54ed537db299159840981Scott Michelbool 597475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 598475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 5999c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 6009c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 60118fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 60218fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 6031a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 6041a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 60550843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 6069c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 607266bc8f7774b153401e54ed537db299159840981Scott Michel 6089c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 60958c5818c01e375a84dc601140470fa68638004cfScott Michel} 61058c5818c01e375a84dc601140470fa68638004cfScott Michel 611266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 612266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 613266bc8f7774b153401e54ed537db299159840981Scott Michel */ 614266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 615475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSPUDAGToDAGISel::Select(SDValue Op) { 616ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *N = Op.getNode(); 617266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 61858c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 61958c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 62083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OpVT = Op.getValueType(); 621475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 622266bc8f7774b153401e54ed537db299159840981Scott Michel 623e8be6c63915e0389f1eef6b53c64300d13b2ce99Dan Gohman if (N->isMachineOpcode()) { 624266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 625266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::FrameIndex) { 626203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel // Selects to (add $sp, FI * stackSlotSize) 627203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = 628203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex()); 62983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrVT = SPUtli.getPointerTy(); 630203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel 631203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel // Adjust stack slot to actual offset in frame: 632203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (isS10Constant(FI)) { 633203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, " 634203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI 635203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << "\n"); 636203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 637203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT); 638203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[1] = CurDAG->getTargetConstant(FI, PtrVT); 639203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 640203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 641203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, " 642203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI 643203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << "\n"); 644203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 645203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT); 646203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Ops[1] = CurDAG->getConstant(FI, PtrVT); 647203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 648203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 64958c5818c01e375a84dc601140470fa68638004cfScott Michel } else if (Opc == ISD::ZERO_EXTEND) { 65058c5818c01e375a84dc601140470fa68638004cfScott Michel // (zero_extend:i16 (and:i8 <arg>, <const>)) 651475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue &Op1 = N->getOperand(0); 65258c5818c01e375a84dc601140470fa68638004cfScott Michel 65358c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) { 65458c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::AND) { 65558c5818c01e375a84dc601140470fa68638004cfScott Michel // Fold this into a single ANDHI. This is often seen in expansions of i1 65658c5818c01e375a84dc601140470fa68638004cfScott Michel // to i8, then i8 to i16 in logical/branching operations. 65758c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 " 65858c5818c01e375a84dc601140470fa68638004cfScott Michel "<arg>, <const>))\n"); 659a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel NewOpc = SPU::ANDHIi8i16; 66058c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[0] = Op1.getOperand(0); 66158c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[1] = Op1.getOperand(1); 66258c5818c01e375a84dc601140470fa68638004cfScott Michel n_ops = 2; 66358c5818c01e375a84dc601140470fa68638004cfScott Michel } 66458c5818c01e375a84dc601140470fa68638004cfScott Michel } 665266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 666266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 66783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = N->getValueType(0); 668475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 669475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 670266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 671a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 672a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel 673a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_ins == 0) { 674a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel cerr << "LDRESULT for unsupported type: " 67583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands << VT.getMVTString() 676a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel << "\n"; 677a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel abort(); 678a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel } 679266bc8f7774b153401e54ed537db299159840981Scott Michel 680a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel Opc = vtm->ldresult_ins; 681a59d469e9b31087f0f045bcb5d1a154c963be9b7Scott Michel if (vtm->ldresult_imm) { 682475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, VT); 68386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 68458c5818c01e375a84dc601140470fa68638004cfScott Michel Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain); 68586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 68630ee7df71c4b08da5d7e3f772f29f7c9ca57d8faScott Michel Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Arg, Chain); 68786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 68886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 689475871a144eb604ddaf37503397ba0941442e5fbDan Gohman Chain = SDValue(Result, 1); 69086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 691266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 692053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 693475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = Op.getOperand(0); 6947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::LDRESULT) { 6957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel /* || Op0.getOpcode() == SPUISD::AFormAddr) */ 6967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel // (IndirectAddr (LDRESULT, imm)) 697475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op1 = Op.getOperand(1); 69883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 69958c5818c01e375a84dc601140470fa68638004cfScott Michel 7007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = "); 701ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif DEBUG(Op.getOperand(0).getNode()->dump(CurDAG)); 70258c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\nOp1 = "); 703ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif DEBUG(Op.getOperand(1).getNode()->dump(CurDAG)); 70458c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\n"); 70558c5818c01e375a84dc601140470fa68638004cfScott Michel 70658c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 70758c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 708f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Op1 = CurDAG->getTargetConstant(CN->getZExtValue(), VT); 7097f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); 7107f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Ops[0] = Op0; 7117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Ops[1] = Op1; 7127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel n_ops = 2; 71358c5818c01e375a84dc601140470fa68638004cfScott Michel } 71458c5818c01e375a84dc601140470fa68638004cfScott Michel } 715266bc8f7774b153401e54ed537db299159840981Scott Michel } 716266bc8f7774b153401e54ed537db299159840981Scott Michel 71758c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 71858c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 71958c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 72058c5818c01e375a84dc601140470fa68638004cfScott Michel else 72158c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops); 72258c5818c01e375a84dc601140470fa68638004cfScott Michel } else 72358c5818c01e375a84dc601140470fa68638004cfScott Michel return SelectCode(Op); 724266bc8f7774b153401e54ed537db299159840981Scott Michel} 725266bc8f7774b153401e54ed537db299159840981Scott Michel 726266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a 727266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 728266bc8f7774b153401e54ed537db299159840981Scott Michel/// 729266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 730266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 731266bc8f7774b153401e54ed537db299159840981Scott Michel} 732