]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/R600/AMDGPUAsmPrinter.cpp
Merge sendmail 8.14.7 to HEAD
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / R600 / 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 /// \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"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Target/TargetLoweringObjectFile.h"
27
28 using namespace llvm;
29
30
31 static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
32                                               MCStreamer &Streamer) {
33   return new AMDGPUAsmPrinter(tm, Streamer);
34 }
35
36 extern "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.
42 bool 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);
50   if (OutStreamer.hasRawTextSupport()) {
51     OutStreamer.EmitRawText("@" + MF.getName() + ":");
52   }
53   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
54   if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
55     EmitProgramInfo(MF);
56   }
57   EmitFunctionBody();
58   return false;
59 }
60
61 void 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:
94         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;
110         } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
111           isSGPR = true;
112           width = 4;
113         } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
114           isSGPR = false;
115           width = 4;
116         } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
117           isSGPR = true;
118           width = 8;
119         } else if (AMDGPU::VReg_256RegClass.contains(reg)) {
120           isSGPR = false;
121           width = 8;
122         } else if (AMDGPU::VReg_512RegClass.contains(reg)) {
123           isSGPR = false;
124           width = 16;
125         } else {
126           assert(!"Unknown register class");
127         }
128         hwReg = RI->getEncodingValue(reg) & 0xff;
129         maxUsed = hwReg + width - 1;
130         if (isSGPR) {
131           MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
132         } else {
133           MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
134         }
135       }
136     }
137   }
138   if (VCCUsed) {
139     MaxSGPR += 2;
140   }
141   SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
142   OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
143   OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
144   OutStreamer.EmitIntValue(MFI->PSInputAddr, 4);
145 }