1 //===-- SIInstrInfo.cpp - SI Instruction Information ---------------------===//
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 // SI Implementation of TargetInstrInfo.
12 //===----------------------------------------------------------------------===//
15 #include "SIInstrInfo.h"
16 #include "AMDGPUTargetMachine.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/MC/MCInstrDesc.h"
24 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine
&tm
)
25 : AMDGPUInstrInfo(tm
),
30 const SIRegisterInfo
&SIInstrInfo::getRegisterInfo() const
36 SIInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
37 MachineBasicBlock::iterator MI
, DebugLoc DL
,
38 unsigned DestReg
, unsigned SrcReg
,
41 BuildMI(MBB
, MI
, DL
, get(AMDIL::V_MOV_B32_e32
), DestReg
)
42 .addReg(SrcReg
, getKillRegState(KillSrc
));
45 unsigned SIInstrInfo::getEncodingType(const MachineInstr
&MI
) const
47 return get(MI
.getOpcode()).TSFlags
& SI_INSTR_FLAGS_ENCODING_MASK
;
50 unsigned SIInstrInfo::getEncodingBytes(const MachineInstr
&MI
) const
53 /* Instructions with literal constants are expanded to 64-bits, and
54 * the constant is stored in bits [63:32] */
55 for (unsigned i
= 0; i
< MI
.getNumOperands(); i
++) {
56 if (MI
.getOperand(i
).getType() == MachineOperand::MO_FPImmediate
) {
61 /* This instruction always has a literal */
62 if (MI
.getOpcode() == AMDIL::S_MOV_IMM_I32
) {
66 unsigned encoding_type
= getEncodingType(MI
);
67 switch (encoding_type
) {
68 case SIInstrEncodingType::EXP
:
69 case SIInstrEncodingType::LDS
:
70 case SIInstrEncodingType::MUBUF
:
71 case SIInstrEncodingType::MTBUF
:
72 case SIInstrEncodingType::MIMG
:
73 case SIInstrEncodingType::VOP3
:
80 MachineInstr
* SIInstrInfo::convertToISA(MachineInstr
& MI
, MachineFunction
&MF
,
84 switch (MI
.getOpcode()) {
86 case AMDIL::ABS_f32
: return convertABS_f32(MI
, MF
, DL
);
87 case AMDIL::CLAMP_f32
: return convertCLAMP_f32(MI
, MF
, DL
);
90 MachineInstr
* newMI
= AMDGPUInstrInfo::convertToISA(MI
, MF
, DL
);
91 const MCInstrDesc
&newDesc
= get(newMI
->getOpcode());
93 /* If this instruction was converted to a VOP3, we need to add the extra
94 * operands for abs, clamp, omod, and negate. */
95 if (getEncodingType(*newMI
) == SIInstrEncodingType::VOP3
96 && newMI
->getNumOperands() < newDesc
.getNumOperands()) {
97 MachineInstrBuilder
builder(newMI
);
98 for (unsigned op_idx
= newMI
->getNumOperands();
99 op_idx
< newDesc
.getNumOperands(); op_idx
++) {
106 unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode
) const
108 switch (AMDILopcode
) {
109 case AMDIL::MAD_f32
: return AMDIL::V_MAD_LEGACY_F32
;
110 //XXX We need a better way of detecting end of program
111 case AMDIL::RETURN
: return AMDIL::S_ENDPGM
;
112 default: return AMDGPUInstrInfo::getISAOpcode(AMDILopcode
);
116 MachineInstr
* SIInstrInfo::convertABS_f32(MachineInstr
& absInstr
,
117 MachineFunction
&MF
, DebugLoc DL
) const
119 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
120 MachineOperand
&dst
= absInstr
.getOperand(0);
122 /* Convert the desination register to the VReg_32 class */
123 if (TargetRegisterInfo::isVirtualRegister(dst
.getReg())) {
124 MRI
.setRegClass(dst
.getReg(), AMDIL::VReg_32RegisterClass
);
127 return BuildMI(MF
, DL
, get(AMDIL::V_MOV_B32_e64
))
128 .addOperand(absInstr
.getOperand(0))
129 .addOperand(absInstr
.getOperand(1))
130 /* VSRC1-2 are unused, but we still need to fill all the
131 * operand slots, so we just reuse the VSRC0 operand */
132 .addOperand(absInstr
.getOperand(1))
133 .addOperand(absInstr
.getOperand(1))
140 MachineInstr
* SIInstrInfo::convertCLAMP_f32(MachineInstr
& clampInstr
,
141 MachineFunction
&MF
, DebugLoc DL
) const
143 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
144 /* XXX: HACK assume that low == zero and high == one for now until
145 * we have a way to propogate the immediates. */
148 uint32_t zero = (uint32_t)APFloat(0.0f).bitcastToAPInt().getZExtValue();
149 uint32_t one = (uint32_t)APFloat(1.0f).bitcastToAPInt().getZExtValue();
150 uint32_t low = clampInstr.getOperand(2).getImm();
151 uint32_t high = clampInstr.getOperand(3).getImm();
153 // if (low == zero && high == one) {
155 /* Convert the desination register to the VReg_32 class */
156 if (TargetRegisterInfo::isVirtualRegister(clampInstr
.getOperand(0).getReg())) {
157 MRI
.setRegClass(clampInstr
.getOperand(0).getReg(),
158 AMDIL::VReg_32RegisterClass
);
160 return BuildMI(MF
, DL
, get(AMDIL::V_MOV_B32_e64
))
161 .addOperand(clampInstr
.getOperand(0))
162 .addOperand(clampInstr
.getOperand(1))
163 /* VSRC1-2 are unused, but we still need to fill all the
164 * operand slots, so we just reuse the VSRC0 operand */
165 .addOperand(clampInstr
.getOperand(1))
166 .addOperand(clampInstr
.getOperand(1))
172 /* XXX: Handle other cases */