blob: c915f508c4407b91766b1aecdcb332a11754b547 [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer --------------------===//
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/// \file
11///
12/// The AMDGPUAsmPrinter is used to print both assembly string and also binary
13/// code. When passed an MCAsmStreamer it prints assembly and when passed
14/// an MCObjectStreamer it outputs binary code.
15//
16//===----------------------------------------------------------------------===//
17//
18
19
20#include "AMDGPUAsmPrinter.h"
21#include "AMDGPU.h"
Tom Stellardcb97e3a2013-04-15 17:51:35 +000022#include "SIDefines.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000023#include "SIMachineFunctionInfo.h"
24#include "SIRegisterInfo.h"
Vincent Lejeune117f0752013-04-23 17:34:12 +000025#include "R600MachineFunctionInfo.h"
Vincent Lejeune98a73802013-04-17 15:17:25 +000026#include "R600RegisterInfo.h"
Tom Stellard3a7beafb32013-04-15 17:51:30 +000027#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCSectionELF.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000029#include "llvm/MC/MCStreamer.h"
Tom Stellard3a7beafb32013-04-15 17:51:30 +000030#include "llvm/Support/ELF.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000031#include "llvm/Support/TargetRegistry.h"
Chandler Carruthbe810232013-01-02 10:22:59 +000032#include "llvm/Target/TargetLoweringObjectFile.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000033
34using namespace llvm;
35
36
37static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
38 MCStreamer &Streamer) {
39 return new AMDGPUAsmPrinter(tm, Streamer);
40}
41
42extern "C" void LLVMInitializeR600AsmPrinter() {
43 TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
44}
45
46/// We need to override this function so we can avoid
47/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
48bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
49 const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
50 if (STM.dumpCode()) {
51#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
52 MF.dump();
53#endif
54 }
55 SetupMachineFunction(MF);
Tom Stellard2e5e7a52013-02-05 17:09:11 +000056 if (OutStreamer.hasRawTextSupport()) {
57 OutStreamer.EmitRawText("@" + MF.getName() + ":");
58 }
Vincent Lejeune98a73802013-04-17 15:17:25 +000059
60 const MCSectionELF *ConfigSection = getObjFileLowering().getContext()
61 .getELFSection(".AMDGPU.config",
Tom Stellard34e40682013-04-24 23:56:14 +000062 ELF::SHT_PROGBITS, 0,
Vincent Lejeune98a73802013-04-17 15:17:25 +000063 SectionKind::getReadOnly());
64 OutStreamer.SwitchSection(ConfigSection);
Tom Stellard75aadc22012-12-11 21:25:42 +000065 if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
Vincent Lejeune98a73802013-04-17 15:17:25 +000066 EmitProgramInfoSI(MF);
67 } else {
68 EmitProgramInfoR600(MF);
Tom Stellard75aadc22012-12-11 21:25:42 +000069 }
Tom Stellard3a7beafb32013-04-15 17:51:30 +000070 OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
Tom Stellard75aadc22012-12-11 21:25:42 +000071 EmitFunctionBody();
72 return false;
73}
74
Vincent Lejeune98a73802013-04-17 15:17:25 +000075void AMDGPUAsmPrinter::EmitProgramInfoR600(MachineFunction &MF) {
76 unsigned MaxGPR = 0;
Vincent Lejeune4a0beb52013-04-30 00:13:13 +000077 bool killPixel = false;
Vincent Lejeune98a73802013-04-17 15:17:25 +000078 const R600RegisterInfo * RI =
79 static_cast<const R600RegisterInfo*>(TM.getRegisterInfo());
Vincent Lejeune117f0752013-04-23 17:34:12 +000080 R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
Vincent Lejeune98a73802013-04-17 15:17:25 +000081
82 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
83 BB != BB_E; ++BB) {
84 MachineBasicBlock &MBB = *BB;
85 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
86 I != E; ++I) {
87 MachineInstr &MI = *I;
Vincent Lejeune4a0beb52013-04-30 00:13:13 +000088 if (MI.getOpcode() == AMDGPU::KILLGT)
89 killPixel = true;
Vincent Lejeune98a73802013-04-17 15:17:25 +000090 unsigned numOperands = MI.getNumOperands();
91 for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
92 MachineOperand & MO = MI.getOperand(op_idx);
93 if (!MO.isReg())
94 continue;
95 unsigned HWReg = RI->getEncodingValue(MO.getReg()) & 0xff;
96
97 // Register with value > 127 aren't GPR
98 if (HWReg > 127)
99 continue;
100 MaxGPR = std::max(MaxGPR, HWReg);
101 }
102 }
103 }
104 OutStreamer.EmitIntValue(MaxGPR + 1, 4);
Vincent Lejeune117f0752013-04-23 17:34:12 +0000105 OutStreamer.EmitIntValue(MFI->StackSize, 4);
Vincent Lejeune4a0beb52013-04-30 00:13:13 +0000106 OutStreamer.EmitIntValue(killPixel, 4);
Vincent Lejeune98a73802013-04-17 15:17:25 +0000107}
108
109void AMDGPUAsmPrinter::EmitProgramInfoSI(MachineFunction &MF) {
Tom Stellard75aadc22012-12-11 21:25:42 +0000110 unsigned MaxSGPR = 0;
111 unsigned MaxVGPR = 0;
112 bool VCCUsed = false;
113 const SIRegisterInfo * RI =
114 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
115
116 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
117 BB != BB_E; ++BB) {
118 MachineBasicBlock &MBB = *BB;
119 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
120 I != E; ++I) {
121 MachineInstr &MI = *I;
122
123 unsigned numOperands = MI.getNumOperands();
124 for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
125 MachineOperand & MO = MI.getOperand(op_idx);
126 unsigned maxUsed;
127 unsigned width = 0;
128 bool isSGPR = false;
129 unsigned reg;
130 unsigned hwReg;
131 if (!MO.isReg()) {
132 continue;
133 }
134 reg = MO.getReg();
135 if (reg == AMDGPU::VCC) {
136 VCCUsed = true;
137 continue;
138 }
139 switch (reg) {
140 default: break;
141 case AMDGPU::EXEC:
Tom Stellard75aadc22012-12-11 21:25:42 +0000142 case AMDGPU::M0:
143 continue;
144 }
145
146 if (AMDGPU::SReg_32RegClass.contains(reg)) {
147 isSGPR = true;
148 width = 1;
149 } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
150 isSGPR = false;
151 width = 1;
152 } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
153 isSGPR = true;
154 width = 2;
155 } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
156 isSGPR = false;
157 width = 2;
Christian Konig8b1ed282013-04-10 08:39:16 +0000158 } else if (AMDGPU::VReg_96RegClass.contains(reg)) {
159 isSGPR = false;
160 width = 3;
Tom Stellard75aadc22012-12-11 21:25:42 +0000161 } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
162 isSGPR = true;
163 width = 4;
164 } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
165 isSGPR = false;
166 width = 4;
167 } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
168 isSGPR = true;
169 width = 8;
Tom Stellard538ceeb2013-02-07 17:02:09 +0000170 } else if (AMDGPU::VReg_256RegClass.contains(reg)) {
171 isSGPR = false;
172 width = 8;
173 } else if (AMDGPU::VReg_512RegClass.contains(reg)) {
174 isSGPR = false;
175 width = 16;
Tom Stellard75aadc22012-12-11 21:25:42 +0000176 } else {
177 assert(!"Unknown register class");
178 }
Tom Stellard1c822a82013-02-07 19:39:45 +0000179 hwReg = RI->getEncodingValue(reg) & 0xff;
Tom Stellard75aadc22012-12-11 21:25:42 +0000180 maxUsed = hwReg + width - 1;
181 if (isSGPR) {
182 MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
183 } else {
184 MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
185 }
186 }
187 }
188 }
189 if (VCCUsed) {
190 MaxSGPR += 2;
191 }
192 SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
Tom Stellardcb97e3a2013-04-15 17:51:35 +0000193 unsigned RsrcReg;
194 switch (MFI->ShaderType) {
195 default: // Fall through
196 case ShaderType::COMPUTE: RsrcReg = R_00B848_COMPUTE_PGM_RSRC1; break;
197 case ShaderType::GEOMETRY: RsrcReg = R_00B228_SPI_SHADER_PGM_RSRC1_GS; break;
198 case ShaderType::PIXEL: RsrcReg = R_00B028_SPI_SHADER_PGM_RSRC1_PS; break;
199 case ShaderType::VERTEX: RsrcReg = R_00B128_SPI_SHADER_PGM_RSRC1_VS; break;
200 }
201
202 OutStreamer.EmitIntValue(RsrcReg, 4);
203 OutStreamer.EmitIntValue(S_00B028_VGPRS(MaxVGPR / 4) | S_00B028_SGPRS(MaxSGPR / 8), 4);
204 if (MFI->ShaderType == ShaderType::PIXEL) {
205 OutStreamer.EmitIntValue(R_0286CC_SPI_PS_INPUT_ENA, 4);
206 OutStreamer.EmitIntValue(MFI->PSInputAddr, 4);
207 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000208}