R600ISelLowering.cpp revision 9c6b0b0ccebf9d9bf0f357a1c72ef941c5bbb2b2
1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===// 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 Custom DAG lowering for R600 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600ISelLowering.h" 16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600Defines.h" 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h" 18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600MachineFunctionInfo.h" 19c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineFrameInfo.h" 20f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineInstrBuilder.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/SelectionDAG.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Argument.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600TargetLowering::R600TargetLowering(TargetMachine &TM) : 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUTargetLowering(TM), 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) { 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::MUL, MVT::i64, Expand); 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass); 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass); 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass); 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass); 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard computeRegisterProperties(); 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FADD, MVT::v4f32, Expand); 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FMUL, MVT::v4f32, Expand); 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FDIV, MVT::v4f32, Expand); 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FSUB, MVT::v4f32, Expand); 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::ADD, MVT::v4i32, Expand); 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::AND, MVT::v4i32, Expand); 45519b456fe1eae633854584f54c8804498b256381Tom Stellard setOperationAction(ISD::FP_TO_SINT, MVT::v4i32, Expand); 46519b456fe1eae633854584f54c8804498b256381Tom Stellard setOperationAction(ISD::FP_TO_UINT, MVT::v4i32, Expand); 47519b456fe1eae633854584f54c8804498b256381Tom Stellard setOperationAction(ISD::SINT_TO_FP, MVT::v4i32, Expand); 48519b456fe1eae633854584f54c8804498b256381Tom Stellard setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Expand); 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::UDIV, MVT::v4i32, Expand); 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::UREM, MVT::v4i32, Expand); 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SETCC, MVT::v4i32, Expand); 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::BR_CC, MVT::i32, Custom); 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::BR_CC, MVT::f32, Custom); 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FSUB, MVT::f32, Expand); 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i1, Custom); 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FPOW, MVT::f32, Custom); 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::ROTL, MVT::i32, Custom); 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 689c6b0b0ccebf9d9bf0f357a1c72ef941c5bbb2b2Tom Stellard setOperationAction(ISD::SETCC, MVT::i32, Expand); 699c6b0b0ccebf9d9bf0f357a1c72ef941c5bbb2b2Tom Stellard setOperationAction(ISD::SETCC, MVT::f32, Expand); 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FP_TO_UINT, MVT::i1, Custom); 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT, MVT::i32, Custom); 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT, MVT::f32, Custom); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 75c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Legalize loads and stores to the private address space. 76c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::LOAD, MVT::i32, Custom); 77c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::LOAD, MVT::v2i32, Custom); 78c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::LOAD, MVT::v4i32, Custom); 79c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setLoadExtAction(ISD::EXTLOAD, MVT::v4i8, Custom); 80c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); 81c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setLoadExtAction(ISD::ZEXTLOAD, MVT::i8, Custom); 82c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i8, Custom); 83c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::STORE, MVT::i8, Custom); 84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::STORE, MVT::i32, Custom); 85c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::STORE, MVT::v2i32, Custom); 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::STORE, MVT::v4i32, Custom); 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 889f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard setOperationAction(ISD::LOAD, MVT::i32, Custom); 899f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard setOperationAction(ISD::LOAD, MVT::v4i32, Custom); 90c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setOperationAction(ISD::FrameIndex, MVT::i32, Custom); 91c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setTargetDAGCombine(ISD::FP_ROUND); 931234c9be42b4ebd4b398df461123205dccf3706cTom Stellard setTargetDAGCombine(ISD::FP_TO_SINT); 949f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); 951234c9be42b4ebd4b398df461123205dccf3706cTom Stellard setTargetDAGCombine(ISD::SELECT_CC); 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 97ff1ccdf9c58d12b142b3ab7473ac531cc5728a06Tom Stellard setBooleanContents(ZeroOrNegativeOneBooleanContent); 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setSchedulingPreference(Sched::VLIW); 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * MI, MachineBasicBlock * BB) const { 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction * MF = BB->getParent(); 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineRegisterInfo &MRI = MF->getRegInfo(); 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = *MI; 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getOpcode()) { 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CLAMP_R600: { 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_CLAMP); 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::FABS_R600: { 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_ABS); 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::FNEG_R600: { 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_NEG); 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MASK_WRITE: { 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned maskedRegister = MI->getOperand(0).getReg(); 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TargetRegisterInfo::isVirtualRegister(maskedRegister)); 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * defInstr = MRI.getVRegDef(maskedRegister); 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(defInstr, 0, MO_FLAG_MASK); 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_F32: 145f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 146f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getFPImm()->getValueAPF() 147f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .bitcastToAPInt().getZExtValue()); 148f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 149f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_I32: 150f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 151f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getImm()); 152f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 153d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune case AMDGPU::CONST_COPY: { 154d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, MI, AMDGPU::MOV, 155d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune MI->getOperand(0).getReg(), AMDGPU::ALU_CONST); 156d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune TII->setImmOperand(NewMI, R600Operands::SRC0_SEL, 157d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune MI->getOperand(1).getImm()); 158d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune break; 159d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune } 160f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RAT_WRITE_CACHELESS_32_eg: 162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RAT_WRITE_CACHELESS_128_eg: { 163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN) ? 1 : 0; 164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 165f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 167f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 168f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(EOP); // Set End of program bit 169f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 172f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::TXD: { 173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 174f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 175f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 176f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 177f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(3)) 178f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 180f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 181f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(2)) 183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 186f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G)) 187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 189f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 190f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 191f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)) 192f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T0, RegState::Implicit) 193f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T1, RegState::Implicit); 194f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 195f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 196f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 197f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::TXD_SHADOW: { 198f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 199f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 200f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 202f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(3)) 203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 206f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 207f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(2)) 208f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 209f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 210f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G)) 212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 213f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 214f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 216f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)) 217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T0, RegState::Implicit) 218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T1, RegState::Implicit); 219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 220f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 221f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 222f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH: 223f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 224f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 225f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(0); 226f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 227f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 228f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH_COND_f32: { 229f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = 230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 231f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::PREDICATE_BIT) 232f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 233f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(OPCODE_IS_NOT_ZERO) 234f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // Flags 235f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 237f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 238f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 239f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 240f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 242f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH_COND_i32: { 243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = 244f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 245f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::PREDICATE_BIT) 246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(OPCODE_IS_NOT_ZERO_INT) 248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // Flags 249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 252f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 253f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 254f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 255f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 256f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::EG_ExportSwz: 257f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::R600_ExportSwz: { 258254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard // Instruction is left unmodified if its not the last one of its type 259254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard bool isLastInstructionOfItsType = true; 260254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard unsigned InstExportType = MI->getOperand(1).getImm(); 261254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard for (MachineBasicBlock::iterator NextExportInst = llvm::next(I), 262254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard EndBlock = BB->end(); NextExportInst != EndBlock; 263254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard NextExportInst = llvm::next(NextExportInst)) { 264254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard if (NextExportInst->getOpcode() == AMDGPU::EG_ExportSwz || 265254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard NextExportInst->getOpcode() == AMDGPU::R600_ExportSwz) { 266254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard unsigned CurrentInstExportType = NextExportInst->getOperand(1) 267254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard .getImm(); 268254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard if (CurrentInstExportType == InstExportType) { 269254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard isLastInstructionOfItsType = false; 270254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard break; 271254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard } 272254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard } 273254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard } 274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN)? 1 : 0; 275254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard if (!EOP && !isLastInstructionOfItsType) 276f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return BB; 277f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned CfInst = (MI->getOpcode() == AMDGPU::EG_ExportSwz)? 84 : 40; 278f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 279f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 280f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 281f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(2)) 282f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(3)) 283f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 284f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 285f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)) 286f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(CfInst) 287254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard .addImm(EOP); 288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 289f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 290a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen case AMDGPU::RETURN: { 291a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen // RETURN instructions must have the live-out registers as implicit uses, 292a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen // otherwise they appear dead. 293a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>(); 294a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen MachineInstrBuilder MIB(*MF, MI); 295a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen for (unsigned i = 0, e = MFI->LiveOuts.size(); i != e; ++i) 296a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen MIB.addReg(MFI->LiveOuts[i], RegState::Implicit); 297a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen return BB; 298a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen } 299f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 300f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 301f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->eraseFromParent(); 302f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return BB; 303f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 304f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 305f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 306f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Lowering Operations 307f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 308f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 309f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm::Intrinsic; 310f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm::AMDGPUIntrinsic; 311f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 312f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 313f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Op.getOpcode()) { 314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::BR_CC: return LowerBR_CC(Op, DAG); 316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::ROTL: return LowerROTL(Op, DAG); 317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SELECT: return LowerSELECT(Op, DAG); 319f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::STORE: return LowerSTORE(Op, DAG); 3209f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case ISD::LOAD: return LowerLOAD(Op, DAG); 321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FPOW: return LowerFPOW(Op, DAG); 322c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case ISD::FrameIndex: return LowerFrameIndex(Op, DAG); 323f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::INTRINSIC_VOID: { 324f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 325f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned IntrinsicID = 326f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 327f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (IntrinsicID) { 328f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::AMDGPU_store_output: { 329f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction &MF = DAG.getMachineFunction(); 330a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); 331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue(); 332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex); 333a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen MFI->LiveOuts.push_back(Reg); 334f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getCopyToReg(Chain, Op.getDebugLoc(), Reg, Op.getOperand(2)); 335f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 336abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune case AMDGPUIntrinsic::R600_store_swizzle: { 337abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune const SDValue Args[8] = { 338abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune Chain, 339abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune Op.getOperand(2), // Export Value 340abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune Op.getOperand(3), // ArrayBase 341abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune Op.getOperand(4), // Type 342abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getConstant(0, MVT::i32), // SWZ_X 343abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getConstant(1, MVT::i32), // SWZ_Y 344abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getConstant(2, MVT::i32), // SWZ_Z 345abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getConstant(3, MVT::i32) // SWZ_W 346abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune }; 347abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune return DAG.getNode(AMDGPUISD::EXPORT, Op.getDebugLoc(), Op.getValueType(), 348abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune Args, 8); 349f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 350f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // default for switch(IntrinsicID) 352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: break; 353f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 354f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // break out of case ISD::INTRINSIC_VOID in switch(Op.getOpcode()) 355f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 356f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 357f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::INTRINSIC_WO_CHAIN: { 358f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned IntrinsicID = 359f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 360f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 361f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 362f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(IntrinsicID) { 363f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 364f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_load_input: { 365f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 366f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex); 367f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, Reg, VT); 368f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 36929b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard 37029b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard case AMDGPUIntrinsic::R600_interp_input: { 371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 37229b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard int ijb = cast<ConstantSDNode>(Op.getOperand(2))->getSExtValue(); 37329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard MachineSDNode *interp; 37429b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard if (ijb < 0) { 37529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard interp = DAG.getMachineNode(AMDGPU::INTERP_VEC_LOAD, DL, 37629b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard MVT::v4f32, DAG.getTargetConstant(slot / 4 , MVT::i32)); 37729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard return DAG.getTargetExtractSubreg( 37829b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard TII->getRegisterInfo().getSubRegFromChannel(slot % 4), 37929b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard DL, MVT::f32, SDValue(interp, 0)); 38029b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard } 38129b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard 38229b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard if (slot % 4 < 2) 38329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_XY, DL, 38429b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard MVT::f32, MVT::f32, DAG.getTargetConstant(slot / 4 , MVT::i32), 38529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 38629b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb + 1), MVT::f32), 38729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 38829b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb), MVT::f32)); 38929b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard else 39029b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_ZW, DL, 39129b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard MVT::f32, MVT::f32, DAG.getTargetConstant(slot / 4 , MVT::i32), 39229b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 39329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb + 1), MVT::f32), 39429b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 39529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb), MVT::f32)); 39629b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard 39729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard return SDValue(interp, slot % 2); 398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_x: 401f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 0); 402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_y: 403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 1); 404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_z: 405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 2); 406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_x: 407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 3); 408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_y: 409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 4); 410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_z: 411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 5); 412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_x: 413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 6); 414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_y: 415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 7); 416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_z: 417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 8); 418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_x: 420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_X, VT); 422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_y: 423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_Y, VT); 425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_z: 426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_Z, VT); 428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_x: 429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_X, VT); 431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_y: 432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_Y, VT); 434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_z: 435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_Z, VT); 437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // break out of case ISD::INTRINSIC_WO_CHAIN in switch(Op.getOpcode()) 439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } // end switch(Op.getOpcode()) 442f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SDValue(); 443f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 444f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 445f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600TargetLowering::ReplaceNodeResults(SDNode *N, 446f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<SDValue> &Results, 447f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG) const { 448f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (N->getOpcode()) { 449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return; 450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG)); 4519f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return; 4529f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case ISD::LOAD: { 4539f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDNode *Node = LowerLOAD(SDValue(N, 0), DAG).getNode(); 4549f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Results.push_back(SDValue(Node, 0)); 4559f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Results.push_back(SDValue(Node, 1)); 4569f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // XXX: LLVM seems not to replace Chain Value inside CustomWidenLowerNode 4579f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // function 4589f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), SDValue(Node, 1)); 4599f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return; 4609f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 461c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case ISD::STORE: 462c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDNode *Node = LowerSTORE(SDValue(N, 0), DAG).getNode(); 463c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Results.push_back(SDValue(Node, 0)); 464c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return; 465f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 466f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 467f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 468f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const { 469f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode( 470f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SETCC, 471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i1, 473f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op, DAG.getConstantFP(0.0f, MVT::f32), 474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE) 475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ); 476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 478f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 479f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CC = Op.getOperand(1); 481f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LHS = Op.getOperand(2); 482f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue RHS = Op.getOperand(3); 483f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue JumpT = Op.getOperand(4); 484f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CmpValue; 485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Result; 486f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 487f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LHS.getValueType() == MVT::i32) { 488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue = DAG.getNode( 489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 491f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i32, 492f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 493f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(-1, MVT::i32), 494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (LHS.getValueType() == MVT::f32) { 497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue = DAG.getNode( 498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 499f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::f32, 501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 502f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(1.0f, MVT::f32), 503f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(0.0f, MVT::f32), 504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 505f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 506f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(0 && "Not valid type for br_cc"); 507f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 508f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Result = DAG.getNode( 509f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::BRANCH_COND, 510f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue.getDebugLoc(), 511f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::Other, Chain, 512f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard JumpT, CmpValue); 513f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Result; 514f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 515f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 516f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT, 517f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL, 518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DwordOffset) const { 519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ByteOffset = DwordOffset * 4; 520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PointerType * PtrType = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUAS::PARAM_I_ADDRESS); 522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // We shouldn't be using an offset wider than 16-bits for implicit parameters. 524f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(isInt<16>(ByteOffset)); 525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getLoad(VT, DL, DAG.getEntryNode(), 527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(ByteOffset, MVT::i32), // PTR 528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachinePointerInfo(ConstantPointerNull::get(PtrType)), 529f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard false, false, false, 0); 530f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 532c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardSDValue R600TargetLowering::LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const { 533c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 534c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineFunction &MF = DAG.getMachineFunction(); 535c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = 536c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard static_cast<const AMDGPUFrameLowering*>(getTargetMachine().getFrameLowering()); 537c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 538c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op); 539c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(FIN); 540c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 541c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned FrameIndex = FIN->getIndex(); 542c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Offset = TFL->getFrameIndexOffset(MF, FrameIndex); 543c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return DAG.getConstant(Offset * 4 * TFL->getStackWidth(MF), MVT::i32); 544c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 545c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 546f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const { 547f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 549f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT, 551f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getNode(ISD::SUB, DL, VT, 554f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(32, MVT::i32), 555f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(1))); 556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 557f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 558f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600TargetLowering::isZero(SDValue Op) const { 559f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if(ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) { 560f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Cst->isNullValue(); 561f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if(ConstantFPSDNode *CstFP = dyn_cast<ConstantFPSDNode>(Op)){ 562f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CstFP->isZero(); 563f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 564f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 565f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 566f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 567f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 568f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { 569f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 570f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 571f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 572f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LHS = Op.getOperand(0); 573f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue RHS = Op.getOperand(1); 574f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue True = Op.getOperand(2); 575f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue False = Op.getOperand(3); 576f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CC = Op.getOperand(4); 577f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Temp; 578f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 579f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // LHS and RHS are guaranteed to be the same value type 580f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT CompareVT = LHS.getValueType(); 581f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 582f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Check if we can lower this to a native operation. 583f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Try to lower to a CND* instruction: 585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // CND* instructions requires RHS to be zero. Some SELECT_CC nodes that 586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // can be lowered to CND* instructions can also be lowered to SET* 587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instructions. CND* instructions are cheaper, because they dont't 588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // require additional instructions to convert their result to the correct 589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // value type, so this check should be first. 590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isZero(LHS) || isZero(RHS)) { 591f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Cond = (isZero(LHS) ? RHS : LHS); 592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Zero = (isZero(LHS) ? LHS : RHS); 593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CompareVT != VT) { 595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Bitcast True / False to the correct types. This will end up being 596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // a nop, but it allows us to define only a single pattern in the 597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // .TD files for each CND* instruction rather than having to have 598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // one pattern for integer True/False and one for fp True/False 599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True); 600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False); 601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isZero(LHS)) { 603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode); 604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (CCOpcode) { 607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETONE: 608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETUNE: 609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETNE: 610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETULE: 611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETULT: 612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETOLE: 613f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETOLT: 614f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETLE: 615f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETLT: 616f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32); 617f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Temp = True; 618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True = False; 619f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard False = Temp; 620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 624f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond, Zero, 626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True, False, 627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(CCOpcode)); 628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode); 629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Try to lower to a SET* instruction: 6321234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // 6331234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // CompareVT == MVT::f32 and VT == MVT::i32 is supported by the hardware, 6341234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // but for the other case where CompareVT != VT, all operands of 6351234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // SELECT_CC need to have the same value type, so we need to change True and 6361234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // False to be the same type as LHS and RHS, and then convert the result of 6371234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // the select_cc back to the correct type. 638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Move hardware True/False values to the correct operand. 640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isHWTrueValue(False) && isHWFalseValue(True)) { 641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::swap(False, True); 643f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC = DAG.getCondCode(ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32)); 644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 646f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isHWTrueValue(True) && isHWFalseValue(False)) { 6471234c9be42b4ebd4b398df461123205dccf3706cTom Stellard if (CompareVT != VT && VT == MVT::f32 && CompareVT == MVT::i32) { 6481234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue Boolean = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 6491234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS, RHS, 6501234c9be42b4ebd4b398df461123205dccf3706cTom Stellard DAG.getConstant(-1, MVT::i32), 6511234c9be42b4ebd4b398df461123205dccf3706cTom Stellard DAG.getConstant(0, MVT::i32), 6521234c9be42b4ebd4b398df461123205dccf3706cTom Stellard CC); 6531234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // Convert integer values of true (-1) and false (0) to fp values of 6541234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // true (1.0f) and false (0.0f). 6551234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue LSB = DAG.getNode(ISD::AND, DL, MVT::i32, Boolean, 6561234c9be42b4ebd4b398df461123205dccf3706cTom Stellard DAG.getConstant(1, MVT::i32)); 6571234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return DAG.getNode(ISD::UINT_TO_FP, DL, VT, LSB); 658f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 659f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // This SELECT_CC is already legal. 660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC); 661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Possible Min/Max pattern 665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue MinMax = LowerMinMax(Op, DAG); 666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MinMax.getNode()) { 667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MinMax; 668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we make it this for it means we have no native instructions to handle 671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // this SELECT_CC, so we must lower it. 672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue HWTrue, HWFalse; 673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CompareVT == MVT::f32) { 675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWTrue = DAG.getConstantFP(1.0f, CompareVT); 676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWFalse = DAG.getConstantFP(0.0f, CompareVT); 677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (CompareVT == MVT::i32) { 678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWTrue = DAG.getConstant(-1, CompareVT); 679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWFalse = DAG.getConstant(0, CompareVT); 680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard else { 682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unhandled value type in LowerSELECT_CC"); 683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Lower this unsupported SELECT_CC into a combination of two supported 686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // SELECT_CC operations. 687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, LHS, RHS, HWTrue, HWFalse, CC); 688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, DL, VT, 690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond, HWFalse, 691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True, False, 692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE)); 693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 695f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { 696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, 697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getValueType(), 699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(1), 702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(2), 703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE)); 704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 706c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// LLVM generates byte-addresed pointers. For indirect addressing, we need to 707c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// convert these pointers to a register index. Each register holds 708c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// 16 bytes, (4 x 32bit sub-register), but we need to take into account the 709c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// \p StackWidth, which tells us how many of the 4 sub-registrers will be used 710c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// for indirect addressing. 711c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardSDValue R600TargetLowering::stackPtrToRegIndex(SDValue Ptr, 712c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth, 713c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SelectionDAG &DAG) const { 714c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SRLPad; 715c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard switch(StackWidth) { 716c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 1: 717c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SRLPad = 2; 718c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 719c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 2: 720c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SRLPad = 3; 721c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 722c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 4: 723c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SRLPad = 4; 724c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 725c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard default: llvm_unreachable("Invalid stack width"); 726c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 727c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 728c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return DAG.getNode(ISD::SRL, Ptr.getDebugLoc(), Ptr.getValueType(), Ptr, 729c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getConstant(SRLPad, MVT::i32)); 730c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 731c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 732c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardvoid R600TargetLowering::getStackAddress(unsigned StackWidth, 733c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ElemIdx, 734c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned &Channel, 735c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned &PtrIncr) const { 736c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard switch (StackWidth) { 737c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard default: 738c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 1: 739c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Channel = 0; 740c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (ElemIdx > 0) { 741c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard PtrIncr = 1; 742c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 743c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard PtrIncr = 0; 744c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 745c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 746c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 2: 747c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Channel = ElemIdx % 2; 748c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (ElemIdx == 2) { 749c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard PtrIncr = 1; 750c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 751c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard PtrIncr = 0; 752c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 753c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 754c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard case 4: 755c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Channel = ElemIdx; 756c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard PtrIncr = 0; 757c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard break; 758c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 759c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 760c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 761f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const { 762f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 763f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard StoreSDNode *StoreNode = cast<StoreSDNode>(Op); 764f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 765f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Value = Op.getOperand(1); 766f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Ptr = Op.getOperand(2); 767f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 768f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (StoreNode->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && 769f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr->getOpcode() != AMDGPUISD::DWORDADDR) { 770f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Convert pointer from byte address to dword address. 771f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, Ptr.getValueType(), 772f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getNode(ISD::SRL, DL, Ptr.getValueType(), 773f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr, DAG.getConstant(2, MVT::i32))); 774f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 775f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (StoreNode->isTruncatingStore() || StoreNode->isIndexed()) { 776f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Truncated and indexed stores not supported yet"); 777f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 778f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Chain = DAG.getStore(Chain, DL, Value, Ptr, StoreNode->getMemOperand()); 779f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 780f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Chain; 781f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 782c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 783c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard EVT ValueVT = Value.getValueType(); 784c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 785c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (StoreNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) { 786c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return SDValue(); 787c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 788c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 789c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Lowering for indirect addressing 790c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 791c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF = DAG.getMachineFunction(); 792c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = static_cast<const AMDGPUFrameLowering*>( 793c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard getTargetMachine().getFrameLowering()); 794c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 795c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 796c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG); 797c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 798c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (ValueVT.isVector()) { 799c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned NumElemVT = ValueVT.getVectorNumElements(); 800c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard EVT ElemVT = ValueVT.getVectorElementType(); 801c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDValue Stores[4]; 802c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 803c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(NumElemVT >= StackWidth && "Stack width cannot be greater than " 804c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard "vector width in load"); 805c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 806c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned i = 0; i < NumElemVT; ++i) { 807c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel, PtrIncr; 808c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard getStackAddress(StackWidth, i, Channel, PtrIncr); 809c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr, 810c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getConstant(PtrIncr, MVT::i32)); 811c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDValue Elem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT, 812c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Value, DAG.getConstant(i, MVT::i32)); 813c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 814c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Stores[i] = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, 815c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Chain, Elem, Ptr, 816c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getTargetConstant(Channel, MVT::i32)); 817c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 818c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores, NumElemVT); 819c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 820c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (ValueVT == MVT::i8) { 821c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Value = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Value); 822c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 823c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Chain = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, Chain, Value, Ptr, 824c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getTargetConstant(0, MVT::i32)); // Channel 825c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 826c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 827c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Chain; 828f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 8309f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard// return (512 + (kc_bank << 12) 8319f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellardstatic int 8329f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom StellardConstantAddressBlock(unsigned AddressSpace) { 8339f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard switch (AddressSpace) { 8349f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_0: 8359f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512; 8369f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_1: 8379f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096; 8389f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_2: 8399f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 2; 8409f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_3: 8419f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 3; 8429f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_4: 8439f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 4; 8449f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_5: 8459f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 5; 8469f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_6: 8479f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 6; 8489f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_7: 8499f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 7; 8509f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_8: 8519f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 8; 8529f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_9: 8539f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 9; 8549f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_10: 8559f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 10; 8569f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_11: 8579f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 11; 8589f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_12: 8599f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 12; 8609f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_13: 8619f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 13; 8629f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_14: 8639f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 14; 8649f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case AMDGPUAS::CONSTANT_BUFFER_15: 8659f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return 512 + 4096 * 15; 8669f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard default: 8679f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return -1; 8689f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 8699f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard} 8709f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 8719f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom StellardSDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const 8729f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard{ 8739f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard EVT VT = Op.getValueType(); 8749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard DebugLoc DL = Op.getDebugLoc(); 8759f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard LoadSDNode *LoadNode = cast<LoadSDNode>(Op); 8769f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Chain = Op.getOperand(0); 8779f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Ptr = Op.getOperand(1); 8789f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue LoweredLoad; 8799f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 8809f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard int ConstantBlock = ConstantAddressBlock(LoadNode->getAddressSpace()); 8819f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (ConstantBlock > -1) { 8829f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Result; 8839f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (dyn_cast<ConstantExpr>(LoadNode->getSrcValue()) || 8843f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune dyn_cast<Constant>(LoadNode->getSrcValue()) || 8853f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune dyn_cast<ConstantSDNode>(Ptr)) { 8869f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Slots[4]; 8879f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard for (unsigned i = 0; i < 4; i++) { 8889f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // We want Const position encoded with the following formula : 8899f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // (((512 + (kc_bank << 12) + const_index) << 2) + chan) 8909f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // const_index is Ptr computed by llvm using an alignment of 16. 8919f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // Thus we add (((512 + (kc_bank << 12)) + chan ) * 4 here and 8929f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // then div by 4 at the ISel step 8939f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue NewPtr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, 8949f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard DAG.getConstant(4 * i + ConstantBlock * 16, MVT::i32)); 8959f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Slots[i] = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::i32, NewPtr); 8969f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 8979f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Result = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4i32, Slots, 4); 8989f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } else { 8999f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // non constant ptr cant be folded, keeps it as a v4f32 load 9009f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Result = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::v4i32, 9013f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune DAG.getNode(ISD::SRL, DL, MVT::i32, Ptr, DAG.getConstant(4, MVT::i32)), 902ff408c07282309a8a3d4daca7c7e127d2fce01edChristian Konig DAG.getConstant(LoadNode->getAddressSpace() - 903ff408c07282309a8a3d4daca7c7e127d2fce01edChristian Konig AMDGPUAS::CONSTANT_BUFFER_0, MVT::i32) 9049f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard ); 9059f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 9069f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 9079f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (!VT.isVector()) { 9089f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, Result, 9099f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard DAG.getConstant(0, MVT::i32)); 9109f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 9119f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 9129f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue MergedValues[2] = { 9139f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Result, 9149f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard Chain 9159f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard }; 9169f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return DAG.getMergeValues(MergedValues, 2, DL); 9179f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 9189f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard 919c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (LoadNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) { 920c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return SDValue(); 921c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 922c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 923c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Lowering for indirect addressing 924c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF = DAG.getMachineFunction(); 925c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = static_cast<const AMDGPUFrameLowering*>( 926c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard getTargetMachine().getFrameLowering()); 927c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 928c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 929c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG); 930c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 931c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (VT.isVector()) { 932c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned NumElemVT = VT.getVectorNumElements(); 933c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard EVT ElemVT = VT.getVectorElementType(); 934c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDValue Loads[4]; 935c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 936c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(NumElemVT >= StackWidth && "Stack width cannot be greater than " 937c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard "vector width in load"); 938c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 939c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned i = 0; i < NumElemVT; ++i) { 940c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel, PtrIncr; 941c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard getStackAddress(StackWidth, i, Channel, PtrIncr); 942c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr, 943c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getConstant(PtrIncr, MVT::i32)); 944c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Loads[i] = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, ElemVT, 945c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Chain, Ptr, 946c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getTargetConstant(Channel, MVT::i32), 947c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Op.getOperand(2)); 948c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 949c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned i = NumElemVT; i < 4; ++i) { 950c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Loads[i] = DAG.getUNDEF(ElemVT); 951c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 952c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard EVT TargetVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, 4); 953c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LoweredLoad = DAG.getNode(ISD::BUILD_VECTOR, DL, TargetVT, Loads, 4); 954c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 955c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LoweredLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, VT, 956c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Chain, Ptr, 957c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard DAG.getTargetConstant(0, MVT::i32), // Channel 958c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Op.getOperand(2)); 959c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 960c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 961c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard SDValue Ops[2]; 962c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ops[0] = LoweredLoad; 963c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Ops[1] = Chain; 964c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 965c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return DAG.getMergeValues(Ops, 2, DL); 9669f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard} 967f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 968f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFPOW(SDValue Op, 969f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG) const { 970f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 971f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 972f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LogBase = DAG.getNode(ISD::FLOG2, DL, VT, Op.getOperand(0)); 973f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue MulLogBase = DAG.getNode(ISD::FMUL, DL, VT, Op.getOperand(1), LogBase); 974f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::FEXP2, DL, VT, MulLogBase); 975f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 976f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 977f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// XXX Only kernel functions are supported, so we can assume for now that 978f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// every function is a kernel function, but in the future we should use 979f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// separate calling conventions for kernel and non-kernel functions. 980f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFormalArguments( 981f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain, 982f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CallingConv::ID CallConv, 983f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool isVarArg, 984f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<ISD::InputArg> &Ins, 985f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL, SelectionDAG &DAG, 986f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<SDValue> &InVals) const { 987f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ParamOffsetBytes = 36; 988f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Function::const_arg_iterator FuncArg = 989f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getMachineFunction().getFunction()->arg_begin(); 990f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0, e = Ins.size(); i < e; ++i, ++FuncArg) { 991f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Ins[i].VT; 992f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Type *ArgType = FuncArg->getType(); 993f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ArgSizeInBits = ArgType->isPointerTy() ? 994f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 32 : ArgType->getPrimitiveSizeInBits(); 995f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ArgBytes = ArgSizeInBits >> 3; 996f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT ArgVT; 997f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ArgSizeInBits < VT.getSizeInBits()) { 998f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!ArgType->isFloatTy() && 999f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Extending floating point arguments not supported yet"); 1000f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT = MVT::getIntegerVT(ArgSizeInBits); 1001f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1002f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT = VT; 1003f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1004f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PointerType *PtrTy = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 1005f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUAS::PARAM_I_ADDRESS); 1006f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Arg = DAG.getExtLoad(ISD::ZEXTLOAD, DL, VT, DAG.getRoot(), 1007f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(ParamOffsetBytes, MVT::i32), 100823339b68e224cedac1e7025ba8bca3e3eb127fabTom Stellard MachinePointerInfo(UndefValue::get(PtrTy)), 1009f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT, false, false, ArgBytes); 1010f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InVals.push_back(Arg); 1011f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ParamOffsetBytes += ArgBytes; 1012f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1013f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Chain; 1014f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1015f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1016f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardEVT R600TargetLowering::getSetCCResultType(EVT VT) const { 1017f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!VT.isVector()) return MVT::i32; 1018f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return VT.changeVectorElementTypeToInteger(); 1019f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1020f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1021f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1022f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Optimizations 1023f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1024f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1025f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::PerformDAGCombine(SDNode *N, 1026f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAGCombinerInfo &DCI) const { 1027f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG = DCI.DAG; 1028f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1029f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (N->getOpcode()) { 1030f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // (f32 fp_round (f64 uint_to_fp a)) -> (f32 uint_to_fp a) 1031f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FP_ROUND: { 1032f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Arg = N->getOperand(0); 1033f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Arg.getOpcode() == ISD::UINT_TO_FP && Arg.getValueType() == MVT::f64) { 1034f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), N->getValueType(0), 1035f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Arg.getOperand(0)); 1036f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1037f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1038f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 10391234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 10401234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // (i32 fp_to_sint (fneg (select_cc f32, f32, 1.0, 0.0 cc))) -> 10411234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // (i32 select_cc f32, f32, -1, 0 cc) 10421234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // 10431234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // Mesa's GLSL frontend generates the above pattern a lot and we can lower 10441234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // this to one of the SET*_DX10 instructions. 10451234c9be42b4ebd4b398df461123205dccf3706cTom Stellard case ISD::FP_TO_SINT: { 10461234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue FNeg = N->getOperand(0); 10471234c9be42b4ebd4b398df461123205dccf3706cTom Stellard if (FNeg.getOpcode() != ISD::FNEG) { 10481234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return SDValue(); 10491234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 10501234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue SelectCC = FNeg.getOperand(0); 10511234c9be42b4ebd4b398df461123205dccf3706cTom Stellard if (SelectCC.getOpcode() != ISD::SELECT_CC || 10521234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SelectCC.getOperand(0).getValueType() != MVT::f32 || // LHS 10531234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SelectCC.getOperand(2).getValueType() != MVT::f32 || // True 10541234c9be42b4ebd4b398df461123205dccf3706cTom Stellard !isHWTrueValue(SelectCC.getOperand(2)) || 10551234c9be42b4ebd4b398df461123205dccf3706cTom Stellard !isHWFalseValue(SelectCC.getOperand(3))) { 10561234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return SDValue(); 10571234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 10581234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 10591234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), N->getValueType(0), 10601234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SelectCC.getOperand(0), // LHS 10611234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SelectCC.getOperand(1), // RHS 10621234c9be42b4ebd4b398df461123205dccf3706cTom Stellard DAG.getConstant(-1, MVT::i32), // True 10631234c9be42b4ebd4b398df461123205dccf3706cTom Stellard DAG.getConstant(0, MVT::i32), // Flase 10641234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SelectCC.getOperand(4)); // CC 10651234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 10661234c9be42b4ebd4b398df461123205dccf3706cTom Stellard break; 10671234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 10689f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // Extract_vec (Build_vector) generated by custom lowering 10699f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard // also needs to be customly combined 10709f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard case ISD::EXTRACT_VECTOR_ELT: { 10719f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard SDValue Arg = N->getOperand(0); 10729f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (Arg.getOpcode() == ISD::BUILD_VECTOR) { 10739f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 10749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard unsigned Element = Const->getZExtValue(); 10759f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return Arg->getOperand(Element); 10769f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 10779f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 1078cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard if (Arg.getOpcode() == ISD::BITCAST && 1079cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard Arg.getOperand(0).getOpcode() == ISD::BUILD_VECTOR) { 1080cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 1081cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard unsigned Element = Const->getZExtValue(); 1082cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard return DAG.getNode(ISD::BITCAST, N->getDebugLoc(), N->getVTList(), 1083cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard Arg->getOperand(0).getOperand(Element)); 1084cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard } 1085cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard } 10869f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard } 10871234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 10881234c9be42b4ebd4b398df461123205dccf3706cTom Stellard case ISD::SELECT_CC: { 10891234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // fold selectcc (selectcc x, y, a, b, cc), b, a, b, seteq -> 10901234c9be42b4ebd4b398df461123205dccf3706cTom Stellard // selectcc x, y, a, b, inv(cc) 10911234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue LHS = N->getOperand(0); 10921234c9be42b4ebd4b398df461123205dccf3706cTom Stellard if (LHS.getOpcode() != ISD::SELECT_CC) { 10931234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return SDValue(); 10941234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 10951234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 10961234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue RHS = N->getOperand(1); 10971234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue True = N->getOperand(2); 10981234c9be42b4ebd4b398df461123205dccf3706cTom Stellard SDValue False = N->getOperand(3); 10991234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 11001234c9be42b4ebd4b398df461123205dccf3706cTom Stellard if (LHS.getOperand(2).getNode() != True.getNode() || 11011234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS.getOperand(3).getNode() != False.getNode() || 11021234c9be42b4ebd4b398df461123205dccf3706cTom Stellard RHS.getNode() != False.getNode() || 11031234c9be42b4ebd4b398df461123205dccf3706cTom Stellard cast<CondCodeSDNode>(N->getOperand(4))->get() != ISD::SETEQ) { 11041234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return SDValue(); 11051234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 11061234c9be42b4ebd4b398df461123205dccf3706cTom Stellard 11071234c9be42b4ebd4b398df461123205dccf3706cTom Stellard ISD::CondCode CCOpcode = cast<CondCodeSDNode>(LHS->getOperand(4))->get(); 11081234c9be42b4ebd4b398df461123205dccf3706cTom Stellard CCOpcode = ISD::getSetCCInverse( 11091234c9be42b4ebd4b398df461123205dccf3706cTom Stellard CCOpcode, LHS.getOperand(0).getValueType().isInteger()); 11101234c9be42b4ebd4b398df461123205dccf3706cTom Stellard return DAG.getSelectCC(N->getDebugLoc(), 11111234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS.getOperand(0), 11121234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS.getOperand(1), 11131234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS.getOperand(2), 11141234c9be42b4ebd4b398df461123205dccf3706cTom Stellard LHS.getOperand(3), 11151234c9be42b4ebd4b398df461123205dccf3706cTom Stellard CCOpcode); 1116abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } 1117abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune case AMDGPUISD::EXPORT: { 1118abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune SDValue Arg = N->getOperand(1); 1119abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune if (Arg.getOpcode() != ISD::BUILD_VECTOR) 1120abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune break; 1121abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune SDValue NewBldVec[4] = { 1122abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getUNDEF(MVT::f32), 1123abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getUNDEF(MVT::f32), 1124abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getUNDEF(MVT::f32), 1125abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DAG.getUNDEF(MVT::f32) 1126abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune }; 1127abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune SDValue NewArgs[8] = { 1128abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(0), // Chain 1129abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune SDValue(), 1130abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(2), // ArrayBase 1131abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(3), // Type 1132abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(4), // SWZ_X 1133abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(5), // SWZ_Y 1134abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(6), // SWZ_Z 1135abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune N->getOperand(7) // SWZ_W 1136abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune }; 1137abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune for (unsigned i = 0; i < Arg.getNumOperands(); i++) { 1138abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Arg.getOperand(i))) { 1139abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune if (C->isZero()) { 1140abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune NewArgs[4 + i] = DAG.getConstant(4, MVT::i32); // SEL_0 1141abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } else if (C->isExactlyValue(1.0)) { 1142abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune NewArgs[4 + i] = DAG.getConstant(5, MVT::i32); // SEL_0 1143abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } else { 1144abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune NewBldVec[i] = Arg.getOperand(i); 1145abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } 1146abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } else { 1147abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune NewBldVec[i] = Arg.getOperand(i); 1148abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } 1149abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune } 1150abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune DebugLoc DL = N->getDebugLoc(); 1151abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune NewArgs[1] = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, NewBldVec, 4); 1152abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune return DAG.getNode(AMDGPUISD::EXPORT, DL, N->getVTList(), NewArgs, 8); 11531234c9be42b4ebd4b398df461123205dccf3706cTom Stellard } 1154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SDValue(); 1156f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1157