1 //===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Most of the DAG lowering is handled in AMDGPUISelLowering.cpp. This file
11 // is mostly EmitInstrWithCustomInserter().
13 //===----------------------------------------------------------------------===//
15 #include "R600ISelLowering.h"
16 #include "AMDGPUUtil.h"
17 #include "R600InstrInfo.h"
18 #include "R600MachineFunctionInfo.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
24 AMDGPUTargetLowering(TM),
25 TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
27 setOperationAction(ISD::MUL, MVT::i64, Expand);
28 addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass);
29 addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass);
30 addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass);
31 addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass);
32 computeRegisterProperties();
34 setOperationAction(ISD::FSUB, MVT::f32, Expand);
36 setOperationAction(ISD::ROTL, MVT::i32, Custom);
38 setSchedulingPreference(Sched::VLIW);
41 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
42 MachineInstr * MI, MachineBasicBlock * BB) const
44 MachineFunction * MF = BB->getParent();
45 MachineRegisterInfo &MRI = MF->getRegInfo();
46 MachineBasicBlock::iterator I = *MI;
48 switch (MI->getOpcode()) {
49 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
51 addLiveIn(MI, MF, MRI, TII, AMDGPU::T1_X);
54 addLiveIn(MI, MF, MRI, TII, AMDGPU::T1_Y);
57 addLiveIn(MI, MF, MRI, TII, AMDGPU::T1_Z);
60 addLiveIn(MI, MF, MRI, TII, AMDGPU::T0_X);
63 addLiveIn(MI, MF, MRI, TII, AMDGPU::T0_Y);
66 addLiveIn(MI, MF, MRI, TII, AMDGPU::T0_Z);
68 case AMDGPU::NGROUPS_X:
69 lowerImplicitParameter(MI, *BB, MRI, 0);
71 case AMDGPU::NGROUPS_Y:
72 lowerImplicitParameter(MI, *BB, MRI, 1);
74 case AMDGPU::NGROUPS_Z:
75 lowerImplicitParameter(MI, *BB, MRI, 2);
77 case AMDGPU::GLOBAL_SIZE_X:
78 lowerImplicitParameter(MI, *BB, MRI, 3);
80 case AMDGPU::GLOBAL_SIZE_Y:
81 lowerImplicitParameter(MI, *BB, MRI, 4);
83 case AMDGPU::GLOBAL_SIZE_Z:
84 lowerImplicitParameter(MI, *BB, MRI, 5);
86 case AMDGPU::LOCAL_SIZE_X:
87 lowerImplicitParameter(MI, *BB, MRI, 6);
89 case AMDGPU::LOCAL_SIZE_Y:
90 lowerImplicitParameter(MI, *BB, MRI, 7);
92 case AMDGPU::LOCAL_SIZE_Z:
93 lowerImplicitParameter(MI, *BB, MRI, 8);
96 case AMDGPU::CLAMP_R600:
97 MI->getOperand(0).addTargetFlag(MO_FLAG_CLAMP);
98 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
99 .addOperand(MI->getOperand(0))
100 .addOperand(MI->getOperand(1));
103 case AMDGPU::FABS_R600:
104 MI->getOperand(1).addTargetFlag(MO_FLAG_ABS);
105 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
106 .addOperand(MI->getOperand(0))
107 .addOperand(MI->getOperand(1));
110 case AMDGPU::FNEG_R600:
111 MI->getOperand(1).addTargetFlag(MO_FLAG_NEG);
112 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
113 .addOperand(MI->getOperand(0))
114 .addOperand(MI->getOperand(1));
117 case AMDGPU::R600_LOAD_CONST:
119 int64_t RegIndex = MI->getOperand(1).getImm();
120 unsigned ConstantReg = AMDGPU::R600_CReg32RegClass.getRegister(RegIndex);
121 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::COPY))
122 .addOperand(MI->getOperand(0))
123 .addReg(ConstantReg);
127 case AMDGPU::LOAD_INPUT:
129 int64_t RegIndex = MI->getOperand(1).getImm();
130 addLiveIn(MI, MF, MRI, TII,
131 AMDGPU::R600_TReg32RegClass.getRegister(RegIndex));
135 case AMDGPU::MASK_WRITE:
137 unsigned maskedRegister = MI->getOperand(0).getReg();
138 assert(TargetRegisterInfo::isVirtualRegister(maskedRegister));
139 MachineInstr * defInstr = MRI.getVRegDef(maskedRegister);
140 MachineOperand * def = defInstr->findRegisterDefOperand(maskedRegister);
141 def->addTargetFlag(MO_FLAG_MASK);
142 // Return early so the instruction is not erased
146 case AMDGPU::RAT_WRITE_CACHELESS_eg:
148 // Convert to DWORD address
149 unsigned NewAddr = MRI.createVirtualRegister(
150 &AMDGPU::R600_TReg32_XRegClass);
151 unsigned ShiftValue = MRI.createVirtualRegister(
152 &AMDGPU::R600_TReg32RegClass);
154 // XXX In theory, we should be able to pass ShiftValue directly to
155 // the LSHR_eg instruction as an inline literal, but I tried doing it
156 // this way and it didn't produce the correct results.
157 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV), ShiftValue)
158 .addReg(AMDGPU::ALU_LITERAL_X)
160 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::LSHR_eg), NewAddr)
161 .addOperand(MI->getOperand(1))
163 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
164 .addOperand(MI->getOperand(0))
169 case AMDGPU::STORE_OUTPUT:
171 int64_t OutputIndex = MI->getOperand(1).getImm();
172 unsigned OutputReg = AMDGPU::R600_TReg32RegClass.getRegister(OutputIndex);
174 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::COPY), OutputReg)
175 .addOperand(MI->getOperand(0));
177 if (!MRI.isLiveOut(OutputReg)) {
178 MRI.addLiveOut(OutputReg);
183 case AMDGPU::RESERVE_REG:
185 R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>();
186 int64_t ReservedIndex = MI->getOperand(0).getImm();
187 unsigned ReservedReg =
188 AMDGPU::R600_TReg32RegClass.getRegister(ReservedIndex);
189 MFI->ReservedRegs.push_back(ReservedReg);
195 unsigned t0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
196 unsigned t1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
198 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), t0)
199 .addOperand(MI->getOperand(3))
200 .addOperand(MI->getOperand(4))
201 .addOperand(MI->getOperand(5));
202 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), t1)
203 .addOperand(MI->getOperand(2))
204 .addOperand(MI->getOperand(4))
205 .addOperand(MI->getOperand(5));
206 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G))
207 .addOperand(MI->getOperand(0))
208 .addOperand(MI->getOperand(1))
209 .addOperand(MI->getOperand(4))
210 .addOperand(MI->getOperand(5))
211 .addReg(t0, RegState::Implicit)
212 .addReg(t1, RegState::Implicit);
215 case AMDGPU::TXD_SHADOW:
217 unsigned t0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
218 unsigned t1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
220 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), t0)
221 .addOperand(MI->getOperand(3))
222 .addOperand(MI->getOperand(4))
223 .addOperand(MI->getOperand(5));
224 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), t1)
225 .addOperand(MI->getOperand(2))
226 .addOperand(MI->getOperand(4))
227 .addOperand(MI->getOperand(5));
228 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G))
229 .addOperand(MI->getOperand(0))
230 .addOperand(MI->getOperand(1))
231 .addOperand(MI->getOperand(4))
232 .addOperand(MI->getOperand(5))
233 .addReg(t0, RegState::Implicit)
234 .addReg(t1, RegState::Implicit);
241 MI->eraseFromParent();
245 void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
246 MachineRegisterInfo & MRI, unsigned dword_offset) const
248 MachineBasicBlock::iterator I = *MI;
249 unsigned PtrReg = MRI.createVirtualRegister(&AMDGPU::R600_TReg32_XRegClass);
250 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDGPU::R600_TReg32_XRegClass);
252 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::MOV), PtrReg)
253 .addReg(AMDGPU::ALU_LITERAL_X)
254 .addImm(dword_offset * 4);
256 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::VTX_READ_PARAM_i32_eg))
257 .addOperand(MI->getOperand(0))
262 //===----------------------------------------------------------------------===//
263 // Custom DAG Lowering Operations
264 //===----------------------------------------------------------------------===//
267 SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
269 switch (Op.getOpcode()) {
270 default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
271 case ISD::ROTL: return LowerROTL(Op, DAG);
275 SDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const
277 DebugLoc DL = Op.getDebugLoc();
278 EVT VT = Op.getValueType();
280 return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT,
283 DAG.getNode(ISD::SUB, DL, VT,
284 DAG.getConstant(32, MVT::i32),