R600ISelLowering.cpp revision 1fe70c6ae12e85cdb5967ba6d72fca8a9e5c3ec3
1//===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Most of the DAG lowering is handled in AMDILISelLowering.cpp. This file 11// is mostly EmitInstrWithCustomInserter(). 12// 13//===----------------------------------------------------------------------===// 14 15#include "R600ISelLowering.h" 16#include "R600InstrInfo.h" 17#include "R600MachineFunctionInfo.h" 18#include "llvm/CodeGen/MachineRegisterInfo.h" 19 20using namespace llvm; 21 22R600TargetLowering::R600TargetLowering(TargetMachine &TM) : 23 AMDGPUTargetLowering(TM), 24 TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) 25{ 26 setOperationAction(ISD::MUL, MVT::i64, Expand); 27// setSchedulingPreference(Sched::VLIW); 28 addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass); 29 addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass); 30 addRegisterClass(MVT::v4i32, &AMDIL::R600_Reg128RegClass); 31 addRegisterClass(MVT::i32, &AMDIL::R600_Reg32RegClass); 32 33 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal); 34 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal); 35 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal); 36 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal); 37 38 setOperationAction(ISD::FSUB, MVT::f32, Expand); 39} 40 41MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( 42 MachineInstr * MI, MachineBasicBlock * BB) const 43{ 44 MachineFunction * MF = BB->getParent(); 45 MachineRegisterInfo &MRI = MF->getRegInfo(); 46 MachineBasicBlock::iterator I = *MI; 47 48 switch (MI->getOpcode()) { 49 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 50 case AMDIL::TGID_X: 51 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X); 52 break; 53 case AMDIL::TGID_Y: 54 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y); 55 break; 56 case AMDIL::TGID_Z: 57 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z); 58 break; 59 case AMDIL::TIDIG_X: 60 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X); 61 break; 62 case AMDIL::TIDIG_Y: 63 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y); 64 break; 65 case AMDIL::TIDIG_Z: 66 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z); 67 break; 68 case AMDIL::NGROUPS_X: 69 lowerImplicitParameter(MI, *BB, MRI, 0); 70 break; 71 case AMDIL::NGROUPS_Y: 72 lowerImplicitParameter(MI, *BB, MRI, 1); 73 break; 74 case AMDIL::NGROUPS_Z: 75 lowerImplicitParameter(MI, *BB, MRI, 2); 76 break; 77 case AMDIL::GLOBAL_SIZE_X: 78 lowerImplicitParameter(MI, *BB, MRI, 3); 79 break; 80 case AMDIL::GLOBAL_SIZE_Y: 81 lowerImplicitParameter(MI, *BB, MRI, 4); 82 break; 83 case AMDIL::GLOBAL_SIZE_Z: 84 lowerImplicitParameter(MI, *BB, MRI, 5); 85 break; 86 case AMDIL::LOCAL_SIZE_X: 87 lowerImplicitParameter(MI, *BB, MRI, 6); 88 break; 89 case AMDIL::LOCAL_SIZE_Y: 90 lowerImplicitParameter(MI, *BB, MRI, 7); 91 break; 92 case AMDIL::LOCAL_SIZE_Z: 93 lowerImplicitParameter(MI, *BB, MRI, 8); 94 break; 95 96 case AMDIL::R600_LOAD_CONST: 97 { 98 int64_t RegIndex = MI->getOperand(1).getImm(); 99 unsigned ConstantReg = AMDIL::R600_CReg32RegClass.getRegister(RegIndex); 100 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY)) 101 .addOperand(MI->getOperand(0)) 102 .addReg(ConstantReg); 103 break; 104 } 105 106 case AMDIL::LOAD_INPUT: 107 { 108 int64_t RegIndex = MI->getOperand(1).getImm(); 109 addLiveIn(MI, MF, MRI, TII, 110 AMDIL::R600_TReg32RegClass.getRegister(RegIndex)); 111 break; 112 } 113 case AMDIL::STORE_OUTPUT: 114 { 115 int64_t OutputIndex = MI->getOperand(1).getImm(); 116 unsigned OutputReg = AMDIL::R600_TReg32RegClass.getRegister(OutputIndex); 117 118 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY), OutputReg) 119 .addOperand(MI->getOperand(0)); 120 121 if (!MRI.isLiveOut(OutputReg)) { 122 MRI.addLiveOut(OutputReg); 123 } 124 break; 125 } 126 127 case AMDIL::RESERVE_REG: 128 { 129 R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>(); 130 int64_t ReservedIndex = MI->getOperand(0).getImm(); 131 unsigned ReservedReg = 132 AMDIL::R600_TReg32RegClass.getRegister(ReservedIndex); 133 MFI->ReservedRegs.push_back(ReservedReg); 134 break; 135 } 136 137 case AMDIL::TXD: 138 { 139 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 140 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 141 142 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0) 143 .addOperand(MI->getOperand(3)) 144 .addOperand(MI->getOperand(4)) 145 .addOperand(MI->getOperand(5)); 146 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1) 147 .addOperand(MI->getOperand(2)) 148 .addOperand(MI->getOperand(4)) 149 .addOperand(MI->getOperand(5)); 150 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_G)) 151 .addOperand(MI->getOperand(0)) 152 .addOperand(MI->getOperand(1)) 153 .addOperand(MI->getOperand(4)) 154 .addOperand(MI->getOperand(5)) 155 .addReg(t0, RegState::Implicit) 156 .addReg(t1, RegState::Implicit); 157 break; 158 } 159 case AMDIL::TXD_SHADOW: 160 { 161 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 162 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 163 164 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0) 165 .addOperand(MI->getOperand(3)) 166 .addOperand(MI->getOperand(4)) 167 .addOperand(MI->getOperand(5)); 168 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1) 169 .addOperand(MI->getOperand(2)) 170 .addOperand(MI->getOperand(4)) 171 .addOperand(MI->getOperand(5)); 172 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_C_G)) 173 .addOperand(MI->getOperand(0)) 174 .addOperand(MI->getOperand(1)) 175 .addOperand(MI->getOperand(4)) 176 .addOperand(MI->getOperand(5)) 177 .addReg(t0, RegState::Implicit) 178 .addReg(t1, RegState::Implicit); 179 break; 180 } 181 182 183 } 184 185 MI->eraseFromParent(); 186 return BB; 187} 188 189void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB, 190 MachineRegisterInfo & MRI, unsigned dword_offset) const 191{ 192 MachineBasicBlock::iterator I = *MI; 193 unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass); 194 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass); 195 196 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg) 197 .addReg(AMDIL::ALU_LITERAL_X) 198 .addImm(dword_offset * 4); 199 200 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg)) 201 .addOperand(MI->getOperand(0)) 202 .addReg(offsetReg) 203 .addImm(0); 204} 205