radeon/llvm: Remove AMDIL MAD instruction defs
[mesa.git] / src / gallium / drivers / radeon / SIInstrInfo.cpp
1 //===-- SIInstrInfo.cpp - SI Instruction Information ---------------------===//
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 // SI Implementation of TargetInstrInfo.
11 //
12 //===----------------------------------------------------------------------===//
13
14
15 #include "SIInstrInfo.h"
16 #include "AMDGPUTargetMachine.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/MC/MCInstrDesc.h"
19
20 #include <stdio.h>
21
22 using namespace llvm;
23
24 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
25 : AMDGPUInstrInfo(tm),
26 RI(tm, *this),
27 TM(tm)
28 { }
29
30 const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const
31 {
32 return RI;
33 }
34
35 void
36 SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
37 MachineBasicBlock::iterator MI, DebugLoc DL,
38 unsigned DestReg, unsigned SrcReg,
39 bool KillSrc) const
40 {
41 BuildMI(MBB, MI, DL, get(AMDIL::V_MOV_B32_e32), DestReg)
42 .addReg(SrcReg, getKillRegState(KillSrc));
43 }
44
45 unsigned SIInstrInfo::getEncodingType(const MachineInstr &MI) const
46 {
47 return get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK;
48 }
49
50 unsigned SIInstrInfo::getEncodingBytes(const MachineInstr &MI) const
51 {
52
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) {
57 return 8;
58 }
59 }
60
61 /* This instruction always has a literal */
62 if (MI.getOpcode() == AMDIL::S_MOV_IMM_I32) {
63 return 8;
64 }
65
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:
74 return 8;
75 default:
76 return 4;
77 }
78 }
79
80 MachineInstr * SIInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
81 DebugLoc DL) const
82 {
83
84 switch (MI.getOpcode()) {
85 default: break;
86 case AMDIL::ABS_f32: return convertABS_f32(MI, MF, DL);
87 case AMDIL::CLAMP_f32: return convertCLAMP_f32(MI, MF, DL);
88 }
89
90 MachineInstr * newMI = AMDGPUInstrInfo::convertToISA(MI, MF, DL);
91 const MCInstrDesc &newDesc = get(newMI->getOpcode());
92
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++) {
100 builder.addImm(0);
101 }
102 }
103 return newMI;
104 }
105
106 unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const
107 {
108 switch (AMDILopcode) {
109 //XXX We need a better way of detecting end of program
110 case AMDIL::RETURN: return AMDIL::S_ENDPGM;
111 default: return AMDGPUInstrInfo::getISAOpcode(AMDILopcode);
112 }
113 }
114
115 MachineInstr * SIInstrInfo::convertABS_f32(MachineInstr & absInstr,
116 MachineFunction &MF, DebugLoc DL) const
117 {
118 MachineRegisterInfo &MRI = MF.getRegInfo();
119 MachineOperand &dst = absInstr.getOperand(0);
120
121 /* Convert the desination register to the VReg_32 class */
122 if (TargetRegisterInfo::isVirtualRegister(dst.getReg())) {
123 MRI.setRegClass(dst.getReg(), AMDIL::VReg_32RegisterClass);
124 }
125
126 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64))
127 .addOperand(absInstr.getOperand(0))
128 .addOperand(absInstr.getOperand(1))
129 /* VSRC1-2 are unused, but we still need to fill all the
130 * operand slots, so we just reuse the VSRC0 operand */
131 .addOperand(absInstr.getOperand(1))
132 .addOperand(absInstr.getOperand(1))
133 .addImm(1) // ABS
134 .addImm(0) // CLAMP
135 .addImm(0) // OMOD
136 .addImm(0); // NEG
137 }
138
139 MachineInstr * SIInstrInfo::convertCLAMP_f32(MachineInstr & clampInstr,
140 MachineFunction &MF, DebugLoc DL) const
141 {
142 MachineRegisterInfo &MRI = MF.getRegInfo();
143 /* XXX: HACK assume that low == zero and high == one for now until
144 * we have a way to propogate the immediates. */
145
146 /*
147 uint32_t zero = (uint32_t)APFloat(0.0f).bitcastToAPInt().getZExtValue();
148 uint32_t one = (uint32_t)APFloat(1.0f).bitcastToAPInt().getZExtValue();
149 uint32_t low = clampInstr.getOperand(2).getImm();
150 uint32_t high = clampInstr.getOperand(3).getImm();
151 */
152 // if (low == zero && high == one) {
153
154 /* Convert the desination register to the VReg_32 class */
155 if (TargetRegisterInfo::isVirtualRegister(clampInstr.getOperand(0).getReg())) {
156 MRI.setRegClass(clampInstr.getOperand(0).getReg(),
157 AMDIL::VReg_32RegisterClass);
158 }
159 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64))
160 .addOperand(clampInstr.getOperand(0))
161 .addOperand(clampInstr.getOperand(1))
162 /* VSRC1-2 are unused, but we still need to fill all the
163 * operand slots, so we just reuse the VSRC0 operand */
164 .addOperand(clampInstr.getOperand(1))
165 .addOperand(clampInstr.getOperand(1))
166 .addImm(0) // ABS
167 .addImm(1) // CLAMP
168 .addImm(0) // OMOD
169 .addImm(0); // NEG
170 // } else {
171 /* XXX: Handle other cases */
172 // abort();
173 // }
174 }