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 AMDILISelLowering.cpp. This file
11 // is mostly EmitInstrWithCustomInserter().
13 //===----------------------------------------------------------------------===//
15 #include "R600ISelLowering.h"
16 #include "R600InstrInfo.h"
17 #include "R600MachineFunctionInfo.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 R600TargetLowering::R600TargetLowering(TargetMachine
&TM
) :
23 AMDGPUTargetLowering(TM
),
24 TII(static_cast<const R600InstrInfo
*>(TM
.getInstrInfo()))
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
);
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
);
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::R600_LOAD_CONST
:
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
);
104 case AMDIL::LOAD_INPUT
:
106 int64_t RegIndex
= MI
->getOperand(1).getImm();
107 addLiveIn(MI
, MF
, MRI
, TII
,
108 AMDIL::R600_TReg32RegClass
.getRegister(RegIndex
));
111 case AMDIL::STORE_OUTPUT
:
113 int64_t OutputIndex
= MI
->getOperand(1).getImm();
114 unsigned OutputReg
= AMDIL::R600_TReg32RegClass
.getRegister(OutputIndex
);
116 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::COPY
), OutputReg
)
117 .addOperand(MI
->getOperand(0));
119 if (!MRI
.isLiveOut(OutputReg
)) {
120 MRI
.addLiveOut(OutputReg
);
125 case AMDIL::RESERVE_REG
:
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
);
137 unsigned t0
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
138 unsigned t1
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
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
);
157 case AMDIL::TXD_SHADOW
:
159 unsigned t0
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
160 unsigned t1
= MRI
.createVirtualRegister(AMDIL::R600_Reg128RegisterClass
);
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
);
183 MI
->eraseFromParent();
187 void R600TargetLowering::lowerImplicitParameter(MachineInstr
*MI
, MachineBasicBlock
&BB
,
188 MachineRegisterInfo
& MRI
, unsigned dword_offset
) const
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
);
194 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::MOV
), offsetReg
)
195 .addReg(AMDIL::ALU_LITERAL_X
)
196 .addImm(dword_offset
* 4);
198 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::VTX_READ_eg
))
199 .addOperand(MI
->getOperand(0))