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