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 // 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();
35 setOperationAction(ISD::FSUB
, MVT::f32
, Expand
);
39 MachineBasicBlock
* R600TargetLowering::EmitInstrWithCustomInserter(
40 MachineInstr
* MI
, MachineBasicBlock
* BB
) const
42 MachineFunction
* MF
= BB
->getParent();
43 MachineRegisterInfo
&MRI
= MF
->getRegInfo();
44 MachineBasicBlock::iterator I
= *MI
;
46 switch (MI
->getOpcode()) {
47 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI
, BB
);
49 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T1_X
);
52 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T1_Y
);
55 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T1_Z
);
58 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T0_X
);
61 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T0_Y
);
64 addLiveIn(MI
, MF
, MRI
, TII
, AMDIL::T0_Z
);
66 case AMDIL::NGROUPS_X
:
67 lowerImplicitParameter(MI
, *BB
, MRI
, 0);
69 case AMDIL::NGROUPS_Y
:
70 lowerImplicitParameter(MI
, *BB
, MRI
, 1);
72 case AMDIL::NGROUPS_Z
:
73 lowerImplicitParameter(MI
, *BB
, MRI
, 2);
75 case AMDIL::GLOBAL_SIZE_X
:
76 lowerImplicitParameter(MI
, *BB
, MRI
, 3);
78 case AMDIL::GLOBAL_SIZE_Y
:
79 lowerImplicitParameter(MI
, *BB
, MRI
, 4);
81 case AMDIL::GLOBAL_SIZE_Z
:
82 lowerImplicitParameter(MI
, *BB
, MRI
, 5);
84 case AMDIL::LOCAL_SIZE_X
:
85 lowerImplicitParameter(MI
, *BB
, MRI
, 6);
87 case AMDIL::LOCAL_SIZE_Y
:
88 lowerImplicitParameter(MI
, *BB
, MRI
, 7);
90 case AMDIL::LOCAL_SIZE_Z
:
91 lowerImplicitParameter(MI
, *BB
, MRI
, 8);
94 case AMDIL::CLAMP_R600
:
95 MI
->getOperand(0).addTargetFlag(MO_FLAG_CLAMP
);
96 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::MOV
))
97 .addOperand(MI
->getOperand(0))
98 .addOperand(MI
->getOperand(1));
101 case AMDIL::FABS_R600
:
102 MI
->getOperand(1).addTargetFlag(MO_FLAG_ABS
);
103 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::MOV
))
104 .addOperand(MI
->getOperand(0))
105 .addOperand(MI
->getOperand(1));
108 case AMDIL::FNEG_R600
:
109 MI
->getOperand(1).addTargetFlag(MO_FLAG_NEG
);
110 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::MOV
))
111 .addOperand(MI
->getOperand(0))
112 .addOperand(MI
->getOperand(1));
115 case AMDIL::R600_LOAD_CONST
:
117 int64_t RegIndex
= MI
->getOperand(1).getImm();
118 unsigned ConstantReg
= AMDIL::R600_CReg32RegClass
.getRegister(RegIndex
);
119 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::COPY
))
120 .addOperand(MI
->getOperand(0))
121 .addReg(ConstantReg
);
125 case AMDIL::LOAD_INPUT
:
127 int64_t RegIndex
= MI
->getOperand(1).getImm();
128 addLiveIn(MI
, MF
, MRI
, TII
,
129 AMDIL::R600_TReg32RegClass
.getRegister(RegIndex
));
133 case AMDIL::MASK_WRITE
:
135 unsigned maskedRegister
= MI
->getOperand(0).getReg();
136 assert(TargetRegisterInfo::isVirtualRegister(maskedRegister
));
137 MachineInstr
* defInstr
= MRI
.getVRegDef(maskedRegister
);
138 MachineOperand
* def
= defInstr
->findRegisterDefOperand(maskedRegister
);
139 def
->addTargetFlag(MO_FLAG_MASK
);
140 // Return early so the instruction is not erased
144 case AMDIL::RAT_WRITE_CACHELESS_eg
:
146 // Convert to DWORD address
147 unsigned NewAddr
= MRI
.createVirtualRegister(
148 AMDIL::R600_TReg32_XRegisterClass
);
149 unsigned ShiftValue
= MRI
.createVirtualRegister(
150 AMDIL::R600_TReg32RegisterClass
);
152 // XXX In theory, we should be able to pass ShiftValue directly to
153 // the LSHR_eg instruction as an inline literal, but I tried doing it
154 // this way and it didn't produce the correct results.
155 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::MOV
), ShiftValue
)
156 .addReg(AMDIL::ALU_LITERAL_X
)
158 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::LSHR_eg
), NewAddr
)
159 .addOperand(MI
->getOperand(1))
161 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(MI
->getOpcode()))
162 .addOperand(MI
->getOperand(0))
167 case AMDIL::STORE_OUTPUT
:
169 int64_t OutputIndex
= MI
->getOperand(1).getImm();
170 unsigned OutputReg
= AMDIL::R600_TReg32RegClass
.getRegister(OutputIndex
);
172 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::COPY
), OutputReg
)
173 .addOperand(MI
->getOperand(0));
175 if (!MRI
.isLiveOut(OutputReg
)) {
176 MRI
.addLiveOut(OutputReg
);
181 case AMDIL::RESERVE_REG
:
183 R600MachineFunctionInfo
* MFI
= MF
->getInfo
<R600MachineFunctionInfo
>();
184 int64_t ReservedIndex
= MI
->getOperand(0).getImm();
185 unsigned ReservedReg
=
186 AMDIL::R600_TReg32RegClass
.getRegister(ReservedIndex
);
187 MFI
->ReservedRegs
.push_back(ReservedReg
);
193 unsigned t0
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
194 unsigned t1
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
196 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SET_GRADIENTS_H
), t0
)
197 .addOperand(MI
->getOperand(3))
198 .addOperand(MI
->getOperand(4))
199 .addOperand(MI
->getOperand(5));
200 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SET_GRADIENTS_V
), t1
)
201 .addOperand(MI
->getOperand(2))
202 .addOperand(MI
->getOperand(4))
203 .addOperand(MI
->getOperand(5));
204 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SAMPLE_G
))
205 .addOperand(MI
->getOperand(0))
206 .addOperand(MI
->getOperand(1))
207 .addOperand(MI
->getOperand(4))
208 .addOperand(MI
->getOperand(5))
209 .addReg(t0
, RegState::Implicit
)
210 .addReg(t1
, RegState::Implicit
);
213 case AMDIL::TXD_SHADOW
:
215 unsigned t0
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
216 unsigned t1
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
218 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SET_GRADIENTS_H
), t0
)
219 .addOperand(MI
->getOperand(3))
220 .addOperand(MI
->getOperand(4))
221 .addOperand(MI
->getOperand(5));
222 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SET_GRADIENTS_V
), t1
)
223 .addOperand(MI
->getOperand(2))
224 .addOperand(MI
->getOperand(4))
225 .addOperand(MI
->getOperand(5));
226 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::TEX_SAMPLE_C_G
))
227 .addOperand(MI
->getOperand(0))
228 .addOperand(MI
->getOperand(1))
229 .addOperand(MI
->getOperand(4))
230 .addOperand(MI
->getOperand(5))
231 .addReg(t0
, RegState::Implicit
)
232 .addReg(t1
, RegState::Implicit
);
239 MI
->eraseFromParent();
243 void R600TargetLowering::lowerImplicitParameter(MachineInstr
*MI
, MachineBasicBlock
&BB
,
244 MachineRegisterInfo
& MRI
, unsigned dword_offset
) const
246 MachineBasicBlock::iterator I
= *MI
;
247 unsigned PtrReg
= MRI
.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass
);
248 MRI
.setRegClass(MI
->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass
);
250 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::MOV
), PtrReg
)
251 .addReg(AMDIL::ALU_LITERAL_X
)
252 .addImm(dword_offset
* 4);
254 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::VTX_READ_PARAM_eg
))
255 .addOperand(MI
->getOperand(0))