1 //===-- SIISelLowering.cpp - SI 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 is
11 // mostly EmitInstrWithCustomInserter().
13 //===----------------------------------------------------------------------===//
15 #include "SIISelLowering.h"
16 #include "SIInstrInfo.h"
17 #include "SIRegisterInfo.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 SITargetLowering::SITargetLowering(TargetMachine
&TM
) :
23 AMDGPUTargetLowering(TM
),
24 TII(static_cast<const SIInstrInfo
*>(TM
.getInstrInfo()))
26 addRegisterClass(MVT::v4f32
, &AMDIL::VReg_128RegClass
);
27 addRegisterClass(MVT::f32
, &AMDIL::VReg_32RegClass
);
29 setOperationAction(ISD::EXTRACT_VECTOR_ELT
, MVT::v4f32
, Legal
);
30 setOperationAction(ISD::INSERT_VECTOR_ELT
, MVT::v4f32
, Legal
);
33 MachineBasicBlock
* SITargetLowering::EmitInstrWithCustomInserter(
34 MachineInstr
* MI
, MachineBasicBlock
* BB
) const
36 const TargetInstrInfo
* TII
= getTargetMachine().getInstrInfo();
37 MachineRegisterInfo
& MRI
= BB
->getParent()->getRegInfo();
38 MachineBasicBlock::iterator I
= MI
;
40 if (TII
->get(MI
->getOpcode()).TSFlags
& SIInstrFlags::NEED_WAIT
) {
41 AppendS_WAITCNT(MI
, *BB
, llvm::next(I
));
45 switch (MI
->getOpcode()) {
47 return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI
, BB
);
50 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::V_MOV_B32_e64
))
51 .addOperand(MI
->getOperand(0))
52 .addOperand(MI
->getOperand(1))
53 /* VSRC1-2 are unused, but we still need to fill all the
54 * operand slots, so we just reuse the VSRC0 operand */
55 .addOperand(MI
->getOperand(1))
56 .addOperand(MI
->getOperand(1))
61 MI
->eraseFromParent();
65 BuildMI(*BB
, I
, BB
->findDebugLoc(I
), TII
->get(AMDIL::V_MOV_B32_e64
))
66 .addOperand(MI
->getOperand(0))
67 .addOperand(MI
->getOperand(1))
68 /* VSRC1-2 are unused, but we still need to fill all the
69 * operand slots, so we just reuse the VSRC0 operand */
70 .addOperand(MI
->getOperand(1))
71 .addOperand(MI
->getOperand(1))
76 MI
->eraseFromParent();
79 case AMDIL::SI_INTERP
:
80 LowerSI_INTERP(MI
, *BB
, I
, MRI
);
82 case AMDIL::SI_INTERP_CONST
:
83 LowerSI_INTERP_CONST(MI
, *BB
, I
);
85 case AMDIL::SI_V_CNDLT
:
86 LowerSI_V_CNDLT(MI
, *BB
, I
, MRI
);
88 case AMDIL::USE_SGPR_32
:
89 case AMDIL::USE_SGPR_64
:
90 lowerUSE_SGPR(MI
, BB
->getParent(), MRI
);
91 MI
->eraseFromParent();
93 case AMDIL::VS_LOAD_BUFFER_INDEX
:
94 addLiveIn(MI
, BB
->getParent(), MRI
, TII
, AMDIL::VGPR0
);
95 MI
->eraseFromParent();
101 void SITargetLowering::AppendS_WAITCNT(MachineInstr
*MI
, MachineBasicBlock
&BB
,
102 MachineBasicBlock::iterator I
) const
104 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::S_WAITCNT
))
108 void SITargetLowering::LowerSI_INTERP(MachineInstr
*MI
, MachineBasicBlock
&BB
,
109 MachineBasicBlock::iterator I
, MachineRegisterInfo
& MRI
) const
111 unsigned tmp
= MRI
.createVirtualRegister(&AMDIL::VReg_32RegClass
);
112 MachineOperand dst
= MI
->getOperand(0);
113 MachineOperand iReg
= MI
->getOperand(1);
114 MachineOperand jReg
= MI
->getOperand(2);
115 MachineOperand attr_chan
= MI
->getOperand(3);
116 MachineOperand attr
= MI
->getOperand(4);
117 MachineOperand params
= MI
->getOperand(5);
119 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::S_MOV_B32
))
123 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::V_INTERP_P1_F32
), tmp
)
125 .addOperand(attr_chan
)
128 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::V_INTERP_P2_F32
))
132 .addOperand(attr_chan
)
135 MI
->eraseFromParent();
138 void SITargetLowering::LowerSI_INTERP_CONST(MachineInstr
*MI
,
139 MachineBasicBlock
&BB
, MachineBasicBlock::iterator I
) const
141 MachineOperand dst
= MI
->getOperand(0);
142 MachineOperand attr_chan
= MI
->getOperand(1);
143 MachineOperand attr
= MI
->getOperand(2);
144 MachineOperand params
= MI
->getOperand(3);
146 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::S_MOV_B32
))
150 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::V_INTERP_MOV_F32
))
152 .addOperand(attr_chan
)
155 MI
->eraseFromParent();
158 void SITargetLowering::LowerSI_V_CNDLT(MachineInstr
*MI
, MachineBasicBlock
&BB
,
159 MachineBasicBlock::iterator I
, MachineRegisterInfo
& MRI
) const
161 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::V_CMP_LT_F32_e32
))
162 .addOperand(MI
->getOperand(1))
163 .addReg(AMDIL::SREG_LIT_0
);
165 BuildMI(BB
, I
, BB
.findDebugLoc(I
), TII
->get(AMDIL::V_CNDMASK_B32
))
166 .addOperand(MI
->getOperand(0))
167 .addOperand(MI
->getOperand(2))
168 .addOperand(MI
->getOperand(3));
170 MI
->eraseFromParent();
173 void SITargetLowering::lowerUSE_SGPR(MachineInstr
*MI
,
174 MachineFunction
* MF
, MachineRegisterInfo
& MRI
) const
176 const TargetInstrInfo
* TII
= getTargetMachine().getInstrInfo();
177 unsigned dstReg
= MI
->getOperand(0).getReg();
178 int64_t newIndex
= MI
->getOperand(1).getImm();
179 const TargetRegisterClass
* dstClass
= MRI
.getRegClass(dstReg
);
181 unsigned newReg
= dstClass
->getRegister(newIndex
);
182 addLiveIn(MI
, MF
, MRI
, TII
, newReg
);