Line data Source code
1 : //===-- R600AsmPrinter.cpp - R600 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 R600AsmPrinter 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 : #include "R600AsmPrinter.h"
19 : #include "AMDGPUSubtarget.h"
20 : #include "R600Defines.h"
21 : #include "R600MachineFunctionInfo.h"
22 : #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
23 : #include "llvm/BinaryFormat/ELF.h"
24 : #include "llvm/MC/MCContext.h"
25 : #include "llvm/MC/MCSectionELF.h"
26 : #include "llvm/MC/MCStreamer.h"
27 : #include "llvm/Target/TargetLoweringObjectFile.h"
28 :
29 : using namespace llvm;
30 :
31 : AsmPrinter *
32 282 : llvm::createR600AsmPrinterPass(TargetMachine &TM,
33 : std::unique_ptr<MCStreamer> &&Streamer) {
34 282 : return new R600AsmPrinter(TM, std::move(Streamer));
35 : }
36 :
37 282 : R600AsmPrinter::R600AsmPrinter(TargetMachine &TM,
38 282 : std::unique_ptr<MCStreamer> Streamer)
39 564 : : AsmPrinter(TM, std::move(Streamer)) { }
40 :
41 0 : StringRef R600AsmPrinter::getPassName() const {
42 0 : return "R600 Assembly Printer";
43 : }
44 :
45 2297 : void R600AsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) {
46 2297 : unsigned MaxGPR = 0;
47 : bool killPixel = false;
48 2297 : const R600Subtarget &STM = MF.getSubtarget<R600Subtarget>();
49 : const R600RegisterInfo *RI = STM.getRegisterInfo();
50 : const R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
51 :
52 4594 : for (const MachineBasicBlock &MBB : MF) {
53 85668 : for (const MachineInstr &MI : MBB) {
54 166742 : if (MI.getOpcode() == R600::KILLGT)
55 : killPixel = true;
56 83371 : unsigned numOperands = MI.getNumOperands();
57 1103834 : for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
58 1020463 : const MachineOperand &MO = MI.getOperand(op_idx);
59 1020463 : if (!MO.isReg())
60 880214 : continue;
61 206155 : unsigned HWReg = RI->getHWRegIndex(MO.getReg());
62 :
63 : // Register with value > 127 aren't GPR
64 206155 : if (HWReg > 127)
65 : continue;
66 140249 : MaxGPR = std::max(MaxGPR, HWReg);
67 : }
68 : }
69 : }
70 :
71 : unsigned RsrcReg;
72 2297 : if (STM.getGeneration() >= AMDGPUSubtarget::EVERGREEN) {
73 : // Evergreen / Northern Islands
74 2270 : switch (MF.getFunction().getCallingConv()) {
75 : default: LLVM_FALLTHROUGH;
76 : case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break;
77 : case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break;
78 : case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break;
79 : case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break;
80 : }
81 : } else {
82 : // R600 / R700
83 54 : switch (MF.getFunction().getCallingConv()) {
84 : default: LLVM_FALLTHROUGH;
85 : case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH;
86 : case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH;
87 : case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break;
88 8 : case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break;
89 : }
90 : }
91 :
92 2297 : OutStreamer->EmitIntValue(RsrcReg, 4);
93 4594 : OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) |
94 2297 : S_STACK_SIZE(MFI->CFStackSize), 4);
95 2297 : OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4);
96 2297 : OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4);
97 :
98 4594 : if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) {
99 2247 : OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4);
100 4494 : OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4);
101 : }
102 2297 : }
103 :
104 2297 : bool R600AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
105 :
106 :
107 : // Functions needs to be cacheline (256B) aligned.
108 : MF.ensureAlignment(8);
109 :
110 2297 : SetupMachineFunction(MF);
111 :
112 2297 : MCContext &Context = getObjFileLowering().getContext();
113 : MCSectionELF *ConfigSection =
114 2297 : Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0);
115 2297 : OutStreamer->SwitchSection(ConfigSection);
116 :
117 2297 : EmitProgramInfoR600(MF);
118 :
119 2297 : EmitFunctionBody();
120 :
121 2297 : if (isVerbose()) {
122 : MCSectionELF *CommentSection =
123 2276 : Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
124 2276 : OutStreamer->SwitchSection(CommentSection);
125 :
126 2276 : R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
127 2276 : OutStreamer->emitRawComment(
128 4552 : Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize)));
129 : }
130 :
131 2297 : return false;
132 : }
133 :
|