radeon/llvm: add SET_GRADIENTS*, fix SAMPLE_G
[mesa.git] / src / gallium / drivers / radeon / R600ISelLowering.cpp
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
20 using namespace llvm;
21
22 R600TargetLowering::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
39 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
40 MachineInstr * MI, MachineBasicBlock * BB) const
41 {
42 MachineFunction * MF = BB->getParent();
43 MachineRegisterInfo &MRI = MF->getRegInfo();
44 MachineBasicBlock::iterator I = *MI;
45
46 switch (MI->getOpcode()) {
47 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
48 case AMDIL::TGID_X:
49 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X);
50 break;
51 case AMDIL::TGID_Y:
52 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y);
53 break;
54 case AMDIL::TGID_Z:
55 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z);
56 break;
57 case AMDIL::TIDIG_X:
58 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X);
59 break;
60 case AMDIL::TIDIG_Y:
61 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y);
62 break;
63 case AMDIL::TIDIG_Z:
64 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z);
65 break;
66 case AMDIL::NGROUPS_X:
67 lowerImplicitParameter(MI, *BB, MRI, 0);
68 break;
69 case AMDIL::NGROUPS_Y:
70 lowerImplicitParameter(MI, *BB, MRI, 1);
71 break;
72 case AMDIL::NGROUPS_Z:
73 lowerImplicitParameter(MI, *BB, MRI, 2);
74 break;
75 case AMDIL::GLOBAL_SIZE_X:
76 lowerImplicitParameter(MI, *BB, MRI, 3);
77 break;
78 case AMDIL::GLOBAL_SIZE_Y:
79 lowerImplicitParameter(MI, *BB, MRI, 4);
80 break;
81 case AMDIL::GLOBAL_SIZE_Z:
82 lowerImplicitParameter(MI, *BB, MRI, 5);
83 break;
84 case AMDIL::LOCAL_SIZE_X:
85 lowerImplicitParameter(MI, *BB, MRI, 6);
86 break;
87 case AMDIL::LOCAL_SIZE_Y:
88 lowerImplicitParameter(MI, *BB, MRI, 7);
89 break;
90 case AMDIL::LOCAL_SIZE_Z:
91 lowerImplicitParameter(MI, *BB, MRI, 8);
92 break;
93
94 case AMDIL::R600_LOAD_CONST:
95 {
96 int64_t RegIndex = MI->getOperand(1).getImm();
97 unsigned ConstantReg = AMDIL::R600_CReg32RegClass.getRegister(RegIndex);
98 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY))
99 .addOperand(MI->getOperand(0))
100 .addReg(ConstantReg);
101 break;
102 }
103
104 case AMDIL::LOAD_INPUT:
105 {
106 int64_t RegIndex = MI->getOperand(1).getImm();
107 addLiveIn(MI, MF, MRI, TII,
108 AMDIL::R600_TReg32RegClass.getRegister(RegIndex));
109 break;
110 }
111 case AMDIL::STORE_OUTPUT:
112 {
113 int64_t OutputIndex = MI->getOperand(1).getImm();
114 unsigned OutputReg = AMDIL::R600_TReg32RegClass.getRegister(OutputIndex);
115
116 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY), OutputReg)
117 .addOperand(MI->getOperand(0));
118
119 if (!MRI.isLiveOut(OutputReg)) {
120 MRI.addLiveOut(OutputReg);
121 }
122 break;
123 }
124
125 case AMDIL::RESERVE_REG:
126 {
127 R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>();
128 int64_t ReservedIndex = MI->getOperand(0).getImm();
129 unsigned ReservedReg =
130 AMDIL::R600_TReg32RegClass.getRegister(ReservedIndex);
131 MFI->ReservedRegs.push_back(ReservedReg);
132 break;
133 }
134
135 case AMDIL::TXD:
136 {
137 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
138 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
139
140 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0)
141 .addOperand(MI->getOperand(3))
142 .addOperand(MI->getOperand(4))
143 .addOperand(MI->getOperand(5));
144 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1)
145 .addOperand(MI->getOperand(2))
146 .addOperand(MI->getOperand(4))
147 .addOperand(MI->getOperand(5));
148 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_G))
149 .addOperand(MI->getOperand(0))
150 .addOperand(MI->getOperand(1))
151 .addOperand(MI->getOperand(4))
152 .addOperand(MI->getOperand(5))
153 .addReg(t0, RegState::Implicit)
154 .addReg(t1, RegState::Implicit);
155 break;
156 }
157 case AMDIL::TXD_SHADOW:
158 {
159 unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
160 unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
161
162 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0)
163 .addOperand(MI->getOperand(3))
164 .addOperand(MI->getOperand(4))
165 .addOperand(MI->getOperand(5));
166 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1)
167 .addOperand(MI->getOperand(2))
168 .addOperand(MI->getOperand(4))
169 .addOperand(MI->getOperand(5));
170 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_C_G))
171 .addOperand(MI->getOperand(0))
172 .addOperand(MI->getOperand(1))
173 .addOperand(MI->getOperand(4))
174 .addOperand(MI->getOperand(5))
175 .addReg(t0, RegState::Implicit)
176 .addReg(t1, RegState::Implicit);
177 break;
178 }
179
180
181 }
182
183 MI->eraseFromParent();
184 return BB;
185 }
186
187 void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
188 MachineRegisterInfo & MRI, unsigned dword_offset) const
189 {
190 MachineBasicBlock::iterator I = *MI;
191 unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
192 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass);
193
194 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg)
195 .addReg(AMDIL::ALU_LITERAL_X)
196 .addImm(dword_offset * 4);
197
198 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg))
199 .addOperand(MI->getOperand(0))
200 .addReg(offsetReg)
201 .addImm(0);
202 }