blob: dacb03325bc71a094c29506cbd787576d6b5ac59 [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"
22#include "SIMachineFunctionInfo.h"
23#include "SIRegisterInfo.h"
24#include "llvm/MC/MCStreamer.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000025#include "llvm/Support/TargetRegistry.h"
Chandler Carruthbe810232013-01-02 10:22:59 +000026#include "llvm/Target/TargetLoweringObjectFile.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000027
28using namespace llvm;
29
30
31static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
32 MCStreamer &Streamer) {
33 return new AMDGPUAsmPrinter(tm, Streamer);
34}
35
36extern "C" void LLVMInitializeR600AsmPrinter() {
37 TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
38}
39
40/// We need to override this function so we can avoid
41/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
42bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
43 const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
44 if (STM.dumpCode()) {
45#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
46 MF.dump();
47#endif
48 }
49 SetupMachineFunction(MF);
Tom Stellard2e5e7a52013-02-05 17:09:11 +000050 if (OutStreamer.hasRawTextSupport()) {
51 OutStreamer.EmitRawText("@" + MF.getName() + ":");
52 }
Tom Stellard75aadc22012-12-11 21:25:42 +000053 OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
54 if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
55 EmitProgramInfo(MF);
56 }
57 EmitFunctionBody();
58 return false;
59}
60
61void AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) {
62 unsigned MaxSGPR = 0;
63 unsigned MaxVGPR = 0;
64 bool VCCUsed = false;
65 const SIRegisterInfo * RI =
66 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
67
68 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
69 BB != BB_E; ++BB) {
70 MachineBasicBlock &MBB = *BB;
71 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
72 I != E; ++I) {
73 MachineInstr &MI = *I;
74
75 unsigned numOperands = MI.getNumOperands();
76 for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
77 MachineOperand & MO = MI.getOperand(op_idx);
78 unsigned maxUsed;
79 unsigned width = 0;
80 bool isSGPR = false;
81 unsigned reg;
82 unsigned hwReg;
83 if (!MO.isReg()) {
84 continue;
85 }
86 reg = MO.getReg();
87 if (reg == AMDGPU::VCC) {
88 VCCUsed = true;
89 continue;
90 }
91 switch (reg) {
92 default: break;
93 case AMDGPU::EXEC:
Tom Stellard75aadc22012-12-11 21:25:42 +000094 case AMDGPU::M0:
95 continue;
96 }
97
98 if (AMDGPU::SReg_32RegClass.contains(reg)) {
99 isSGPR = true;
100 width = 1;
101 } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
102 isSGPR = false;
103 width = 1;
104 } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
105 isSGPR = true;
106 width = 2;
107 } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
108 isSGPR = false;
109 width = 2;
Christian Konig8b1ed282013-04-10 08:39:16 +0000110 } else if (AMDGPU::VReg_96RegClass.contains(reg)) {
111 isSGPR = false;
112 width = 3;
Tom Stellard75aadc22012-12-11 21:25:42 +0000113 } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
114 isSGPR = true;
115 width = 4;
116 } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
117 isSGPR = false;
118 width = 4;
119 } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
120 isSGPR = true;
121 width = 8;
Tom Stellard538ceeb2013-02-07 17:02:09 +0000122 } else if (AMDGPU::VReg_256RegClass.contains(reg)) {
123 isSGPR = false;
124 width = 8;
125 } else if (AMDGPU::VReg_512RegClass.contains(reg)) {
126 isSGPR = false;
127 width = 16;
Tom Stellard75aadc22012-12-11 21:25:42 +0000128 } else {
129 assert(!"Unknown register class");
130 }
Tom Stellard1c822a82013-02-07 19:39:45 +0000131 hwReg = RI->getEncodingValue(reg) & 0xff;
Tom Stellard75aadc22012-12-11 21:25:42 +0000132 maxUsed = hwReg + width - 1;
133 if (isSGPR) {
134 MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
135 } else {
136 MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
137 }
138 }
139 }
140 }
141 if (VCCUsed) {
142 MaxSGPR += 2;
143 }
144 SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
145 OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
146 OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
Christian Konig99ee0f42013-03-07 09:04:14 +0000147 OutStreamer.EmitIntValue(MFI->PSInputAddr, 4);
Tom Stellard75aadc22012-12-11 21:25:42 +0000148}