SPUISelDAGToDAG.cpp revision 053c1da8d956a794d158ac906b3927c923f97c4d
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" 20266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h" 21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h" 22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h" 23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h" 24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h" 25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h" 26266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h" 27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h" 28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h" 29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h" 30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h" 31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 32266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 33266bc8f7774b153401e54ed537db299159840981Scott Michel#include <iostream> 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 { 44266bc8f7774b153401e54ed537db299159840981Scott Michel return isS10Constant(CN->getValue()); 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 { 51266bc8f7774b153401e54ed537db299159840981Scott Michel return isS10Constant((int) CN->getValue()); 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 { 68504c369213efb263136bb048e79af3516511c040Scott Michel return isU10Constant((int) CN->getValue()); 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 { 75266bc8f7774b153401e54ed537db299159840981Scott Michel return isS10Constant((short) CN->getValue()); 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 { 90ec2a08ff061af36b46160e475362959f21663e76Scott Michel return isU10Constant((short) CN->getValue()); 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 { 113266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType vt = CN->getValueType(0); 114266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) CN->getValue(); 115266bc8f7774b153401e54ed537db299159840981Scott Michel if (vt >= MVT::i1 && vt <= MVT::i16) { 116266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 117266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (vt == MVT::i32) { 118266bc8f7774b153401e54ed537db299159840981Scott Michel int32_t i_val = (int32_t) CN->getValue(); 119266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 120266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 121266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 122266bc8f7774b153401e54ed537db299159840981Scott Michel int64_t i_val = (int64_t) CN->getValue(); 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 { 142266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType 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 154053c1da8d956a794d158ac906b3927c923f97c4dScott Michel isHighLow(const SDOperand &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 //===------------------------------------------------------------------===// 16486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel //! MVT::ValueType to "useful stuff" mapping structure: 165266bc8f7774b153401e54ed537db299159840981Scott Michel 166266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 167266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType VT; 168266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 169266bc8f7774b153401e54ed537db299159840981Scott Michel int prefslot_byte; /// Byte offset of the "preferred" slot 170053c1da8d956a794d158ac906b3927c923f97c4dScott Michel unsigned insmask_ins; /// Insert mask instruction for a-form 171266bc8f7774b153401e54ed537db299159840981Scott Michel }; 172266bc8f7774b153401e54ed537db299159840981Scott Michel 173266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 174053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::i1, 0, 3, 0 }, 175053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::i8, SPU::ORBIr8, 3, 0 }, 176053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::i16, SPU::ORHIr16, 2, 0 }, 177053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::i32, SPU::ORIr32, 0, 0 }, 178053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::i64, SPU::ORIr64, 0, 0 }, 179053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::f32, 0, 0, 0 }, 180053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::f64, 0, 0, 0 }, 18158c5818c01e375a84dc601140470fa68638004cfScott Michel // vector types... (sigh!) 182053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v16i8, 0, 0, SPU::CBD }, 183053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v8i16, 0, 0, SPU::CHD }, 184053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v4i32, 0, 0, SPU::CWD }, 185053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v2i64, 0, 0, 0 }, 186053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v4f32, 0, 0, SPU::CWD }, 187053c1da8d956a794d158ac906b3927c923f97c4dScott Michel { MVT::v2f64, 0, 0, 0 } 188266bc8f7774b153401e54ed537db299159840981Scott Michel }; 189266bc8f7774b153401e54ed537db299159840981Scott Michel 190266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 191266bc8f7774b153401e54ed537db299159840981Scott Michel 192266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *getValueTypeMapEntry(MVT::ValueType 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) { 197266bc8f7774b153401e54ed537db299159840981Scott Michel retval = valtype_map + i; 198266bc8f7774b153401e54ed537db299159840981Scott 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 " 206266bc8f7774b153401e54ed537db299159840981Scott Michel << MVT::getValueTypeString(VT) 207266bc8f7774b153401e54ed537db299159840981Scott Michel << "\n"; 208266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 209266bc8f7774b153401e54ed537db299159840981Scott Michel } 210266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 211266bc8f7774b153401e54ed537db299159840981Scott Michel 212266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 213266bc8f7774b153401e54ed537db299159840981Scott Michel } 214266bc8f7774b153401e54ed537db299159840981Scott Michel} 215266bc8f7774b153401e54ed537db299159840981Scott Michel 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: 228266bc8f7774b153401e54ed537db299159840981Scott Michel 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. 243266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand 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. 249266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand 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. 254266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand 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. 260266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Select(SDOperand Op); 261266bc8f7774b153401e54ed537db299159840981Scott Michel 262266bc8f7774b153401e54ed537db299159840981Scott Michel /// Return true if the address N is a RI7 format address [r+imm] 263266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, 264266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Base); 265266bc8f7774b153401e54ed537db299159840981Scott Michel 266266bc8f7774b153401e54ed537db299159840981Scott Michel //! Returns true if the address N is an A-form (local store) address 267266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 268266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 269266bc8f7774b153401e54ed537db299159840981Scott Michel 270266bc8f7774b153401e54ed537db299159840981Scott Michel //! D-form address predicate 271266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 272266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 273266bc8f7774b153401e54ed537db299159840981Scott Michel 274266bc8f7774b153401e54ed537db299159840981Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 275266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 276266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 277266bc8f7774b153401e54ed537db299159840981Scott Michel 278266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 279266bc8f7774b153401e54ed537db299159840981Scott Michel /// inline asm expressions. 280266bc8f7774b153401e54ed537db299159840981Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op, 281266bc8f7774b153401e54ed537db299159840981Scott Michel char ConstraintCode, 282266bc8f7774b153401e54ed537db299159840981Scott Michel std::vector<SDOperand> &OutOps, 283266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAG &DAG) { 284266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op0, Op1; 285266bc8f7774b153401e54ed537db299159840981Scott Michel switch (ConstraintCode) { 286266bc8f7774b153401e54ed537db299159840981Scott Michel default: return true; 287266bc8f7774b153401e54ed537db299159840981Scott Michel case 'm': // memory 288266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 289266bc8f7774b153401e54ed537db299159840981Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 290266bc8f7774b153401e54ed537db299159840981Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 291266bc8f7774b153401e54ed537db299159840981Scott Michel break; 292266bc8f7774b153401e54ed537db299159840981Scott Michel case 'o': // offsetable 293266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 294266bc8f7774b153401e54ed537db299159840981Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 295266bc8f7774b153401e54ed537db299159840981Scott Michel Op0 = Op; 296266bc8f7774b153401e54ed537db299159840981Scott Michel AddToISelQueue(Op0); // r+0. 297266bc8f7774b153401e54ed537db299159840981Scott Michel Op1 = getSmallIPtrImm(0); 298266bc8f7774b153401e54ed537db299159840981Scott Michel } 299266bc8f7774b153401e54ed537db299159840981Scott Michel break; 300266bc8f7774b153401e54ed537db299159840981Scott Michel case 'v': // not offsetable 301266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 302266bc8f7774b153401e54ed537db299159840981Scott Michel assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 303266bc8f7774b153401e54ed537db299159840981Scott Michel#else 304266bc8f7774b153401e54ed537db299159840981Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 305266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 306266bc8f7774b153401e54ed537db299159840981Scott Michel break; 307266bc8f7774b153401e54ed537db299159840981Scott Michel } 308266bc8f7774b153401e54ed537db299159840981Scott Michel 309266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op0); 310266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op1); 311266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 312266bc8f7774b153401e54ed537db299159840981Scott Michel } 313266bc8f7774b153401e54ed537db299159840981Scott Michel 314266bc8f7774b153401e54ed537db299159840981Scott Michel /// InstructionSelectBasicBlock - This callback is invoked by 315266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 316266bc8f7774b153401e54ed537db299159840981Scott Michel virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 317266bc8f7774b153401e54ed537db299159840981Scott Michel 318266bc8f7774b153401e54ed537db299159840981Scott Michel virtual const char *getPassName() const { 319266bc8f7774b153401e54ed537db299159840981Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 320266bc8f7774b153401e54ed537db299159840981Scott Michel } 321266bc8f7774b153401e54ed537db299159840981Scott Michel 322266bc8f7774b153401e54ed537db299159840981Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 323266bc8f7774b153401e54ed537db299159840981Scott Michel /// this target when scheduling the DAG. 324266bc8f7774b153401e54ed537db299159840981Scott Michel virtual HazardRecognizer *CreateTargetHazardRecognizer() { 325266bc8f7774b153401e54ed537db299159840981Scott Michel const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo(); 326266bc8f7774b153401e54ed537db299159840981Scott Michel assert(II && "No InstrInfo?"); 327266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUHazardRecognizer(*II); 328266bc8f7774b153401e54ed537db299159840981Scott Michel } 329266bc8f7774b153401e54ed537db299159840981Scott Michel 330266bc8f7774b153401e54ed537db299159840981Scott Michel // Include the pieces autogenerated from the target description. 331266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 332266bc8f7774b153401e54ed537db299159840981Scott Michel}; 333266bc8f7774b153401e54ed537db299159840981Scott Michel 334266bc8f7774b153401e54ed537db299159840981Scott Michel/// InstructionSelectBasicBlock - This callback is invoked by 335266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 336266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 337266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) 338266bc8f7774b153401e54ed537db299159840981Scott Michel{ 339266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 340266bc8f7774b153401e54ed537db299159840981Scott Michel 341266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 342266bc8f7774b153401e54ed537db299159840981Scott Michel DAG.setRoot(SelectRoot(DAG.getRoot())); 343266bc8f7774b153401e54ed537db299159840981Scott Michel DAG.RemoveDeadNodes(); 344266bc8f7774b153401e54ed537db299159840981Scott Michel 345266bc8f7774b153401e54ed537db299159840981Scott Michel // Emit machine code to BB. 346266bc8f7774b153401e54ed537db299159840981Scott Michel ScheduleAndEmitDAG(DAG); 347266bc8f7774b153401e54ed537db299159840981Scott Michel} 348266bc8f7774b153401e54ed537db299159840981Scott Michel 349266bc8f7774b153401e54ed537db299159840981Scott Michelbool 350266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, 351266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Base) { 352266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 353266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned VT = N.getValueType(); 354266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType PtrVT = SPUtli.getPointerTy(); 355266bc8f7774b153401e54ed537db299159840981Scott Michel ConstantSDNode *CN = 0; 356266bc8f7774b153401e54ed537db299159840981Scott Michel int Imm; 357266bc8f7774b153401e54ed537db299159840981Scott Michel 358266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc == ISD::ADD) { 359266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op0 = N.getOperand(0); 360266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op1 = N.getOperand(1); 361266bc8f7774b153401e54ed537db299159840981Scott Michel if (Op1.getOpcode() == ISD::Constant || 362266bc8f7774b153401e54ed537db299159840981Scott Michel Op1.getOpcode() == ISD::TargetConstant) { 363266bc8f7774b153401e54ed537db299159840981Scott Michel CN = cast<ConstantSDNode>(Op1); 364266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = int(CN->getValue()); 365266bc8f7774b153401e54ed537db299159840981Scott Michel if (Imm <= 0xff) { 366266bc8f7774b153401e54ed537db299159840981Scott Michel Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 367266bc8f7774b153401e54ed537db299159840981Scott Michel Base = Op0; 368266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 369266bc8f7774b153401e54ed537db299159840981Scott Michel } 370266bc8f7774b153401e54ed537db299159840981Scott Michel } 371266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::GlobalAddress 372266bc8f7774b153401e54ed537db299159840981Scott Michel || Opc == ISD::TargetGlobalAddress 373266bc8f7774b153401e54ed537db299159840981Scott Michel || Opc == ISD::Register) { 374266bc8f7774b153401e54ed537db299159840981Scott Michel // Plain old local store address: 375266bc8f7774b153401e54ed537db299159840981Scott Michel Disp = CurDAG->getTargetConstant(0, VT); 376266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N; 377266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 378053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 379053c1da8d956a794d158ac906b3927c923f97c4dScott Michel SDOperand Op1 = N.getOperand(1); 380053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::TargetConstant 381053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::Constant) { 382053c1da8d956a794d158ac906b3927c923f97c4dScott Michel CN = cast<ConstantSDNode>(N.getOperand(1)); 383053c1da8d956a794d158ac906b3927c923f97c4dScott Michel assert(CN != 0 && "SelectIndirectAddr/SPUISD::DForm2Addr expecting constant"); 384053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Imm = unsigned(CN->getValue()); 385053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Imm < 0xff) { 386053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT); 387053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = N.getOperand(0); 388053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 389053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 390266bc8f7774b153401e54ed537db299159840981Scott Michel } 391266bc8f7774b153401e54ed537db299159840981Scott Michel } 392266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 393266bc8f7774b153401e54ed537db299159840981Scott Michel} 394266bc8f7774b153401e54ed537db299159840981Scott Michel 395266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 396266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand 397266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 398266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 399266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 400266bc8f7774b153401e54ed537db299159840981Scott Michel */ 401266bc8f7774b153401e54ed537db299159840981Scott Michelbool 402266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 403266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 404266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 405266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType OffsVT = MVT::i16; 406053c1da8d956a794d158ac906b3927c923f97c4dScott Michel SDOperand Zero = CurDAG->getTargetConstant(0, OffsVT); 407266bc8f7774b153401e54ed537db299159840981Scott Michel 408266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 409266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 4109de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 4119de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 4129de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 4139de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel abort(); 4149de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 4159de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 416053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 4179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 418053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 419053c1da8d956a794d158ac906b3927c923f97c4dScott Michel cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as " 420053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << "A-form address.\n"; 421053c1da8d956a794d158ac906b3927c923f97c4dScott Michel abort(); 422053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 423266bc8f7774b153401e54ed537db299159840981Scott Michel 424053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case SPUISD::AFormAddr: 425053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 426053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 427053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 428053c1da8d956a794d158ac906b3927c923f97c4dScott Michel SDOperand Op0 = N.getOperand(0); 429053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 430053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 431053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 432053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 433053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 434053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 435053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 436053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 437053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 438053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalValue *GV = GSDN->getGlobal(); 439053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 440053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 441053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 442053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 443053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 444053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 445053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 446053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 447053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 448053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 449053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 450266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 451266bc8f7774b153401e54ed537db299159840981Scott Michel} 452266bc8f7774b153401e54ed537db299159840981Scott Michel 453266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 454266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 455266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 456266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 457266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 458266bc8f7774b153401e54ed537db299159840981Scott Michel 459266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 460266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 461266bc8f7774b153401e54ed537db299159840981Scott Michel 462266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 463266bc8f7774b153401e54ed537db299159840981Scott Michel to non-empty SDOperand instances. 464266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 465266bc8f7774b153401e54ed537db299159840981Scott Michelbool 466266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 467266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 468266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 469266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned PtrTy = SPUtli.getPointerTy(); 470266bc8f7774b153401e54ed537db299159840981Scott Michel 471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 473266bc8f7774b153401e54ed537db299159840981Scott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N); 474266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 475053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << FI->getIndex() << "\n"); 476266bc8f7774b153401e54ed537db299159840981Scott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 477266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 478266bc8f7774b153401e54ed537db299159840981Scott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 479266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 480266bc8f7774b153401e54ed537db299159840981Scott Michel } 481266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 482266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const SDOperand Op0 = N.getOperand(0); 484053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const SDOperand Op1 = N.getOperand(1); 485266bc8f7774b153401e54ed537db299159840981Scott Michel 486053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 487053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 488053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 489053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 490053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 491053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 492053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 4939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 494053c1da8d956a794d158ac906b3927c923f97c4dScott Michel int32_t offset = int32_t(CN->getSignExtended()); 495266bc8f7774b153401e54ed537db299159840981Scott Michel 496053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0); 4989de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 4999de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel << " frame index = " << FI->getIndex() << "\n"); 5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 5029de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 5039de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 5049de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5059de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 5069de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else if (offset > SPUFrameInfo::minFrameOffset() 5079de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel && offset < SPUFrameInfo::maxFrameOffset()) { 5089de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 510053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 511053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 512053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 513053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 514053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 515053c1da8d956a794d158ac906b3927c923f97c4dScott Michel int32_t offset = int32_t(CN->getSignExtended()); 516053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 517053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 518053c1da8d956a794d158ac906b3927c923f97c4dScott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op1); 519053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 520053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << " frame index = " << FI->getIndex() << "\n"); 521053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 522053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 523053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 524053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 5259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5269de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 527053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (offset > SPUFrameInfo::minFrameOffset() 528053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && offset < SPUFrameInfo::maxFrameOffset()) { 529053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 530053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 531053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 532266bc8f7774b153401e54ed537db299159840981Scott Michel } 533497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 534053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 535053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 536053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const SDOperand Op0 = N.getOperand(0); 537053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const SDOperand Op1 = N.getOperand(1); 538053c1da8d956a794d158ac906b3927c923f97c4dScott Michel SDOperand Zero = CurDAG->getTargetConstant(0, N.getValueType()); 539053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 540053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::Constant 541053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 542053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 543053c1da8d956a794d158ac906b3927c923f97c4dScott Michel int32_t offset = int32_t(CN->getSignExtended()); 544053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (offset > SPUFrameInfo::minFrameOffset() 545053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && offset < SPUFrameInfo::maxFrameOffset()) { 546053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); 547053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 548053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 549053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 550053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 551053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 552053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 553053c1da8d956a794d158ac906b3927c923f97c4dScott Michel int32_t offset = int32_t(CN->getSignExtended()); 554053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (offset > SPUFrameInfo::minFrameOffset() 555053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && offset < SPUFrameInfo::maxFrameOffset()) { 556053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); 557053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 558053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 559053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 560053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == SPUISD::Hi 561053c1da8d956a794d158ac906b3927c923f97c4dScott Michel && Op1.getOpcode() == SPUISD::Lo) { 562053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 5639de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 564053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 5659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 567053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 568053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 569053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 57058c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 571266bc8f7774b153401e54ed537db299159840981Scott Michel } 572266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 573266bc8f7774b153401e54ed537db299159840981Scott Michel} 574266bc8f7774b153401e54ed537db299159840981Scott Michel 575266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 576266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 577266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 578266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 579266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 580266bc8f7774b153401e54ed537db299159840981Scott Michel 581266bc8f7774b153401e54ed537db299159840981Scott Michel If the address \a N can be expressed as a [r + s10imm] address, returns false. 582266bc8f7774b153401e54ed537db299159840981Scott Michel Otherwise, creates two operands, Base and Index that will become the [r+r] 583266bc8f7774b153401e54ed537db299159840981Scott Michel address. 584266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 585266bc8f7774b153401e54ed537db299159840981Scott Michelbool 586266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 587266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 588266bc8f7774b153401e54ed537db299159840981Scott Michel if (SelectAFormAddr(Op, N, Base, Index) 589266bc8f7774b153401e54ed537db299159840981Scott Michel || SelectDFormAddr(Op, N, Base, Index)) 590266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 591266bc8f7774b153401e54ed537db299159840981Scott Michel 592053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // All else fails, punt and use an X-form address: 593053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = N.getOperand(0); 594053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N.getOperand(1); 595053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 59658c5818c01e375a84dc601140470fa68638004cfScott Michel} 59758c5818c01e375a84dc601140470fa68638004cfScott Michel 598266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 599266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 600266bc8f7774b153401e54ed537db299159840981Scott Michel */ 601266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 602266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::Select(SDOperand Op) { 603266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *N = Op.Val; 604266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 60558c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 60658c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 60758c5818c01e375a84dc601140470fa68638004cfScott Michel MVT::ValueType OpVT = Op.getValueType(); 60858c5818c01e375a84dc601140470fa68638004cfScott Michel SDOperand Ops[8]; 609266bc8f7774b153401e54ed537db299159840981Scott Michel 610266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) { 611266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 612266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::FrameIndex) { 613266bc8f7774b153401e54ed537db299159840981Scott Michel // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm. 614266bc8f7774b153401e54ed537db299159840981Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 6159de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel MVT::ValueType PtrVT = SPUtli.getPointerTy(); 6169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT); 6179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT); 618266bc8f7774b153401e54ed537db299159840981Scott Michel 6199999e685ea86e9cb8c8d59bfb2f3f4c20acc4de4Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n"); 62058c5818c01e375a84dc601140470fa68638004cfScott Michel NewOpc = SPU::AIr32; 62158c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[0] = TFI; 62258c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[1] = Zero; 62358c5818c01e375a84dc601140470fa68638004cfScott Michel n_ops = 2; 62458c5818c01e375a84dc601140470fa68638004cfScott Michel } else if (Opc == ISD::ZERO_EXTEND) { 62558c5818c01e375a84dc601140470fa68638004cfScott Michel // (zero_extend:i16 (and:i8 <arg>, <const>)) 62658c5818c01e375a84dc601140470fa68638004cfScott Michel const SDOperand &Op1 = N->getOperand(0); 62758c5818c01e375a84dc601140470fa68638004cfScott Michel 62858c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) { 62958c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::AND) { 63058c5818c01e375a84dc601140470fa68638004cfScott Michel // Fold this into a single ANDHI. This is often seen in expansions of i1 63158c5818c01e375a84dc601140470fa68638004cfScott Michel // to i8, then i8 to i16 in logical/branching operations. 63258c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 " 63358c5818c01e375a84dc601140470fa68638004cfScott Michel "<arg>, <const>))\n"); 63458c5818c01e375a84dc601140470fa68638004cfScott Michel NewOpc = SPU::ANDHI1To2; 63558c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[0] = Op1.getOperand(0); 63658c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[1] = Op1.getOperand(1); 63758c5818c01e375a84dc601140470fa68638004cfScott Michel n_ops = 2; 63858c5818c01e375a84dc601140470fa68638004cfScott Michel } 63958c5818c01e375a84dc601140470fa68638004cfScott Michel } 640053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::INSERT_MASK) { 641053c1da8d956a794d158ac906b3927c923f97c4dScott Michel SDOperand Op0 = Op.getOperand(0); 642053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == SPUISD::AFormAddr) { 643053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUvecinsmask (SPUaform <arg>, 0)) -> 644053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (CBD|CHD|CWD 0, arg) 645053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const valtype_map_s *vtm = getValueTypeMapEntry(OpVT); 646053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0.getOperand(1)); 647053c1da8d956a794d158ac906b3927c923f97c4dScott Michel assert(vtm->insmask_ins != 0 && "missing insert mask instruction"); 648053c1da8d956a794d158ac906b3927c923f97c4dScott Michel NewOpc = vtm->insmask_ins; 649053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[0] = CurDAG->getTargetConstant(CN->getValue(), Op0.getValueType()); 650053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[1] = Op0; 651053c1da8d956a794d158ac906b3927c923f97c4dScott Michel n_ops = 2; 652053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 653053c1da8d956a794d158ac906b3927c923f97c4dScott Michel AddToISelQueue(Op0); 654053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::FrameIndex) { 655053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUvecinsmask <fi>) -> 656053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (CBD|CHD|CWD 0, <fi>) 657053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const valtype_map_s *vtm = getValueTypeMapEntry(OpVT); 658053c1da8d956a794d158ac906b3927c923f97c4dScott Michel NewOpc = vtm->insmask_ins; 659053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[0] = CurDAG->getTargetConstant(0, Op0.getValueType()); 660053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[1] = Op0; 661053c1da8d956a794d158ac906b3927c923f97c4dScott Michel n_ops = 2; 662053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (isHighLow(Op0)) { 663053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUvecinsmask (SPUindirect (SPUhi <arg>, 0), (SPUlow <arg>, 0))) -> 664053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (CBD|CHD|CWD 0, arg) 665053c1da8d956a794d158ac906b3927c923f97c4dScott Michel const valtype_map_s *vtm = getValueTypeMapEntry(OpVT); 666053c1da8d956a794d158ac906b3927c923f97c4dScott Michel NewOpc = vtm->insmask_ins; 667053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[0] = CurDAG->getTargetConstant(0, Op0.getValueType()); 668053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Ops[1] = Op0; 669053c1da8d956a794d158ac906b3927c923f97c4dScott Michel n_ops = 2; 670053c1da8d956a794d158ac906b3927c923f97c4dScott Michel AddToISelQueue(Op0); 671053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 672266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 673266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 674266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned VT = N->getValueType(0); 675266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Arg = N->getOperand(0); 676266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Chain = N->getOperand(1); 677266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 678266bc8f7774b153401e54ed537db299159840981Scott Michel 679266bc8f7774b153401e54ed537db299159840981Scott Michel AddToISelQueue(Arg); 68086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel if (!MVT::isFloatingPoint(VT)) { 68186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel SDOperand Zero = CurDAG->getTargetConstant(0, VT); 68286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 68386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 68486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel if (vtm->ldresult_ins == 0) { 68586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel cerr << "LDRESULT for unsupported type: " 68686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel << MVT::getValueTypeString(VT) 68786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel << "\n"; 68886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel abort(); 68986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else 69086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel Opc = vtm->ldresult_ins; 69186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 69286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Zero); 69358c5818c01e375a84dc601140470fa68638004cfScott Michel Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain); 69486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 69558c5818c01e375a84dc601140470fa68638004cfScott Michel Opc = (VT == MVT::f32 ? SPU::ORf32 : SPU::ORf64); 69658c5818c01e375a84dc601140470fa68638004cfScott Michel Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain); 69786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 69886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 699266bc8f7774b153401e54ed537db299159840981Scott Michel Chain = SDOperand(Result, 1); 70086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Chain); 70186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 702266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 703053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 70458c5818c01e375a84dc601140470fa68638004cfScott Michel SDOperand Op0 = Op.getOperand(0); 70558c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op0.getOpcode() == SPUISD::LDRESULT 70658c5818c01e375a84dc601140470fa68638004cfScott Michel || Op0.getOpcode() == SPUISD::AFormAddr) { 707053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (IndirectAddr (LDRESULT|AFormAddr, imm)) 70858c5818c01e375a84dc601140470fa68638004cfScott Michel SDOperand Op1 = Op.getOperand(1); 70958c5818c01e375a84dc601140470fa68638004cfScott Michel MVT::ValueType VT = Op.getValueType(); 71058c5818c01e375a84dc601140470fa68638004cfScott Michel 711053c1da8d956a794d158ac906b3927c923f97c4dScott Michel DEBUG(cerr << "CellSPU: IndirectAddr(" 712053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << (Op0.getOpcode() == SPUISD::LDRESULT 713053c1da8d956a794d158ac906b3927c923f97c4dScott Michel ? "LDRESULT" 714053c1da8d956a794d158ac906b3927c923f97c4dScott Michel : "AFormAddr") 715053c1da8d956a794d158ac906b3927c923f97c4dScott Michel << ", imm):\nOp0 = "); 71658c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(Op.getOperand(0).Val->dump(CurDAG)); 71758c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\nOp1 = "); 71858c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(Op.getOperand(1).Val->dump(CurDAG)); 71958c5818c01e375a84dc601140470fa68638004cfScott Michel DEBUG(cerr << "\n"); 72058c5818c01e375a84dc601140470fa68638004cfScott Michel 72158c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 72258c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 72358c5818c01e375a84dc601140470fa68638004cfScott Michel Op1 = CurDAG->getTargetConstant(CN->getValue(), VT); 72458c5818c01e375a84dc601140470fa68638004cfScott Michel } 72558c5818c01e375a84dc601140470fa68638004cfScott Michel AddToISelQueue(Op0); 72658c5818c01e375a84dc601140470fa68638004cfScott Michel AddToISelQueue(Op1); 72758c5818c01e375a84dc601140470fa68638004cfScott Michel NewOpc = SPU::AIr32; 72858c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[0] = Op0; 72958c5818c01e375a84dc601140470fa68638004cfScott Michel Ops[1] = Op1; 73058c5818c01e375a84dc601140470fa68638004cfScott Michel n_ops = 2; 73158c5818c01e375a84dc601140470fa68638004cfScott Michel } 732266bc8f7774b153401e54ed537db299159840981Scott Michel } 733266bc8f7774b153401e54ed537db299159840981Scott Michel 73458c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 73558c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 73658c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 73758c5818c01e375a84dc601140470fa68638004cfScott Michel else 73858c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops); 73958c5818c01e375a84dc601140470fa68638004cfScott Michel } else 74058c5818c01e375a84dc601140470fa68638004cfScott Michel return SelectCode(Op); 741266bc8f7774b153401e54ed537db299159840981Scott Michel} 742266bc8f7774b153401e54ed537db299159840981Scott Michel 743266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a 744266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 745266bc8f7774b153401e54ed537db299159840981Scott Michel/// 746266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 747266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 748266bc8f7774b153401e54ed537db299159840981Scott Michel} 749