1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- AMDILISelDAGToDAG.cpp - A dag to dag inst selector for AMDIL ------===// 2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// The LLVM Compiler Infrastructure 4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source 6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details. 7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//==-----------------------------------------------------------------------===// 9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file 11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief Defines an instruction selector for the AMDGPU target. 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUInstrInfo.h" 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUISelLowering.h" // For AMDGPUISD 16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPURegisterInfo.h" 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDILDevices.h" 18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h" 19d3b5509b8099b72104bd8a0d9a998a69eb56ab2aChristian Konig#include "SIISelLowering.h" 20f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/ADT/ValueMap.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/PseudoSourceValue.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/SelectionDAGISel.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/Compiler.h" 249f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard#include "llvm/CodeGen/SelectionDAG.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include <list> 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include <queue> 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Instruction Selector Implementation 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardnamespace { 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// AMDGPU specific code to select AMDGPU machine instructions for 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// SelectionDAG operations. 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardclass AMDGPUDAGToDAGISel : public SelectionDAGISel { 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // make the right decision when generating code for different targets. 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const AMDGPUSubtarget &Subtarget; 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic: 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUDAGToDAGISel(TargetMachine &TM); 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual ~AMDGPUDAGToDAGISel(); 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDNode *Select(SDNode *N); 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual const char *getPassName() const; 47c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig virtual void PostprocessISelDAG(); 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardprivate: 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard inline SDValue getSmallIPtrImm(unsigned Imm); 519f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard bool FoldOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Complex pattern selectors 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2); 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2); 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2); 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool checkType(const Value *ptr, unsigned int addrspace); 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static const Value *getBasePointerValue(const Value *V); 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isGlobalStore(const StoreSDNode *N); 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isPrivateStore(const StoreSDNode *N); 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isLocalStore(const StoreSDNode *N); 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isRegionStore(const StoreSDNode *N); 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isCPLoad(const LoadSDNode *N); 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isConstantLoad(const LoadSDNode *N, int cbID); 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isGlobalLoad(const LoadSDNode *N); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isParamLoad(const LoadSDNode *N); 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isPrivateLoad(const LoadSDNode *N); 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isLocalLoad(const LoadSDNode *N); 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static bool isRegionLoad(const LoadSDNode *N); 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); 759f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard bool SelectGlobalValueVariableOffset(SDValue Addr, 769f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue &BaseReg, SDValue& Offset); 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); 78c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Include the pieces autogenerated from the target description. 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUGenDAGISel.inc" 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}; 83f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} // end anonymous namespace 84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief This pass converts a legalized DAG into a AMDGPU-specific 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// DAG, ready for instruction scheduling. 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardFunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ) { 89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return new AMDGPUDAGToDAGISel(TM); 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ) 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard : SelectionDAGISel(TM), Subtarget(TM.getSubtarget<AMDGPUSubtarget>()) { 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() { 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(unsigned int Imm) { 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CurDAG->getTargetConstant(Imm, MVT::i32); 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::SelectADDRParam( 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Addr, SDValue& R1, SDValue& R2) { 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Addr.getOpcode() == ISD::FrameIndex) { 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i32); 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr; 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i32); 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Addr.getOpcode() == ISD::ADD) { 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr.getOperand(0); 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = Addr.getOperand(1); 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr; 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i32); 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) { 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Addr.getOpcode() == ISD::TargetExternalSymbol || 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Addr.getOpcode() == ISD::TargetGlobalAddress) { 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SelectADDRParam(Addr, R1, R2); 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::SelectADDR64(SDValue Addr, SDValue& R1, SDValue& R2) { 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Addr.getOpcode() == ISD::TargetExternalSymbol || 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Addr.getOpcode() == ISD::TargetGlobalAddress) { 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Addr.getOpcode() == ISD::FrameIndex) { 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i64); 144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 145f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr; 146f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i64); 147f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 148f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Addr.getOpcode() == ISD::ADD) { 149f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr.getOperand(0); 150f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = Addr.getOperand(1); 151f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 152f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R1 = Addr; 153f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R2 = CurDAG->getTargetConstant(0, MVT::i64); 154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 156f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 157f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 158f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { 159f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned int Opc = N->getOpcode(); 160f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (N->isMachineOpcode()) { 161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return NULL; // Already selected. 162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opc) { 164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: break; 165cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune case ISD::BUILD_VECTOR: { 166cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 167cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 168cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune break; 169cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune } 170cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune // BUILD_VECTOR is usually lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG 171cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune // that adds a 128 bits reg copy when going through TwoAddressInstructions 172cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune // pass. We want to avoid 128 bits copies as much as possible because they 173cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune // can't be bundled by our scheduler. 174cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune SDValue RegSeqArgs[9] = { 175cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune CurDAG->getTargetConstant(AMDGPU::R600_Reg128RegClassID, MVT::i32), 176cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune SDValue(), CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32), 177cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune SDValue(), CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32), 178cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune SDValue(), CurDAG->getTargetConstant(AMDGPU::sub2, MVT::i32), 179cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune SDValue(), CurDAG->getTargetConstant(AMDGPU::sub3, MVT::i32) 180cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune }; 181cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune bool IsRegSeq = true; 182cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune for (unsigned i = 0; i < N->getNumOperands(); i++) { 183cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune if (dyn_cast<RegisterSDNode>(N->getOperand(i))) { 184cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune IsRegSeq = false; 185cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune break; 186cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune } 187cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune RegSeqArgs[2 * i + 1] = N->getOperand(i); 188cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune } 189cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune if (!IsRegSeq) 190cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune break; 191cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->getVTList(), 192cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune RegSeqArgs, 2 * N->getNumOperands() + 1); 193cae6801b7df7c006d2956d5b6012b902cf6eb14dVincent Lejeune } 194f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::ConstantFP: 195f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::Constant: { 196f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 197f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: Custom immediate lowering not implemented yet. Instead we use 198f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // pseudo instructions defined in SIInstructions.td 199f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 200f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 202f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const R600InstrInfo *TII = static_cast<const R600InstrInfo*>(TM.getInstrInfo()); 203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t ImmValue = 0; 205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ImmReg = AMDGPU::ALU_LITERAL_X; 206f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 207f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (N->getOpcode() == ISD::ConstantFP) { 208f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: 64-bit Immediates not supported yet 209f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(N->getValueType(0) != MVT::f64); 210f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N); 212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard APFloat Value = C->getValueAPF(); 213f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard float FloatValue = Value.convertToFloat(); 214f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FloatValue == 0.0) { 215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmReg = AMDGPU::ZERO; 216f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (FloatValue == 0.5) { 217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmReg = AMDGPU::HALF; 218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (FloatValue == 1.0) { 219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmReg = AMDGPU::ONE; 220f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 221f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmValue = Value.bitcastToAPInt().getZExtValue(); 222f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 223f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 224f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: 64-bit Immediates not supported yet 225f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(N->getValueType(0) != MVT::i64); 226f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 227f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ConstantSDNode *C = dyn_cast<ConstantSDNode>(N); 228f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (C->getZExtValue() == 0) { 229f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmReg = AMDGPU::ZERO; 230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (C->getZExtValue() == 1) { 231f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmReg = AMDGPU::ONE_INT; 232f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 233f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmValue = C->getZExtValue(); 234f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 235f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 237f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (SDNode::use_iterator Use = N->use_begin(), Next = llvm::next(Use); 238f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Use != SDNode::use_end(); Use = Next) { 239f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Next = llvm::next(Use); 240f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::vector<SDValue> Ops; 241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0; i < Use->getNumOperands(); ++i) { 242f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ops.push_back(Use->getOperand(i)); 243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 244f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 245f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!Use->isMachineOpcode()) { 246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ImmReg == AMDGPU::ALU_LITERAL_X) { 247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // We can only use literal constants (e.g. AMDGPU::ZERO, 248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // AMDGPU::ONE, etc) in machine opcodes. 249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 252df65b0fb51d57a7e8dfcd19557b1d00c11c9fe2aVincent Lejeune if (!TII->isALUInstr(Use->getMachineOpcode()) || 253df65b0fb51d57a7e8dfcd19557b1d00c11c9fe2aVincent Lejeune (TII->get(Use->getMachineOpcode()).TSFlags & 254df65b0fb51d57a7e8dfcd19557b1d00c11c9fe2aVincent Lejeune R600_InstFlag::VECTOR)) { 255f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 256f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 257f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 258f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int ImmIdx = TII->getOperandIdx(Use->getMachineOpcode(), R600Operands::IMM); 259f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(ImmIdx != -1); 260f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 261f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // subtract one from ImmIdx, because the DST operand is usually index 262f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // 0 for MachineInstrs, but we have no DST in the Ops vector. 263f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ImmIdx--; 264f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 265f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Check that we aren't already using an immediate. 266f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: It's possible for an instruction to have more than one 267f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // immediate operand, but this is not supported yet. 268f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ImmReg == AMDGPU::ALU_LITERAL_X) { 269f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ConstantSDNode *C = dyn_cast<ConstantSDNode>(Use->getOperand(ImmIdx)); 270f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(C); 271f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 272f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (C->getZExtValue() != 0) { 273f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // This instruction is already using an immediate. 274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 275f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 276f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 277f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Set the immediate value 278f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ops[ImmIdx] = CurDAG->getTargetConstant(ImmValue, MVT::i32); 279f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 280f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 281f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Set the immediate register 282f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ops[Use.getOperandNo()] = CurDAG->getRegister(ImmReg, MVT::i32); 283f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 284f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CurDAG->UpdateNodeOperands(*Use, Ops.data(), Use->getNumOperands()); 285f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 286f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 287f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 2899f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDNode *Result = SelectCode(N); 2909f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 2919f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // Fold operands of selected node 2929f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 2939f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 2949f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { 2959f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard const R600InstrInfo *TII = 2969f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard static_cast<const R600InstrInfo*>(TM.getInstrInfo()); 297df65b0fb51d57a7e8dfcd19557b1d00c11c9fe2aVincent Lejeune if (Result && Result->isMachineOpcode() && 298df65b0fb51d57a7e8dfcd19557b1d00c11c9fe2aVincent Lejeune !(TII->get(Result->getMachineOpcode()).TSFlags & R600_InstFlag::VECTOR) 2994bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard && TII->isALUInstr(Result->getMachineOpcode())) { 3004bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard // Fold FNEG/FABS/CONST_ADDRESS 3014bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard // TODO: Isel can generate multiple MachineInst, we need to recursively 3024bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard // parse Result 3039f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard bool IsModified = false; 3049f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard do { 3059f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard std::vector<SDValue> Ops; 3069f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard for(SDNode::op_iterator I = Result->op_begin(), E = Result->op_end(); 3079f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard I != E; ++I) 3089f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Ops.push_back(*I); 3099f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard IsModified = FoldOperands(Result->getMachineOpcode(), TII, Ops); 3109f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (IsModified) { 3114bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Result = CurDAG->UpdateNodeOperands(Result, Ops.data(), Ops.size()); 3129f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 3139f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } while (IsModified); 3144bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard 3154bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard // If node has a single use which is CLAMP_R600, folds it 3164bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard if (Result->hasOneUse() && Result->isMachineOpcode()) { 3174bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard SDNode *PotentialClamp = *Result->use_begin(); 3184bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard if (PotentialClamp->isMachineOpcode() && 3194bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard PotentialClamp->getMachineOpcode() == AMDGPU::CLAMP_R600) { 3204bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard unsigned ClampIdx = 3214bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Result->getMachineOpcode(), R600Operands::CLAMP); 3224bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard std::vector<SDValue> Ops; 3234bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard unsigned NumOp = Result->getNumOperands(); 3244bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard for (unsigned i = 0; i < NumOp; ++i) { 3254bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops.push_back(Result->getOperand(i)); 3264bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard } 3274bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops[ClampIdx - 1] = CurDAG->getTargetConstant(1, MVT::i32); 3284bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Result = CurDAG->SelectNodeTo(PotentialClamp, 3294bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Result->getMachineOpcode(), PotentialClamp->getVTList(), 3304bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops.data(), NumOp); 3314bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard } 3324bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard } 3339f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 3349f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 3359f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 3369f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return Result; 3379f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard} 3389f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 3399f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellardbool AMDGPUDAGToDAGISel::FoldOperands(unsigned Opcode, 3409f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard const R600InstrInfo *TII, std::vector<SDValue> &Ops) { 3419f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard int OperandIdx[] = { 3429f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC0), 3439f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC1), 3449f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC2) 3459f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard }; 3469f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard int SelIdx[] = { 3479f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC0_SEL), 3489f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC1_SEL), 3499f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC2_SEL) 3509f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard }; 3514bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard int NegIdx[] = { 3524bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC0_NEG), 3534bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC1_NEG), 3544bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC2_NEG) 3554bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard }; 3564bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard int AbsIdx[] = { 3574bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC0_ABS), 3584bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard TII->getOperandIdx(Opcode, R600Operands::SRC1_ABS), 3594bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard -1 3604bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard }; 3614bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard 3629f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard for (unsigned i = 0; i < 3; i++) { 3639f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (OperandIdx[i] < 0) 3649f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return false; 3659f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Operand = Ops[OperandIdx[i] - 1]; 3669f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard switch (Operand.getOpcode()) { 3679f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUISD::CONST_ADDRESS: { 3689f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue CstOffset; 3693ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Operand.getValueType().isVector() || 3703ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune !SelectGlobalValueConstantOffset(Operand.getOperand(0), CstOffset)) 3713ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune break; 3723ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 3733ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune // Gather others constants values 3743ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune std::vector<unsigned> Consts; 3753ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned j = 0; j < 3; j++) { 3763ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune int SrcIdx = OperandIdx[j]; 3773ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (SrcIdx < 0) 3783ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune break; 3793ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (RegisterSDNode *Reg = dyn_cast<RegisterSDNode>(Ops[SrcIdx - 1])) { 3803ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Reg->getReg() == AMDGPU::ALU_CONST) { 3813ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Ops[SelIdx[j] - 1]); 3823ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Consts.push_back(Cst->getZExtValue()); 3833ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3843ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3859f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 3863ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 3873ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(CstOffset); 3883ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Consts.push_back(Cst->getZExtValue()); 3893ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!TII->fitsConstReadLimitations(Consts)) 3903ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune break; 3913ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 3923ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Ops[OperandIdx[i] - 1] = CurDAG->getRegister(AMDGPU::ALU_CONST, MVT::f32); 3933ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Ops[SelIdx[i] - 1] = CstOffset; 3943ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return true; 3959f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 3964bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard case ISD::FNEG: 3974bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard if (NegIdx[i] < 0) 3984bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard break; 3994bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops[OperandIdx[i] - 1] = Operand.getOperand(0); 4004bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops[NegIdx[i] - 1] = CurDAG->getTargetConstant(1, MVT::i32); 4014bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard return true; 4024bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard case ISD::FABS: 4034bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard if (AbsIdx[i] < 0) 4044bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard break; 4054bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops[OperandIdx[i] - 1] = Operand.getOperand(0); 4064bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard Ops[AbsIdx[i] - 1] = CurDAG->getTargetConstant(1, MVT::i32); 4074bdf9890edd91b82487a29ae134d53676829bd0dTom Stellard return true; 408cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard case ISD::BITCAST: 409cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard Ops[OperandIdx[i] - 1] = Operand.getOperand(0); 410cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard return true; 4119f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard default: 4129f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard break; 4139f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 4149f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 4159f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return false; 416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) { 419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!ptr) { 420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Type *ptrType = ptr->getType(); 423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace; 424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardconst Value * AMDGPUDAGToDAGISel::getBasePointerValue(const Value *V) { 427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!V) { 428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return NULL; 429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const Value *ret = NULL; 431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueMap<const Value *, bool> ValueBitMap; 432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::queue<const Value *, std::list<const Value *> > ValueQueue; 433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueQueue.push(V); 434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (!ValueQueue.empty()) { 435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard V = ValueQueue.front(); 436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ValueBitMap.find(V) == ValueBitMap.end()) { 437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueBitMap[V] = true; 438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (dyn_cast<Argument>(V) && dyn_cast<PointerType>(V->getType())) { 439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ret = V; 440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (dyn_cast<GlobalVariable>(V)) { 442f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ret = V; 443f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 444f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (dyn_cast<Constant>(V)) { 445f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const ConstantExpr *CE = dyn_cast<ConstantExpr>(V); 446f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CE) { 447f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueQueue.push(CE->getOperand(0)); 448f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) { 450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ret = AI; 451f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 452f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (const Instruction *I = dyn_cast<Instruction>(V)) { 453f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint32_t numOps = I->getNumOperands(); 454f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (uint32_t x = 0; x < numOps; ++x) { 455f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueQueue.push(I->getOperand(x)); 456f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 457f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 458f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Found a Value that we didn't know how to handle!"); 459f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 460f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 461f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ValueQueue.pop(); 462f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 463f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return ret; 464f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 465f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 466f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isGlobalStore(const StoreSDNode *N) { 467f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 468f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 469f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 470f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isPrivateStore(const StoreSDNode *N) { 471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 473f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS)); 474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isLocalStore(const StoreSDNode *N) { 477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 478f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 479f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isRegionStore(const StoreSDNode *N) { 481f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 482f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 483f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 484f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int cbID) { 485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS)) { 486f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 487f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineMemOperand *MMO = N->getMemOperand(); 489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const Value *V = MMO->getValue(); 490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const Value *BV = getBasePointerValue(V); 491f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MMO 492f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && MMO->getValue() 493f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && ((V && dyn_cast<GlobalValue>(V)) 494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard || (BV && dyn_cast<GlobalValue>( 495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard getBasePointerValue(MMO->getValue()))))) { 496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS); 497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 499f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 502f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) { 503f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 505f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 506f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isParamLoad(const LoadSDNode *N) { 507f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS); 508f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 509f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 510f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isLocalLoad(const LoadSDNode *N) { 511f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 512f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 513f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 514f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isRegionLoad(const LoadSDNode *N) { 515f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 516f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 517f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isCPLoad(const LoadSDNode *N) { 519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineMemOperand *MMO = N->getMemOperand(); 520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MMO) { 522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const Value *V = MMO->getValue(); 523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V); 524f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PSV && PSV == PseudoSourceValue::getConstantPool()) { 525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 529f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 530f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 532f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) { 533f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 534f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Check to make sure we are not a constant pool load or a constant load 535f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // that is marked as a private load 536f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isCPLoad(N) || isConstantLoad(N, -1)) { 537f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 538f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 539f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 540f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 541f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 542f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS) 543f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS) 544f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_D_ADDRESS) 545f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS)) { 546f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 547f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 549f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 551f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardconst char *AMDGPUDAGToDAGISel::getPassName() const { 552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return "AMDGPU DAG->DAG Pattern Instruction Selection"; 553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 554f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 555f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#ifdef DEBUGTMP 556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#undef INT64_C 557f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#endif 558f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#undef DEBUGTMP 559f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 560f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard///==== AMDGPU Functions ====/// 561f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 5629f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellardbool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr, 5639f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue& IntPtr) { 5649f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) { 5659f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, true); 5669f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return true; 5679f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 5689f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return false; 5699f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard} 5709f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 5719f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellardbool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr, 5729f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue& BaseReg, SDValue &Offset) { 5739f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (!dyn_cast<ConstantSDNode>(Addr)) { 5749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard BaseReg = Addr; 5759f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Offset = CurDAG->getIntPtrConstant(0, true); 5769f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return true; 5779f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 5789f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return false; 5799f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard} 5809f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 581f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 582f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue &Offset) { 583f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ConstantSDNode * IMMOffset; 584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Addr.getOpcode() == ISD::ADD 586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && isInt<16>(IMMOffset->getZExtValue())) { 588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Base = Addr.getOperand(0); 590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 591f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the pointer address is constant, we can move it to the offset field. 593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) 594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && isInt<16>(IMMOffset->getZExtValue())) { 595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CurDAG->getEntryNode().getDebugLoc(), 597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::ZERO, MVT::i32); 598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Default case, no offset 603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Base = Addr; 604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Offset = CurDAG->getTargetConstant(0, MVT::i32); 605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 608c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardbool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, 609c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDValue &Offset) { 610c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ConstantSDNode *C; 611c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 612c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if ((C = dyn_cast<ConstantSDNode>(Addr))) { 613c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 614c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); 615c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && 616c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 617c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Base = Addr.getOperand(0); 618c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); 619c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 620c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Base = Addr; 621c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = CurDAG->getTargetConstant(0, MVT::i32); 622c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 623c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 624c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return true; 625c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 626c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig 627c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konigvoid AMDGPUDAGToDAGISel::PostprocessISelDAG() { 628c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig 629c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig // Go over all selected nodes and try to fold them a bit more 630c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig const AMDGPUTargetLowering& Lowering = ((const AMDGPUTargetLowering&)TLI); 631c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), 632c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig E = CurDAG->allnodes_end(); I != E; ++I) { 633c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig 634c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig MachineSDNode *Node = dyn_cast<MachineSDNode>(I); 635c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig if (!Node) 636c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig continue; 637c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig 638c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig SDNode *ResNode = Lowering.PostISelFolding(Node, *CurDAG); 639c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig if (ResNode != Node) 640c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig ReplaceUses(Node, ResNode); 641c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig } 642c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig} 643c018ecac2f2f475b6e1023e90d0e48fcf9bd6e1dChristian Konig 644