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