radeon/llvm: Ignore special registers when calculating reg count
[mesa.git] / src / gallium / drivers / radeon / AMDGPUAsmPrinter.cpp
1 //===-- 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 // The AMDGPUAsmPrinter is used to print both assembly string and also binary
11 // code. When passed an MCAsmStreamer it prints assembly and when passed
12 // an MCObjectStreamer it outputs binary code.
13 //
14 //===----------------------------------------------------------------------===//
15 //
16
17
18 #include "AMDGPUAsmPrinter.h"
19 #include "AMDGPU.h"
20 #include "SIMachineFunctionInfo.h"
21 #include "SIRegisterInfo.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/Target/TargetLoweringObjectFile.h"
24 #include "llvm/Support/TargetRegistry.h"
25
26 using namespace llvm;
27
28
29 static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
30 MCStreamer &Streamer) {
31 return new AMDGPUAsmPrinter(tm, Streamer);
32 }
33
34 extern "C" void LLVMInitializeAMDGPUAsmPrinter() {
35 TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
36 }
37
38 /// runOnMachineFunction - We need to override this function so we can avoid
39 /// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
40 bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
41 const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
42 if (STM.dumpCode()) {
43 MF.dump();
44 }
45 SetupMachineFunction(MF);
46 if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
47 EmitProgramInfo(MF);
48 }
49 OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
50 EmitFunctionBody();
51 return false;
52 }
53
54 void AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) {
55 unsigned MaxSGPR = 0;
56 unsigned MaxVGPR = 0;
57 bool VCCUsed = false;
58 const SIRegisterInfo * RI =
59 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
60
61 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
62 BB != BB_E; ++BB) {
63 MachineBasicBlock &MBB = *BB;
64 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
65 I != E; ++I) {
66 MachineInstr &MI = *I;
67
68 unsigned numOperands = MI.getNumOperands();
69 for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
70 MachineOperand & MO = MI.getOperand(op_idx);
71 unsigned maxUsed;
72 unsigned width = 0;
73 bool isSGPR = false;
74 unsigned reg;
75 unsigned hwReg;
76 if (!MO.isReg()) {
77 continue;
78 }
79 reg = MO.getReg();
80 if (reg == AMDGPU::VCC) {
81 VCCUsed = true;
82 continue;
83 }
84 switch (reg) {
85 default: break;
86 case AMDGPU::EXEC:
87 case AMDGPU::SI_LITERAL_CONSTANT:
88 case AMDGPU::SREG_LIT_0:
89 case AMDGPU::M0:
90 continue;
91 }
92
93 if (AMDGPU::SReg_32RegClass.contains(reg)) {
94 isSGPR = true;
95 width = 1;
96 } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
97 isSGPR = false;
98 width = 1;
99 } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
100 isSGPR = true;
101 width = 2;
102 } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
103 isSGPR = false;
104 width = 2;
105 } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
106 isSGPR = true;
107 width = 4;
108 } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
109 isSGPR = false;
110 width = 4;
111 } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
112 isSGPR = true;
113 width = 8;
114 } else {
115 assert(!"Unknown register class");
116 }
117 hwReg = RI->getHWRegNum(reg);
118 maxUsed = hwReg + width - 1;
119 if (isSGPR) {
120 MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
121 } else {
122 MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
123 }
124 }
125 }
126 }
127 if (VCCUsed) {
128 MaxSGPR += 2;
129 }
130 SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
131 OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
132 OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
133 OutStreamer.EmitIntValue(MFI->SPIPSInputAddr, 4);
134 }