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