AMDGPUAsmPrinter.cpp revision 249259
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
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);
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
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:
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}
146