R600ISelLowering.cpp revision f98f2ce29e6e2996fa58f38979143eceaa818335
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" 19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Argument.h" 20f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Function.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineInstrBuilder.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/SelectionDAG.h" 24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600TargetLowering::R600TargetLowering(TargetMachine &TM) : 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUTargetLowering(TM), 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) { 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::MUL, MVT::i64, Expand); 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass); 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass); 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass); 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass); 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard computeRegisterProperties(); 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FADD, MVT::v4f32, Expand); 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FMUL, MVT::v4f32, Expand); 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FDIV, MVT::v4f32, Expand); 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FSUB, MVT::v4f32, Expand); 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::ADD, MVT::v4i32, Expand); 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::AND, MVT::v4i32, Expand); 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::UDIV, MVT::v4i32, Expand); 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::UREM, MVT::v4i32, Expand); 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SETCC, MVT::v4i32, Expand); 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::BR_CC, MVT::i32, Custom); 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::BR_CC, MVT::f32, Custom); 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FSUB, MVT::f32, Expand); 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i1, Custom); 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FPOW, MVT::f32, Custom); 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::ROTL, MVT::i32, Custom); 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SETCC, MVT::i32, Custom); 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SETCC, MVT::f32, Custom); 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::FP_TO_UINT, MVT::i1, Custom); 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT, MVT::i32, Custom); 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::SELECT, MVT::f32, Custom); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::STORE, MVT::i32, Custom); 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setOperationAction(ISD::STORE, MVT::v4i32, Custom); 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setTargetDAGCombine(ISD::FP_ROUND); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setSchedulingPreference(Sched::VLIW); 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * MI, MachineBasicBlock * BB) const { 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction * MF = BB->getParent(); 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineRegisterInfo &MRI = MF->getRegInfo(); 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = *MI; 83f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getOpcode()) { 85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::SHADER_TYPE: break; 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CLAMP_R600: { 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_CLAMP); 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::FABS_R600: { 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_ABS); 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::FNEG_R600: { 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I, 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::MOV, 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(0).getReg(), 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getReg()); 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_NEG); 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::R600_LOAD_CONST: { 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = MI->getOperand(1).getImm(); 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ConstantReg = AMDGPU::R600_CReg32RegClass.getRegister(RegIndex); 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::COPY)) 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(ConstantReg); 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MASK_WRITE: { 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned maskedRegister = MI->getOperand(0).getReg(); 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TargetRegisterInfo::isVirtualRegister(maskedRegister)); 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * defInstr = MRI.getVRegDef(maskedRegister); 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(defInstr, 0, MO_FLAG_MASK); 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_F32: 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getFPImm()->getValueAPF() 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .bitcastToAPInt().getZExtValue()); 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_I32: 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(), 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(1).getImm()); 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RAT_WRITE_CACHELESS_32_eg: 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RAT_WRITE_CACHELESS_128_eg: { 144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN) ? 1 : 0; 145f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 146f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode())) 147f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 148f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 149f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(EOP); // Set End of program bit 150f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 151f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 152f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 153f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RESERVE_REG: { 154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>(); 155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t ReservedIndex = MI->getOperand(0).getImm(); 156f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ReservedReg = 157f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::R600_TReg32RegClass.getRegister(ReservedIndex); 158f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MFI->ReservedRegs.push_back(ReservedReg); 159f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SuperReg = 160f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::R600_Reg128RegClass.getRegister(ReservedIndex / 4); 161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MFI->ReservedRegs.push_back(SuperReg); 162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 165f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::TXD: { 166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 167f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 168f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 169f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(3)) 171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 172f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 174f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 175f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(2)) 176f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 177f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 178f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G)) 180f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 181f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)) 185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T0, RegState::Implicit) 186f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T1, RegState::Implicit); 187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 189f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 190f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::TXD_SHADOW: { 191f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 192f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass); 193f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 194f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0) 195f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(3)) 196f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 197f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 198f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 199f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1) 200f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(2)) 201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 202f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)); 204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G)) 205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 206f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 207f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(4)) 208f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(5)) 209f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(6)) 210f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T0, RegState::Implicit) 211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(T1, RegState::Implicit); 212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 213f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 214f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH: 216f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(0); 219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 220f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 221f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH_COND_f32: { 222f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = 223f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 224f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::PREDICATE_BIT) 225f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 226f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(OPCODE_IS_NOT_ZERO) 227f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // Flags 228f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 229f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 231f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 232f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 233f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 234f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 235f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::BRANCH_COND_i32: { 236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = 237f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X), 238f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::PREDICATE_BIT) 239f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(1)) 240f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(OPCODE_IS_NOT_ZERO_INT) 241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // Flags 242f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TII->addFlag(NewMI, 0, MO_FLAG_PUSH); 243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP)) 244f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addOperand(MI->getOperand(0)) 245f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::input_perspective: { 250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>(); 251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 252f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX Be more fine about register reservation 253f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0; i < 4; i ++) { 254f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ReservedReg = AMDGPU::R600_TReg32RegClass.getRegister(i); 255f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MFI->ReservedRegs.push_back(ReservedReg); 256f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 257f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 258f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getOperand(1).getImm()) { 259f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 0:// Perspective 260f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MFI->HasPerspectiveInterpolation = true; 261f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 262f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 1:// Linear 263f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MFI->HasLinearInterpolation = true; 264f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 265f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 266f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(0 && "Unknow ij index"); 267f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 268f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 269f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return BB; 270f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 271f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 272f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::EG_ExportSwz: 273f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::R600_ExportSwz: { 274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN)? 1 : 0; 275f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!EOP) 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) 287f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(1); 288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 289f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 290f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 291f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 292f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->eraseFromParent(); 293f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return BB; 294f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 295f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 296f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 297f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Lowering Operations 298f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 299f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 300f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm::Intrinsic; 301f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm::AMDGPUIntrinsic; 302f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 303f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic SDValue 304f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardInsertScalarToRegisterExport(SelectionDAG &DAG, DebugLoc DL, SDNode **ExportMap, 305f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Slot, unsigned Channel, unsigned Inst, unsigned Type, 306f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Scalar, SDValue Chain) { 307f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!ExportMap[Slot]) { 308f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, 309f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, MVT::v4f32, 310f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getUNDEF(MVT::v4f32), 311f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Scalar, 312f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Channel, MVT::i32)); 313f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Mask = 1 << Channel; 315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SDValue Ops[] = {Chain, Vector, DAG.getConstant(Inst, MVT::i32), 317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Type, MVT::i32), DAG.getConstant(Slot, MVT::i32), 318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Mask, MVT::i32)}; 319f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 320f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Res = DAG.getNode( 321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::EXPORT, 322f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, 323f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::Other, 324f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ops, 6); 325f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ExportMap[Slot] = Res.getNode(); 326f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Res; 327f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 328f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 329f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDNode *ExportInstruction = (SDNode *) ExportMap[Slot] ; 330f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue PreviousVector = ExportInstruction->getOperand(1); 331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, 332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, MVT::v4f32, 333f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PreviousVector, 334f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Scalar, 335f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Channel, MVT::i32)); 336f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 337f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Mask = dyn_cast<ConstantSDNode>(ExportInstruction->getOperand(5)) 338f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ->getZExtValue(); 339f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Mask |= (1 << Channel); 340f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 341f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SDValue Ops[] = {ExportInstruction->getOperand(0), Vector, 342f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Inst, MVT::i32), 343f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Type, MVT::i32), 344f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Slot, MVT::i32), 345f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(Mask, MVT::i32)}; 346f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 347f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.UpdateNodeOperands(ExportInstruction, 348f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ops, 6); 349f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 350f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Chain; 351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 353f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 354f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { 355f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Op.getOpcode()) { 356f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 357f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::BR_CC: return LowerBR_CC(Op, DAG); 358f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::ROTL: return LowerROTL(Op, DAG); 359f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 360f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SELECT: return LowerSELECT(Op, DAG); 361f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETCC: return LowerSETCC(Op, DAG); 362f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::STORE: return LowerSTORE(Op, DAG); 363f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FPOW: return LowerFPOW(Op, DAG); 364f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::INTRINSIC_VOID: { 365f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 366f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned IntrinsicID = 367f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 368f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (IntrinsicID) { 369f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::AMDGPU_store_output: { 370f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction &MF = DAG.getMachineFunction(); 371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineRegisterInfo &MRI = MF.getRegInfo(); 372f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue(); 373f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex); 374f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!MRI.isLiveOut(Reg)) { 375f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MRI.addLiveOut(Reg); 376f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 377f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getCopyToReg(Chain, Op.getDebugLoc(), Reg, Op.getOperand(2)); 378f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 379f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_store_pixel_color: { 380f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction &MF = DAG.getMachineFunction(); 381f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); 382f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue(); 383f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 384f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDNode **OutputsMap = MFI->Outputs; 385f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return InsertScalarToRegisterExport(DAG, Op.getDebugLoc(), OutputsMap, 386f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegIndex / 4, RegIndex % 4, 0, 0, Op.getOperand(2), 387f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Chain); 388f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 389f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 390f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_store_stream_output : { 391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineFunction &MF = DAG.getMachineFunction(); 392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); 393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue(); 394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t BufIndex = cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue(); 395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDNode **OutputsMap = MFI->StreamOutputs[BufIndex]; 397f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Inst; 398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue() ) { 399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // STREAM3 400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 3: 401f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Inst = 4; 402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // STREAM2 404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 2: 405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Inst = 3; 406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // STREAM1 408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 1: 409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Inst = 2; 410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // STREAM0 412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 0: 413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Inst = 1; 414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(0 && "Wrong buffer id for stream outputs !"); 417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return InsertScalarToRegisterExport(DAG, Op.getDebugLoc(), OutputsMap, 420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegIndex / 4, RegIndex % 4, Inst, 0, Op.getOperand(2), 421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Chain); 422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // default for switch(IntrinsicID) 424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: break; 425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // break out of case ISD::INTRINSIC_VOID in switch(Op.getOpcode()) 427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::INTRINSIC_WO_CHAIN: { 430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned IntrinsicID = 431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(IntrinsicID) { 435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); 436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_load_input: { 437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex); 439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, Reg, VT); 440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_load_input_perspective: { 442f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 443f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (slot < 0) 444f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getUNDEF(MVT::f32); 445f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue FullVector = DAG.getNode( 446f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::INTERP, 447f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, MVT::v4f32, 448f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), DAG.getConstant(slot / 4 , MVT::i32)); 449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, 450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); 451f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 452f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_load_input_linear: { 453f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 454f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (slot < 0) 455f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getUNDEF(MVT::f32); 456f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue FullVector = DAG.getNode( 457f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::INTERP, 458f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, MVT::v4f32, 459f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(1, MVT::i32), DAG.getConstant(slot / 4 , MVT::i32)); 460f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, 461f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); 462f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 463f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPUIntrinsic::R600_load_input_constant: { 464f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 465f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (slot < 0) 466f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getUNDEF(MVT::f32); 467f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue FullVector = DAG.getNode( 468f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::INTERP_P0, 469f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, MVT::v4f32, 470f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(slot / 4 , MVT::i32)); 471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, 472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); 473f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_x: 476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 0); 477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_y: 478f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 1); 479f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_ngroups_z: 480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 2); 481f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_x: 482f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 3); 483f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_y: 484f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 4); 485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_global_size_z: 486f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 5); 487f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_x: 488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 6); 489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_y: 490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 7); 491f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_local_size_z: 492f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return LowerImplicitParameter(DAG, VT, DL, 8); 493f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_x: 495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_X, VT); 497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_y: 498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 499f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_Y, VT); 500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tgid_z: 501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 502f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T1_Z, VT); 503f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_x: 504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 505f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_X, VT); 506f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_y: 507f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 508f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_Y, VT); 509f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case r600_read_tidig_z: 510f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, 511f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::T0_Z, VT); 512f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 513f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // break out of case ISD::INTRINSIC_WO_CHAIN in switch(Op.getOpcode()) 514f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 515f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 516f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } // end switch(Op.getOpcode()) 517f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SDValue(); 518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600TargetLowering::ReplaceNodeResults(SDNode *N, 521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<SDValue> &Results, 522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG) const { 523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (N->getOpcode()) { 524f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return; 525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG)); 526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 529f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const { 530f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode( 531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SETCC, 532f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 533f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i1, 534f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op, DAG.getConstantFP(0.0f, MVT::f32), 535f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE) 536f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ); 537f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 538f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 539f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 540f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 541f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CC = Op.getOperand(1); 542f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LHS = Op.getOperand(2); 543f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue RHS = Op.getOperand(3); 544f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue JumpT = Op.getOperand(4); 545f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CmpValue; 546f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Result; 547f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LHS.getValueType() == MVT::i32) { 549f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue = DAG.getNode( 550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 551f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i32, 553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 554f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(-1, MVT::i32), 555f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 557f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (LHS.getValueType() == MVT::f32) { 558f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue = DAG.getNode( 559f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 560f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 561f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::f32, 562f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 563f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(1.0f, MVT::f32), 564f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(0.0f, MVT::f32), 565f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 566f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 567f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(0 && "Not valid type for br_cc"); 568f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 569f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Result = DAG.getNode( 570f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUISD::BRANCH_COND, 571f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CmpValue.getDebugLoc(), 572f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::Other, Chain, 573f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard JumpT, CmpValue); 574f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Result; 575f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 576f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 577f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT, 578f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL, 579f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DwordOffset) const { 580f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ByteOffset = DwordOffset * 4; 581f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PointerType * PtrType = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 582f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUAS::PARAM_I_ADDRESS); 583f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // We shouldn't be using an offset wider than 16-bits for implicit parameters. 585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(isInt<16>(ByteOffset)); 586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getLoad(VT, DL, DAG.getEntryNode(), 588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(ByteOffset, MVT::i32), // PTR 589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachinePointerInfo(ConstantPointerNull::get(PtrType)), 590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard false, false, false, 0); 591f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 593f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const { 594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT, 598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getNode(ISD::SUB, DL, VT, 601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(32, MVT::i32), 602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(1))); 603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600TargetLowering::isZero(SDValue Op) const { 606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if(ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) { 607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Cst->isNullValue(); 608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if(ConstantFPSDNode *CstFP = dyn_cast<ConstantFPSDNode>(Op)){ 609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return CstFP->isZero(); 610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 613f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 614f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 615f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { 616f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 617f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 619f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LHS = Op.getOperand(0); 620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue RHS = Op.getOperand(1); 621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue True = Op.getOperand(2); 622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue False = Op.getOperand(3); 623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CC = Op.getOperand(4); 624f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Temp; 625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // LHS and RHS are guaranteed to be the same value type 627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT CompareVT = LHS.getValueType(); 628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Check if we can lower this to a native operation. 630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Try to lower to a CND* instruction: 632f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // CND* instructions requires RHS to be zero. Some SELECT_CC nodes that 633f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // can be lowered to CND* instructions can also be lowered to SET* 634f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instructions. CND* instructions are cheaper, because they dont't 635f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // require additional instructions to convert their result to the correct 636f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // value type, so this check should be first. 637f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isZero(LHS) || isZero(RHS)) { 638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Cond = (isZero(LHS) ? RHS : LHS); 639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Zero = (isZero(LHS) ? LHS : RHS); 640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CompareVT != VT) { 642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Bitcast True / False to the correct types. This will end up being 643f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // a nop, but it allows us to define only a single pattern in the 644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // .TD files for each CND* instruction rather than having to have 645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // one pattern for integer True/False and one for fp True/False 646f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True); 647f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False); 648f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 649f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isZero(LHS)) { 650f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode); 651f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 652f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 653f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (CCOpcode) { 654f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETONE: 655f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETUNE: 656f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETNE: 657f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETULE: 658f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETULT: 659f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETOLE: 660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETOLT: 661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETLE: 662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::SETLT: 663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32); 664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Temp = True; 665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True = False; 666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard False = Temp; 667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond, Zero, 673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True, False, 674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(CCOpcode)); 675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode); 676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Try to lower to a SET* instruction: 679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // We need all the operands of SELECT_CC to have the same value type, so if 680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // necessary we need to change True and False to be the same type as LHS and 681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // RHS, and then convert the result of the select_cc back to the correct type. 682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Move hardware True/False values to the correct operand. 684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isHWTrueValue(False) && isHWFalseValue(True)) { 685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get(); 686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::swap(False, True); 687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC = DAG.getCondCode(ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32)); 688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isHWTrueValue(True) && isHWFalseValue(False)) { 691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CompareVT != VT) { 692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (VT == MVT::f32 && CompareVT == MVT::i32) { 693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Boolean = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(-1, MVT::i32), 696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Convert integer values of true (-1) and false (0) to fp values of 699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // true (1.0f) and false (0.0f). 700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LSB = DAG.getNode(ISD::AND, DL, MVT::i32, Boolean, 701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(1, MVT::i32)); 702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::UINT_TO_FP, DL, VT, LSB); 703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (VT == MVT::i32 && CompareVT == MVT::f32) { 704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue BoolAsFlt = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, 705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 706f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(1.0f, MVT::f32), 707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(0.0f, MVT::f32), 708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Convert fp values of true (1.0f) and false (0.0f) to integer values 710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // of true (-1) and false (0). 711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Neg = DAG.getNode(ISD::FNEG, DL, MVT::f32, BoolAsFlt); 712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::FP_TO_SINT, DL, VT, Neg); 713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // I don't think there will be any other type pairings. 715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unhandled operand type parings in SELECT_CC"); 716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 717f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 718f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // This SELECT_CC is already legal. 719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC); 720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 722f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 723f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Possible Min/Max pattern 724f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue MinMax = LowerMinMax(Op, DAG); 725f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MinMax.getNode()) { 726f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MinMax; 727f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 728f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 729f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we make it this for it means we have no native instructions to handle 730f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // this SELECT_CC, so we must lower it. 731f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue HWTrue, HWFalse; 732f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 733f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (CompareVT == MVT::f32) { 734f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWTrue = DAG.getConstantFP(1.0f, CompareVT); 735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWFalse = DAG.getConstantFP(0.0f, CompareVT); 736f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (CompareVT == MVT::i32) { 737f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWTrue = DAG.getConstant(-1, CompareVT); 738f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard HWFalse = DAG.getConstant(0, CompareVT); 739f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 740f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard else { 741f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unhandled value type in LowerSELECT_CC"); 742f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 743f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 744f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Lower this unsupported SELECT_CC into a combination of two supported 745f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // SELECT_CC operations. 746f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, LHS, RHS, HWTrue, HWFalse, CC); 747f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 748f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, DL, VT, 749f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond, HWFalse, 750f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard True, False, 751f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE)); 752f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 753f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 754f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { 755f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::SELECT_CC, 756f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 757f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getValueType(), 758f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(0), 759f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 760f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(1), 761f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getOperand(2), 762f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getCondCode(ISD::SETNE)); 763f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 764f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 765f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 766f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Cond; 767f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LHS = Op.getOperand(0); 768f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue RHS = Op.getOperand(1); 769f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue CC = Op.getOperand(2); 770f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 771f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(Op.getValueType() == MVT::i32); 772f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LHS.getValueType() == MVT::i32) { 773f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond = DAG.getNode( 774f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 775f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 776f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i32, 777f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 778f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(-1, MVT::i32), 779f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(0, MVT::i32), 780f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 781f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (LHS.getValueType() == MVT::f32) { 782f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond = DAG.getNode( 783f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::SELECT_CC, 784f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Op.getDebugLoc(), 785f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::f32, 786f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LHS, RHS, 787f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(1.0f, MVT::f32), 788f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstantFP(0.0f, MVT::f32), 789f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CC); 790f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond = DAG.getNode( 791f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::FP_TO_SINT, 792f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, 793f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i32, 794f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond); 795f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 796f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(0 && "Not valid type for set_cc"); 797f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 798f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond = DAG.getNode( 799f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ISD::AND, 800f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DL, 801f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MVT::i32, 802f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(1, MVT::i32), 803f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond); 804f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Cond; 805f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 806f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 807f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const { 808f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 809f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard StoreSDNode *StoreNode = cast<StoreSDNode>(Op); 810f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain = Op.getOperand(0); 811f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Value = Op.getOperand(1); 812f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Ptr = Op.getOperand(2); 813f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 814f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (StoreNode->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && 815f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr->getOpcode() != AMDGPUISD::DWORDADDR) { 816f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Convert pointer from byte address to dword address. 817f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, Ptr.getValueType(), 818f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getNode(ISD::SRL, DL, Ptr.getValueType(), 819f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Ptr, DAG.getConstant(2, MVT::i32))); 820f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 821f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (StoreNode->isTruncatingStore() || StoreNode->isIndexed()) { 822f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Truncated and indexed stores not supported yet"); 823f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 824f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Chain = DAG.getStore(Chain, DL, Value, Ptr, StoreNode->getMemOperand()); 825f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 826f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Chain; 827f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 828f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SDValue(); 829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 830f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 831f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 832f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFPOW(SDValue Op, 833f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG) const { 834f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL = Op.getDebugLoc(); 835f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Op.getValueType(); 836f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue LogBase = DAG.getNode(ISD::FLOG2, DL, VT, Op.getOperand(0)); 837f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue MulLogBase = DAG.getNode(ISD::FMUL, DL, VT, Op.getOperand(1), LogBase); 838f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::FEXP2, DL, VT, MulLogBase); 839f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 840f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 841f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// XXX Only kernel functions are supported, so we can assume for now that 842f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// every function is a kernel function, but in the future we should use 843f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// separate calling conventions for kernel and non-kernel functions. 844f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFormalArguments( 845f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Chain, 846f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CallingConv::ID CallConv, 847f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool isVarArg, 848f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<ISD::InputArg> &Ins, 849f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL, SelectionDAG &DAG, 850f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<SDValue> &InVals) const { 851f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ParamOffsetBytes = 36; 852f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Function::const_arg_iterator FuncArg = 853f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getMachineFunction().getFunction()->arg_begin(); 854f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0, e = Ins.size(); i < e; ++i, ++FuncArg) { 855f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT VT = Ins[i].VT; 856f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Type *ArgType = FuncArg->getType(); 857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ArgSizeInBits = ArgType->isPointerTy() ? 858f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 32 : ArgType->getPrimitiveSizeInBits(); 859f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ArgBytes = ArgSizeInBits >> 3; 860f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EVT ArgVT; 861f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (ArgSizeInBits < VT.getSizeInBits()) { 862f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!ArgType->isFloatTy() && 863f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Extending floating point arguments not supported yet"); 864f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT = MVT::getIntegerVT(ArgSizeInBits); 865f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT = VT; 867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PointerType *PtrTy = PointerType::get(VT.getTypeForEVT(*DAG.getContext()), 869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUAS::PARAM_I_ADDRESS); 870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Arg = DAG.getExtLoad(ISD::ZEXTLOAD, DL, VT, DAG.getRoot(), 871f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAG.getConstant(ParamOffsetBytes, MVT::i32), 872f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachinePointerInfo(new Argument(PtrTy)), 873f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ArgVT, false, false, ArgBytes); 874f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InVals.push_back(Arg); 875f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ParamOffsetBytes += ArgBytes; 876f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 877f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Chain; 878f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 879f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 880f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardEVT R600TargetLowering::getSetCCResultType(EVT VT) const { 881f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!VT.isVector()) return MVT::i32; 882f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return VT.changeVectorElementTypeToInteger(); 883f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 884f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 885f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 886f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Optimizations 887f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 888f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 889f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::PerformDAGCombine(SDNode *N, 890f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DAGCombinerInfo &DCI) const { 891f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SelectionDAG &DAG = DCI.DAG; 892f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 893f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (N->getOpcode()) { 894f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // (f32 fp_round (f64 uint_to_fp a)) -> (f32 uint_to_fp a) 895f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case ISD::FP_ROUND: { 896f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SDValue Arg = N->getOperand(0); 897f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Arg.getOpcode() == ISD::UINT_TO_FP && Arg.getValueType() == MVT::f64) { 898f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), N->getValueType(0), 899f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Arg.getOperand(0)); 900f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 901f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 902f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 903f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 904f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return SDValue(); 905f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 906