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