SPUISelDAGToDAG.cpp revision 497e888daf9ba6489928e1153804ed12a7fe44c5
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 153266bc8f7774b153401e54ed537db299159840981Scott Michel //===------------------------------------------------------------------===// 15486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel //! MVT::ValueType to "useful stuff" mapping structure: 155266bc8f7774b153401e54ed537db299159840981Scott Michel 156266bc8f7774b153401e54ed537db299159840981Scott Michel struct valtype_map_s { 157266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType VT; 158266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 159266bc8f7774b153401e54ed537db299159840981Scott Michel int prefslot_byte; /// Byte offset of the "preferred" slot 160266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned brcc_eq_ins; /// br_cc equal instruction 161266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned brcc_neq_ins; /// br_cc not equal instruction 162266bc8f7774b153401e54ed537db299159840981Scott Michel }; 163266bc8f7774b153401e54ed537db299159840981Scott Michel 164266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s valtype_map[] = { 16586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::i1, 0, 3, 0, 0 }, 16686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::i8, 0, 3, 0, 0 }, 16786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::i16, SPU::ORHIr16, 2, SPU::BRHZ, SPU::BRHNZ }, 16886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::i32, SPU::ORIr32, 0, SPU::BRZ, SPU::BRNZ }, 16986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::i64, SPU::ORIr64, 0, 0, 0 }, 17086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::f32, 0, 0, 0, 0 }, 17186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel { MVT::f64, 0, 0, 0, 0 } 172266bc8f7774b153401e54ed537db299159840981Scott Michel }; 173266bc8f7774b153401e54ed537db299159840981Scott Michel 174266bc8f7774b153401e54ed537db299159840981Scott Michel const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 175266bc8f7774b153401e54ed537db299159840981Scott Michel 176266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT) 177266bc8f7774b153401e54ed537db299159840981Scott Michel { 178266bc8f7774b153401e54ed537db299159840981Scott Michel const valtype_map_s *retval = 0; 179266bc8f7774b153401e54ed537db299159840981Scott Michel for (size_t i = 0; i < n_valtype_map; ++i) { 180266bc8f7774b153401e54ed537db299159840981Scott Michel if (valtype_map[i].VT == VT) { 181266bc8f7774b153401e54ed537db299159840981Scott Michel retval = valtype_map + i; 182266bc8f7774b153401e54ed537db299159840981Scott Michel break; 183266bc8f7774b153401e54ed537db299159840981Scott Michel } 184266bc8f7774b153401e54ed537db299159840981Scott Michel } 185266bc8f7774b153401e54ed537db299159840981Scott Michel 186266bc8f7774b153401e54ed537db299159840981Scott Michel 187266bc8f7774b153401e54ed537db299159840981Scott Michel#ifndef NDEBUG 188266bc8f7774b153401e54ed537db299159840981Scott Michel if (retval == 0) { 189266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 190266bc8f7774b153401e54ed537db299159840981Scott Michel << MVT::getValueTypeString(VT) 191266bc8f7774b153401e54ed537db299159840981Scott Michel << "\n"; 192266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 193266bc8f7774b153401e54ed537db299159840981Scott Michel } 194266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 195266bc8f7774b153401e54ed537db299159840981Scott Michel 196266bc8f7774b153401e54ed537db299159840981Scott Michel return retval; 197266bc8f7774b153401e54ed537db299159840981Scott Michel } 198266bc8f7774b153401e54ed537db299159840981Scott Michel} 199266bc8f7774b153401e54ed537db299159840981Scott Michel 200266bc8f7774b153401e54ed537db299159840981Scott Michel//===--------------------------------------------------------------------===// 201266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 202266bc8f7774b153401e54ed537db299159840981Scott Michel/// instructions for SelectionDAG operations. 203266bc8f7774b153401e54ed537db299159840981Scott Michel/// 204266bc8f7774b153401e54ed537db299159840981Scott Michelclass SPUDAGToDAGISel : 205266bc8f7774b153401e54ed537db299159840981Scott Michel public SelectionDAGISel 206266bc8f7774b153401e54ed537db299159840981Scott Michel{ 207266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetMachine &TM; 208266bc8f7774b153401e54ed537db299159840981Scott Michel SPUTargetLowering &SPUtli; 209266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned GlobalBaseReg; 210266bc8f7774b153401e54ed537db299159840981Scott Michel 211266bc8f7774b153401e54ed537db299159840981Scott Michelpublic: 212266bc8f7774b153401e54ed537db299159840981Scott Michel SPUDAGToDAGISel(SPUTargetMachine &tm) : 213266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel(*tm.getTargetLowering()), 214266bc8f7774b153401e54ed537db299159840981Scott Michel TM(tm), 215266bc8f7774b153401e54ed537db299159840981Scott Michel SPUtli(*tm.getTargetLowering()) 216266bc8f7774b153401e54ed537db299159840981Scott Michel {} 217266bc8f7774b153401e54ed537db299159840981Scott Michel 218266bc8f7774b153401e54ed537db299159840981Scott Michel virtual bool runOnFunction(Function &Fn) { 219266bc8f7774b153401e54ed537db299159840981Scott Michel // Make sure we re-emit a set of the global base reg if necessary 220266bc8f7774b153401e54ed537db299159840981Scott Michel GlobalBaseReg = 0; 221266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAGISel::runOnFunction(Fn); 222266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 223266bc8f7774b153401e54ed537db299159840981Scott Michel } 224266bc8f7774b153401e54ed537db299159840981Scott Michel 225266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 226266bc8f7774b153401e54ed537db299159840981Scott Michel /// i32. 227266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand getI32Imm(uint32_t Imm) { 228266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i32); 229266bc8f7774b153401e54ed537db299159840981Scott Michel } 230266bc8f7774b153401e54ed537db299159840981Scott Michel 231266bc8f7774b153401e54ed537db299159840981Scott Michel /// getI64Imm - Return a target constant with the specified value, of type 232266bc8f7774b153401e54ed537db299159840981Scott Michel /// i64. 233266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand getI64Imm(uint64_t Imm) { 234266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, MVT::i64); 235266bc8f7774b153401e54ed537db299159840981Scott Michel } 236266bc8f7774b153401e54ed537db299159840981Scott Michel 237266bc8f7774b153401e54ed537db299159840981Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 238266bc8f7774b153401e54ed537db299159840981Scott Michel inline SDOperand getSmallIPtrImm(unsigned Imm) { 239266bc8f7774b153401e54ed537db299159840981Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 240266bc8f7774b153401e54ed537db299159840981Scott Michel } 241266bc8f7774b153401e54ed537db299159840981Scott Michel 242266bc8f7774b153401e54ed537db299159840981Scott Michel /// Select - Convert the specified operand from a target-independent to a 243266bc8f7774b153401e54ed537db299159840981Scott Michel /// target-specific node if it hasn't already been changed. 244266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Select(SDOperand Op); 245266bc8f7774b153401e54ed537db299159840981Scott Michel 246266bc8f7774b153401e54ed537db299159840981Scott Michel /// Return true if the address N is a RI7 format address [r+imm] 247266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, 248266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Base); 249266bc8f7774b153401e54ed537db299159840981Scott Michel 250266bc8f7774b153401e54ed537db299159840981Scott Michel //! Returns true if the address N is an A-form (local store) address 251266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 252266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 253266bc8f7774b153401e54ed537db299159840981Scott Michel 254266bc8f7774b153401e54ed537db299159840981Scott Michel //! D-form address predicate 255266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 256266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 257266bc8f7774b153401e54ed537db299159840981Scott Michel 258266bc8f7774b153401e54ed537db299159840981Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 259266bc8f7774b153401e54ed537db299159840981Scott Michel bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 260266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index); 261266bc8f7774b153401e54ed537db299159840981Scott Michel 262266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 263266bc8f7774b153401e54ed537db299159840981Scott Michel /// inline asm expressions. 264266bc8f7774b153401e54ed537db299159840981Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op, 265266bc8f7774b153401e54ed537db299159840981Scott Michel char ConstraintCode, 266266bc8f7774b153401e54ed537db299159840981Scott Michel std::vector<SDOperand> &OutOps, 267266bc8f7774b153401e54ed537db299159840981Scott Michel SelectionDAG &DAG) { 268266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op0, Op1; 269266bc8f7774b153401e54ed537db299159840981Scott Michel switch (ConstraintCode) { 270266bc8f7774b153401e54ed537db299159840981Scott Michel default: return true; 271266bc8f7774b153401e54ed537db299159840981Scott Michel case 'm': // memory 272266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 273266bc8f7774b153401e54ed537db299159840981Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) 274266bc8f7774b153401e54ed537db299159840981Scott Michel SelectXFormAddr(Op, Op, Op0, Op1); 275266bc8f7774b153401e54ed537db299159840981Scott Michel break; 276266bc8f7774b153401e54ed537db299159840981Scott Michel case 'o': // offsetable 277266bc8f7774b153401e54ed537db299159840981Scott Michel if (!SelectDFormAddr(Op, Op, Op0, Op1) 278266bc8f7774b153401e54ed537db299159840981Scott Michel && !SelectAFormAddr(Op, Op, Op0, Op1)) { 279266bc8f7774b153401e54ed537db299159840981Scott Michel Op0 = Op; 280266bc8f7774b153401e54ed537db299159840981Scott Michel AddToISelQueue(Op0); // r+0. 281266bc8f7774b153401e54ed537db299159840981Scott Michel Op1 = getSmallIPtrImm(0); 282266bc8f7774b153401e54ed537db299159840981Scott Michel } 283266bc8f7774b153401e54ed537db299159840981Scott Michel break; 284266bc8f7774b153401e54ed537db299159840981Scott Michel case 'v': // not offsetable 285266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 286266bc8f7774b153401e54ed537db299159840981Scott Michel assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 287266bc8f7774b153401e54ed537db299159840981Scott Michel#else 288266bc8f7774b153401e54ed537db299159840981Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 289266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 290266bc8f7774b153401e54ed537db299159840981Scott Michel break; 291266bc8f7774b153401e54ed537db299159840981Scott Michel } 292266bc8f7774b153401e54ed537db299159840981Scott Michel 293266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op0); 294266bc8f7774b153401e54ed537db299159840981Scott Michel OutOps.push_back(Op1); 295266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 296266bc8f7774b153401e54ed537db299159840981Scott Michel } 297266bc8f7774b153401e54ed537db299159840981Scott Michel 298266bc8f7774b153401e54ed537db299159840981Scott Michel /// InstructionSelectBasicBlock - This callback is invoked by 299266bc8f7774b153401e54ed537db299159840981Scott Michel /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 300266bc8f7774b153401e54ed537db299159840981Scott Michel virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 301266bc8f7774b153401e54ed537db299159840981Scott Michel 302266bc8f7774b153401e54ed537db299159840981Scott Michel virtual const char *getPassName() const { 303266bc8f7774b153401e54ed537db299159840981Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 304266bc8f7774b153401e54ed537db299159840981Scott Michel } 305266bc8f7774b153401e54ed537db299159840981Scott Michel 306266bc8f7774b153401e54ed537db299159840981Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 307266bc8f7774b153401e54ed537db299159840981Scott Michel /// this target when scheduling the DAG. 308266bc8f7774b153401e54ed537db299159840981Scott Michel virtual HazardRecognizer *CreateTargetHazardRecognizer() { 309266bc8f7774b153401e54ed537db299159840981Scott Michel const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo(); 310266bc8f7774b153401e54ed537db299159840981Scott Michel assert(II && "No InstrInfo?"); 311266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUHazardRecognizer(*II); 312266bc8f7774b153401e54ed537db299159840981Scott Michel } 313266bc8f7774b153401e54ed537db299159840981Scott Michel 314266bc8f7774b153401e54ed537db299159840981Scott Michel // Include the pieces autogenerated from the target description. 315266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 316266bc8f7774b153401e54ed537db299159840981Scott Michel}; 317266bc8f7774b153401e54ed537db299159840981Scott Michel 318266bc8f7774b153401e54ed537db299159840981Scott Michel/// InstructionSelectBasicBlock - This callback is invoked by 319266bc8f7774b153401e54ed537db299159840981Scott Michel/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 320266bc8f7774b153401e54ed537db299159840981Scott Michelvoid 321266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) 322266bc8f7774b153401e54ed537db299159840981Scott Michel{ 323266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(BB->dump()); 324266bc8f7774b153401e54ed537db299159840981Scott Michel 325266bc8f7774b153401e54ed537db299159840981Scott Michel // Select target instructions for the DAG. 326266bc8f7774b153401e54ed537db299159840981Scott Michel DAG.setRoot(SelectRoot(DAG.getRoot())); 327266bc8f7774b153401e54ed537db299159840981Scott Michel DAG.RemoveDeadNodes(); 328266bc8f7774b153401e54ed537db299159840981Scott Michel 329266bc8f7774b153401e54ed537db299159840981Scott Michel // Emit machine code to BB. 330266bc8f7774b153401e54ed537db299159840981Scott Michel ScheduleAndEmitDAG(DAG); 331266bc8f7774b153401e54ed537db299159840981Scott Michel} 332266bc8f7774b153401e54ed537db299159840981Scott Michel 333266bc8f7774b153401e54ed537db299159840981Scott Michelbool 334266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp, 335266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Base) { 336266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 337266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned VT = N.getValueType(); 338266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType PtrVT = SPUtli.getPointerTy(); 339266bc8f7774b153401e54ed537db299159840981Scott Michel ConstantSDNode *CN = 0; 340266bc8f7774b153401e54ed537db299159840981Scott Michel int Imm; 341266bc8f7774b153401e54ed537db299159840981Scott Michel 342266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc == ISD::ADD) { 343266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op0 = N.getOperand(0); 344266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Op1 = N.getOperand(1); 345266bc8f7774b153401e54ed537db299159840981Scott Michel if (Op1.getOpcode() == ISD::Constant || 346266bc8f7774b153401e54ed537db299159840981Scott Michel Op1.getOpcode() == ISD::TargetConstant) { 347266bc8f7774b153401e54ed537db299159840981Scott Michel CN = cast<ConstantSDNode>(Op1); 348266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = int(CN->getValue()); 349266bc8f7774b153401e54ed537db299159840981Scott Michel if (Imm <= 0xff) { 350266bc8f7774b153401e54ed537db299159840981Scott Michel Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 351266bc8f7774b153401e54ed537db299159840981Scott Michel Base = Op0; 352266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 353266bc8f7774b153401e54ed537db299159840981Scott Michel } 354266bc8f7774b153401e54ed537db299159840981Scott Michel } 355266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::GlobalAddress 356266bc8f7774b153401e54ed537db299159840981Scott Michel || Opc == ISD::TargetGlobalAddress 357266bc8f7774b153401e54ed537db299159840981Scott Michel || Opc == ISD::Register) { 358266bc8f7774b153401e54ed537db299159840981Scott Michel // Plain old local store address: 359266bc8f7774b153401e54ed537db299159840981Scott Michel Disp = CurDAG->getTargetConstant(0, VT); 360266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N; 361266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 362266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::DFormAddr) { 363266bc8f7774b153401e54ed537db299159840981Scott Michel // D-Form address: This is pretty straightforward, naturally... 364266bc8f7774b153401e54ed537db299159840981Scott Michel CN = cast<ConstantSDNode>(N.getOperand(1)); 365266bc8f7774b153401e54ed537db299159840981Scott Michel assert(CN != 0 && "SelectDFormAddr/SPUISD::DForm2Addr expecting constant"); 366266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = unsigned(CN->getValue()); 367266bc8f7774b153401e54ed537db299159840981Scott Michel if (Imm < 0xff) { 368266bc8f7774b153401e54ed537db299159840981Scott Michel Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT); 369266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N.getOperand(0); 370266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 371266bc8f7774b153401e54ed537db299159840981Scott Michel } 372266bc8f7774b153401e54ed537db299159840981Scott Michel } 373266bc8f7774b153401e54ed537db299159840981Scott Michel 374266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 375266bc8f7774b153401e54ed537db299159840981Scott Michel} 376266bc8f7774b153401e54ed537db299159840981Scott Michel 377266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 378266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instructio operand 379266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 380266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 381266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 382266bc8f7774b153401e54ed537db299159840981Scott Michel */ 383266bc8f7774b153401e54ed537db299159840981Scott Michelbool 384266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 385266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 386266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 387266bc8f7774b153401e54ed537db299159840981Scott Michel MVT::ValueType OffsVT = MVT::i16; 3889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel MVT::ValueType PtrVT = SPUtli.getPointerTy(); 389266bc8f7774b153401e54ed537db299159840981Scott Michel 390266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 391266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 3929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 3939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 3949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 3959de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel abort(); 3969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 3979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 398266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::TargetConstant: { 399266bc8f7774b153401e54ed537db299159840981Scott Michel // Loading from a constant address. 400266bc8f7774b153401e54ed537db299159840981Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); 401266bc8f7774b153401e54ed537db299159840981Scott Michel int Imm = (int)CN->getValue(); 402266bc8f7774b153401e54ed537db299159840981Scott Michel if (Imm < 0x3ffff && (Imm & 0x3) == 0) { 403266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(Imm, PtrVT); 404266bc8f7774b153401e54ed537db299159840981Scott Michel // Note that this operand will be ignored by the assembly printer... 405266bc8f7774b153401e54ed537db299159840981Scott Michel Index = CurDAG->getTargetConstant(0, OffsVT); 406266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 407266bc8f7774b153401e54ed537db299159840981Scott Michel } 408266bc8f7774b153401e54ed537db299159840981Scott Michel } 4099de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 4109de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetConstantPool: 4119de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case SPUISD::AFormAddr: { 4129de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // The address is in Base. N is a dummy that will be ignored by 413266bc8f7774b153401e54ed537db299159840981Scott Michel // the assembly printer. 414266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N; 415266bc8f7774b153401e54ed537db299159840981Scott Michel Index = CurDAG->getTargetConstant(0, OffsVT); 416266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 417266bc8f7774b153401e54ed537db299159840981Scott Michel } 418266bc8f7774b153401e54ed537db299159840981Scott Michel } 419266bc8f7774b153401e54ed537db299159840981Scott Michel 420266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 421266bc8f7774b153401e54ed537db299159840981Scott Michel} 422266bc8f7774b153401e54ed537db299159840981Scott Michel 423266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 424266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 425266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 426266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 427266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 428266bc8f7774b153401e54ed537db299159840981Scott Michel 429266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 430266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 431266bc8f7774b153401e54ed537db299159840981Scott Michel 432266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 433266bc8f7774b153401e54ed537db299159840981Scott Michel to non-empty SDOperand instances. 434266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 435266bc8f7774b153401e54ed537db299159840981Scott Michelbool 436266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 437266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 438266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 439266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned PtrTy = SPUtli.getPointerTy(); 440266bc8f7774b153401e54ed537db299159840981Scott Michel 441266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc == ISD::Register) { 442266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N; 443266bc8f7774b153401e54ed537db299159840981Scott Michel Index = CurDAG->getTargetConstant(0, PtrTy); 444266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 445266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::FrameIndex) { 446266bc8f7774b153401e54ed537db299159840981Scott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N); 447266bc8f7774b153401e54ed537db299159840981Scott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel << FI->getIndex() << "\n"); 449266bc8f7774b153401e54ed537db299159840981Scott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 450266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 451266bc8f7774b153401e54ed537db299159840981Scott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 452266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 453266bc8f7774b153401e54ed537db299159840981Scott Michel } 454266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 455266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 456266bc8f7774b153401e54ed537db299159840981Scott Michel const SDOperand Op0 = N.getOperand(0); // Frame index/base 457266bc8f7774b153401e54ed537db299159840981Scott Michel const SDOperand Op1 = N.getOperand(1); // Offset within base 458266bc8f7774b153401e54ed537db299159840981Scott Michel 459497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel if ((Op1.getOpcode() == ISD::Constant 460497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel || Op1.getOpcode() == ISD::TargetConstant) 461497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel && Op0.getOpcode() != SPUISD::XFormAddr) { 4629de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 4639de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel assert(CN != 0 && "SelectDFormAddr: Expected a constant"); 464266bc8f7774b153401e54ed537db299159840981Scott Michel 4659de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel int32_t offset = (int32_t) CN->getSignExtended(); 4669de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel unsigned Opc0 = Op0.getOpcode(); 467266bc8f7774b153401e54ed537db299159840981Scott Michel 4689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if ((offset & 0xf) != 0) { 4699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // Unaligned offset: punt and let X-form address handle it. 4709de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // NOTE: This really doesn't have to be strictly 16-byte aligned, 4719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // since the load/store quadword instructions will implicitly 4729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // zero the lower 4 bits of the resulting address. 4739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return false; 474266bc8f7774b153401e54ed537db299159840981Scott Michel } 4759de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 4769de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (Opc0 == ISD::FrameIndex) { 4779de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0); 4789de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 4799de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel << " frame index = " << FI->getIndex() << "\n"); 4809de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 4819de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 4829de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 4839de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 4849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4859de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4869de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else if (offset > SPUFrameInfo::minFrameOffset() 4879de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel && offset < SPUFrameInfo::maxFrameOffset()) { 4889de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 4899de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (Opc0 == ISD::GlobalAddress) { 4909de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // Convert global address to target global address 4919de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0); 4929de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy); 4939de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4949de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else { 4959de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // Otherwise, just take operand 0 4969de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = Op0; 4979de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4989de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 499266bc8f7774b153401e54ed537db299159840981Scott Michel } 5009de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else 5019de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return false; 502266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::DFormAddr) { 503497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel // D-Form address: This is pretty straightforward, 504497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel // naturally... but make sure that this isn't a D-form address 505497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel // with a X-form address embedded within: 506497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel const SDOperand Op0 = N.getOperand(0); // Frame index/base 507497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel const SDOperand Op1 = N.getOperand(1); // Offset within base 508497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel 509497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel if (Op0.getOpcode() != SPUISD::XFormAddr) { 510497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 511497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); 512497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); 513497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel Index = Op0; 514497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel return true; 515497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 5169de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else if (Opc == ISD::FrameIndex) { 5179de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel // Stack frame index must be less than 512 (divided by 16): 5189de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N); 5199de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 5209de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel << FI->getIndex() << "\n"); 5219de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) { 5229de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 5239de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy); 5249de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 5259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 526266bc8f7774b153401e54ed537db299159840981Scott Michel } 527266bc8f7774b153401e54ed537db299159840981Scott Michel 528266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 529266bc8f7774b153401e54ed537db299159840981Scott Michel} 530266bc8f7774b153401e54ed537db299159840981Scott Michel 531266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 532266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 533266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 534266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 535266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 536266bc8f7774b153401e54ed537db299159840981Scott Michel 537266bc8f7774b153401e54ed537db299159840981Scott Michel If the address \a N can be expressed as a [r + s10imm] address, returns false. 538266bc8f7774b153401e54ed537db299159840981Scott Michel Otherwise, creates two operands, Base and Index that will become the [r+r] 539266bc8f7774b153401e54ed537db299159840981Scott Michel address. 540266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 541266bc8f7774b153401e54ed537db299159840981Scott Michelbool 542266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, 543266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand &Index) { 544266bc8f7774b153401e54ed537db299159840981Scott Michel if (SelectAFormAddr(Op, N, Base, Index) 545266bc8f7774b153401e54ed537db299159840981Scott Michel || SelectDFormAddr(Op, N, Base, Index)) 546266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 547266bc8f7774b153401e54ed537db299159840981Scott Michel 548266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 549266bc8f7774b153401e54ed537db299159840981Scott Michel 550266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc == ISD::ADD) { 551266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand N1 = N.getOperand(0); 552266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand N2 = N.getOperand(1); 553266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned N1Opc = N1.getOpcode(); 554266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned N2Opc = N2.getOpcode(); 555266bc8f7774b153401e54ed537db299159840981Scott Michel 556266bc8f7774b153401e54ed537db299159840981Scott Michel if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo) 5579de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi) 5589de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel || (N1Opc == SPUISD::XFormAddr)) { 559266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N.getOperand(0); 560266bc8f7774b153401e54ed537db299159840981Scott Michel Index = N.getOperand(1); 561266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 562266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 563266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SelectXFormAddr: Unhandled ADD operands:\n"; 564266bc8f7774b153401e54ed537db299159840981Scott Michel N1.Val->dump(); 565266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "\n"; 566266bc8f7774b153401e54ed537db299159840981Scott Michel N2.Val->dump(); 567266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "\n"; 568266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 569266bc8f7774b153401e54ed537db299159840981Scott Michel /*UNREACHED*/ 570266bc8f7774b153401e54ed537db299159840981Scott Michel } 5719de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } else if (Opc == SPUISD::XFormAddr) { 5729de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = N; 5739de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Index = N.getOperand(1); 5749de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 575497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } else if (Opc == SPUISD::DFormAddr) { 576497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel // Must be a D-form address with an X-form address embedded 577497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel // within: 578497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel Base = N.getOperand(0); 579497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel Index = N.getOperand(1); 580497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel return true; 581266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (N.getNumOperands() == 2) { 582266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand N1 = N.getOperand(0); 583266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand N2 = N.getOperand(1); 584266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned N1Opc = N1.getOpcode(); 585266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned N2Opc = N2.getOpcode(); 586266bc8f7774b153401e54ed537db299159840981Scott Michel 587266bc8f7774b153401e54ed537db299159840981Scott Michel if ((N1Opc == ISD::CopyToReg || N1Opc == ISD::Register) 588266bc8f7774b153401e54ed537db299159840981Scott Michel && (N2Opc == ISD::CopyToReg || N2Opc == ISD::Register)) { 589266bc8f7774b153401e54ed537db299159840981Scott Michel Base = N.getOperand(0); 590266bc8f7774b153401e54ed537db299159840981Scott Michel Index = N.getOperand(1); 591266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 592266bc8f7774b153401e54ed537db299159840981Scott Michel /*UNREACHED*/ 593266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 594266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SelectXFormAddr: 2-operand unhandled operand:\n"; 595497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel N.Val->dump(CurDAG); 596266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "\n"; 597266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 598266bc8f7774b153401e54ed537db299159840981Scott Michel /*UNREACHED*/ 599266bc8f7774b153401e54ed537db299159840981Scott Michel } 600266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 601266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "SelectXFormAddr: Unhandled operand type:\n"; 602497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel N.Val->dump(CurDAG); 603266bc8f7774b153401e54ed537db299159840981Scott Michel cerr << "\n"; 604266bc8f7774b153401e54ed537db299159840981Scott Michel abort(); 605266bc8f7774b153401e54ed537db299159840981Scott Michel /*UNREACHED*/ 606266bc8f7774b153401e54ed537db299159840981Scott Michel } 607266bc8f7774b153401e54ed537db299159840981Scott Michel 608266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 609266bc8f7774b153401e54ed537db299159840981Scott Michel} 610266bc8f7774b153401e54ed537db299159840981Scott Michel 611266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 612266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 613266bc8f7774b153401e54ed537db299159840981Scott Michel */ 614266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 615266bc8f7774b153401e54ed537db299159840981Scott MichelSPUDAGToDAGISel::Select(SDOperand Op) { 616266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *N = Op.Val; 617266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 618266bc8f7774b153401e54ed537db299159840981Scott Michel 619266bc8f7774b153401e54ed537db299159840981Scott Michel if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) { 620266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 621266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::FrameIndex) { 622266bc8f7774b153401e54ed537db299159840981Scott Michel // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm. 623266bc8f7774b153401e54ed537db299159840981Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 6249de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel MVT::ValueType PtrVT = SPUtli.getPointerTy(); 6259de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT); 6269de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT); 627266bc8f7774b153401e54ed537db299159840981Scott Michel 6289999e685ea86e9cb8c8d59bfb2f3f4c20acc4de4Scott Michel DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n"); 6299de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel if (N->hasOneUse()) 6309de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI, Zero); 6319de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel CurDAG->getTargetNode(SPU::AIr32, Op.getValueType(), TFI, Zero); 632266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 633266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 634266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned VT = N->getValueType(0); 635266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Arg = N->getOperand(0); 636266bc8f7774b153401e54ed537db299159840981Scott Michel SDOperand Chain = N->getOperand(1); 637266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 638266bc8f7774b153401e54ed537db299159840981Scott Michel 639266bc8f7774b153401e54ed537db299159840981Scott Michel AddToISelQueue(Arg); 64086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel if (!MVT::isFloatingPoint(VT)) { 64186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel SDOperand Zero = CurDAG->getTargetConstant(0, VT); 64286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel const valtype_map_s *vtm = getValueTypeMapEntry(VT); 64386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 64486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel if (vtm->ldresult_ins == 0) { 64586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel cerr << "LDRESULT for unsupported type: " 64686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel << MVT::getValueTypeString(VT) 64786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel << "\n"; 64886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel abort(); 64986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else 65086c041f50e17f7fcd18193ff49e58379924d6472Scott Michel Opc = vtm->ldresult_ins; 65186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 65286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Zero); 65386c041f50e17f7fcd18193ff49e58379924d6472Scott Michel Result = CurDAG->SelectNodeTo(N, Opc, VT, MVT::Other, Arg, Zero, Chain); 65486c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } else { 65586c041f50e17f7fcd18193ff49e58379924d6472Scott Michel Result = 65686c041f50e17f7fcd18193ff49e58379924d6472Scott Michel CurDAG->SelectNodeTo(N, (VT == MVT::f32 ? SPU::ORf32 : SPU::ORf64), 65786c041f50e17f7fcd18193ff49e58379924d6472Scott Michel MVT::Other, Arg, Arg, Chain); 65886c041f50e17f7fcd18193ff49e58379924d6472Scott Michel } 65986c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 660266bc8f7774b153401e54ed537db299159840981Scott Michel Chain = SDOperand(Result, 1); 66186c041f50e17f7fcd18193ff49e58379924d6472Scott Michel AddToISelQueue(Chain); 66286c041f50e17f7fcd18193ff49e58379924d6472Scott Michel 663266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 664266bc8f7774b153401e54ed537db299159840981Scott Michel } 665266bc8f7774b153401e54ed537db299159840981Scott Michel 666266bc8f7774b153401e54ed537db299159840981Scott Michel return SelectCode(Op); 667266bc8f7774b153401e54ed537db299159840981Scott Michel} 668266bc8f7774b153401e54ed537db299159840981Scott Michel 669266bc8f7774b153401e54ed537db299159840981Scott Michel/// createPPCISelDag - This pass converts a legalized DAG into a 670266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 671266bc8f7774b153401e54ed537db299159840981Scott Michel/// 672266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 673266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 674266bc8f7774b153401e54ed537db299159840981Scott Michel} 675