R600ISelLowering.cpp revision 467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2
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 "AMDGPUUtil.h" 17#include "R600InstrInfo.h" 18#include "R600MachineFunctionInfo.h" 19#include "llvm/CodeGen/MachineRegisterInfo.h" 20 21using namespace llvm; 22 23R600TargetLowering::R600TargetLowering(TargetMachine &TM) : 24 AMDGPUTargetLowering(TM), 25 TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo())) 26{ 27 setOperationAction(ISD::MUL, MVT::i64, Expand); 28// setSchedulingPreference(Sched::VLIW); 29 addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass); 30 addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass); 31 addRegisterClass(MVT::v4i32, &AMDIL::R600_Reg128RegClass); 32 addRegisterClass(MVT::i32, &AMDIL::R600_Reg32RegClass); 33 computeRegisterProperties(); 34 35 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal); 36 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal); 37 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal); 38 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal); 39 40 setOperationAction(ISD::FSUB, MVT::f32, Expand); 41 42#if 0 43 44 setTargetDAGCombine(ISD::Constant); 45 setTargetDAGCombine(ISD::ConstantFP); 46 47#endif 48} 49 50MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( 51 MachineInstr * MI, MachineBasicBlock * BB) const 52{ 53 MachineFunction * MF = BB->getParent(); 54 MachineRegisterInfo &MRI = MF->getRegInfo(); 55 MachineBasicBlock::iterator I = *MI; 56 57 switch (MI->getOpcode()) { 58 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 59 case AMDIL::TGID_X: 60 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X); 61 break; 62 case AMDIL::TGID_Y: 63 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y); 64 break; 65 case AMDIL::TGID_Z: 66 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z); 67 break; 68 case AMDIL::TIDIG_X: 69 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X); 70 break; 71 case AMDIL::TIDIG_Y: 72 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y); 73 break; 74 case AMDIL::TIDIG_Z: 75 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z); 76 break; 77 case AMDIL::NGROUPS_X: 78 lowerImplicitParameter(MI, *BB, MRI, 0); 79 break; 80 case AMDIL::NGROUPS_Y: 81 lowerImplicitParameter(MI, *BB, MRI, 1); 82 break; 83 case AMDIL::NGROUPS_Z: 84 lowerImplicitParameter(MI, *BB, MRI, 2); 85 break; 86 case AMDIL::GLOBAL_SIZE_X: 87 lowerImplicitParameter(MI, *BB, MRI, 3); 88 break; 89 case AMDIL::GLOBAL_SIZE_Y: 90 lowerImplicitParameter(MI, *BB, MRI, 4); 91 break; 92 case AMDIL::GLOBAL_SIZE_Z: 93 lowerImplicitParameter(MI, *BB, MRI, 5); 94 break; 95 case AMDIL::LOCAL_SIZE_X: 96 lowerImplicitParameter(MI, *BB, MRI, 6); 97 break; 98 case AMDIL::LOCAL_SIZE_Y: 99 lowerImplicitParameter(MI, *BB, MRI, 7); 100 break; 101 case AMDIL::LOCAL_SIZE_Z: 102 lowerImplicitParameter(MI, *BB, MRI, 8); 103 break; 104 105 case AMDIL::CLAMP_R600: 106 MI->getOperand(0).addTargetFlag(MO_FLAG_CLAMP); 107 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV)) 108 .addOperand(MI->getOperand(0)) 109 .addOperand(MI->getOperand(1)); 110 break; 111 112 case AMDIL::FABS_R600: 113 MI->getOperand(1).addTargetFlag(MO_FLAG_ABS); 114 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV)) 115 .addOperand(MI->getOperand(0)) 116 .addOperand(MI->getOperand(1)); 117 break; 118 119 case AMDIL::FNEG_R600: 120 MI->getOperand(1).addTargetFlag(MO_FLAG_NEG); 121 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV)) 122 .addOperand(MI->getOperand(0)) 123 .addOperand(MI->getOperand(1)); 124 break; 125 126 case AMDIL::R600_LOAD_CONST: 127 { 128 int64_t RegIndex = MI->getOperand(1).getImm(); 129 unsigned ConstantReg = AMDIL::R600_CReg32RegClass.getRegister(RegIndex); 130 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY)) 131 .addOperand(MI->getOperand(0)) 132 .addReg(ConstantReg); 133 break; 134 } 135 136 case AMDIL::LOAD_INPUT: 137 { 138 int64_t RegIndex = MI->getOperand(1).getImm(); 139 addLiveIn(MI, MF, MRI, TII, 140 AMDIL::R600_TReg32RegClass.getRegister(RegIndex)); 141 break; 142 } 143 144 case AMDIL::MASK_WRITE: 145 { 146 unsigned maskedRegister = MI->getOperand(0).getReg(); 147 assert(TargetRegisterInfo::isVirtualRegister(maskedRegister)); 148 MachineInstr * defInstr = MRI.getVRegDef(maskedRegister); 149 MachineOperand * def = defInstr->findRegisterDefOperand(maskedRegister); 150 def->addTargetFlag(MO_FLAG_MASK); 151 // Return early so the instruction is not erased 152 return BB; 153 } 154 155 case AMDIL::STORE_OUTPUT: 156 { 157 int64_t OutputIndex = MI->getOperand(1).getImm(); 158 unsigned OutputReg = AMDIL::R600_TReg32RegClass.getRegister(OutputIndex); 159 160 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY), OutputReg) 161 .addOperand(MI->getOperand(0)); 162 163 if (!MRI.isLiveOut(OutputReg)) { 164 MRI.addLiveOut(OutputReg); 165 } 166 break; 167 } 168 169 case AMDIL::RESERVE_REG: 170 { 171 R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>(); 172 int64_t ReservedIndex = MI->getOperand(0).getImm(); 173 unsigned ReservedReg = 174 AMDIL::R600_TReg32RegClass.getRegister(ReservedIndex); 175 MFI->ReservedRegs.push_back(ReservedReg); 176 break; 177 } 178 179 case AMDIL::TXD: 180 { 181 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 182 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 183 184 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0) 185 .addOperand(MI->getOperand(3)) 186 .addOperand(MI->getOperand(4)) 187 .addOperand(MI->getOperand(5)); 188 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1) 189 .addOperand(MI->getOperand(2)) 190 .addOperand(MI->getOperand(4)) 191 .addOperand(MI->getOperand(5)); 192 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_G)) 193 .addOperand(MI->getOperand(0)) 194 .addOperand(MI->getOperand(1)) 195 .addOperand(MI->getOperand(4)) 196 .addOperand(MI->getOperand(5)) 197 .addReg(t0, RegState::Implicit) 198 .addReg(t1, RegState::Implicit); 199 break; 200 } 201 case AMDIL::TXD_SHADOW: 202 { 203 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 204 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass); 205 206 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0) 207 .addOperand(MI->getOperand(3)) 208 .addOperand(MI->getOperand(4)) 209 .addOperand(MI->getOperand(5)); 210 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1) 211 .addOperand(MI->getOperand(2)) 212 .addOperand(MI->getOperand(4)) 213 .addOperand(MI->getOperand(5)); 214 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_C_G)) 215 .addOperand(MI->getOperand(0)) 216 .addOperand(MI->getOperand(1)) 217 .addOperand(MI->getOperand(4)) 218 .addOperand(MI->getOperand(5)) 219 .addReg(t0, RegState::Implicit) 220 .addReg(t1, RegState::Implicit); 221 break; 222 } 223 224 225 } 226 227 MI->eraseFromParent(); 228 return BB; 229} 230 231void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB, 232 MachineRegisterInfo & MRI, unsigned dword_offset) const 233{ 234 MachineBasicBlock::iterator I = *MI; 235 unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass); 236 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass); 237 238 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg) 239 .addReg(AMDIL::ALU_LITERAL_X) 240 .addImm(dword_offset * 4); 241 242 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg)) 243 .addOperand(MI->getOperand(0)) 244 .addReg(offsetReg) 245 .addImm(0); 246} 247