• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createAMDGPUAsmPrinterPass(TargetMachine & tm,MCStreamer & Streamer)29 static AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
30                                               MCStreamer &Streamer) {
31   return new AMDGPUAsmPrinter(tm, Streamer);
32 }
33 
LLVMInitializeAMDGPUAsmPrinter()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.
runOnMachineFunction(MachineFunction & MF)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 
EmitProgramInfo(MachineFunction & MF)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         if (reg == AMDGPU::EXEC) {
85           continue;
86         }
87         if (AMDGPU::SReg_32RegClass.contains(reg)) {
88           isSGPR = true;
89           width = 1;
90         } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
91           isSGPR = false;
92           width = 1;
93         } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
94           isSGPR = true;
95           width = 2;
96         } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
97           isSGPR = false;
98           width = 2;
99         } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
100           isSGPR = true;
101           width = 4;
102         } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
103           isSGPR = false;
104           width = 4;
105         } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
106           isSGPR = true;
107           width = 8;
108         } else {
109           assert("!Unknown register class");
110         }
111         hwReg = RI->getHWRegNum(reg);
112         maxUsed = hwReg + width - 1;
113         if (isSGPR) {
114           MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
115         } else {
116           MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
117         }
118       }
119     }
120   }
121   if (VCCUsed) {
122     MaxSGPR += 2;
123   }
124   SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
125   OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
126   OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
127   OutStreamer.EmitIntValue(MFI->spi_ps_input_addr, 4);
128 }
129