/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AMDGPU/R600AsmPrinter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- R600AsmPrinter.cpp - R600 Assebly printer ------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | /// \file |
10 | | /// |
11 | | /// The R600AsmPrinter is used to print both assembly string and also binary |
12 | | /// code. When passed an MCAsmStreamer it prints assembly and when passed |
13 | | /// an MCObjectStreamer it outputs binary code. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #include "R600AsmPrinter.h" |
18 | | #include "AMDGPUSubtarget.h" |
19 | | #include "R600Defines.h" |
20 | | #include "R600MachineFunctionInfo.h" |
21 | | #include "MCTargetDesc/AMDGPUMCTargetDesc.h" |
22 | | #include "llvm/BinaryFormat/ELF.h" |
23 | | #include "llvm/MC/MCContext.h" |
24 | | #include "llvm/MC/MCSectionELF.h" |
25 | | #include "llvm/MC/MCStreamer.h" |
26 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
27 | | |
28 | | using namespace llvm; |
29 | | |
30 | | AsmPrinter * |
31 | | llvm::createR600AsmPrinterPass(TargetMachine &TM, |
32 | 280 | std::unique_ptr<MCStreamer> &&Streamer) { |
33 | 280 | return new R600AsmPrinter(TM, std::move(Streamer)); |
34 | 280 | } |
35 | | |
36 | | R600AsmPrinter::R600AsmPrinter(TargetMachine &TM, |
37 | | std::unique_ptr<MCStreamer> Streamer) |
38 | 280 | : AsmPrinter(TM, std::move(Streamer)) { } |
39 | | |
40 | 2.29k | StringRef R600AsmPrinter::getPassName() const { |
41 | 2.29k | return "R600 Assembly Printer"; |
42 | 2.29k | } |
43 | | |
44 | 2.29k | void R600AsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) { |
45 | 2.29k | unsigned MaxGPR = 0; |
46 | 2.29k | bool killPixel = false; |
47 | 2.29k | const R600Subtarget &STM = MF.getSubtarget<R600Subtarget>(); |
48 | 2.29k | const R600RegisterInfo *RI = STM.getRegisterInfo(); |
49 | 2.29k | const R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); |
50 | 2.29k | |
51 | 2.29k | for (const MachineBasicBlock &MBB : MF) { |
52 | 83.6k | for (const MachineInstr &MI : MBB) { |
53 | 83.6k | if (MI.getOpcode() == R600::KILLGT) |
54 | 0 | killPixel = true; |
55 | 83.6k | unsigned numOperands = MI.getNumOperands(); |
56 | 1.11M | for (unsigned op_idx = 0; op_idx < numOperands; op_idx++1.02M ) { |
57 | 1.02M | const MachineOperand &MO = MI.getOperand(op_idx); |
58 | 1.02M | if (!MO.isReg()) |
59 | 819k | continue; |
60 | 207k | unsigned HWReg = RI->getHWRegIndex(MO.getReg()); |
61 | 207k | |
62 | 207k | // Register with value > 127 aren't GPR |
63 | 207k | if (HWReg > 127) |
64 | 66.5k | continue; |
65 | 141k | MaxGPR = std::max(MaxGPR, HWReg); |
66 | 141k | } |
67 | 83.6k | } |
68 | 2.29k | } |
69 | 2.29k | |
70 | 2.29k | unsigned RsrcReg; |
71 | 2.29k | if (STM.getGeneration() >= AMDGPUSubtarget::EVERGREEN) { |
72 | 2.26k | // Evergreen / Northern Islands |
73 | 2.26k | switch (MF.getFunction().getCallingConv()) { |
74 | 2.26k | default: 2.22k LLVM_FALLTHROUGH2.22k ; |
75 | 2.22k | case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break; |
76 | 2.22k | case CallingConv::AMDGPU_GS: RsrcReg = 0 R_028878_SQ_PGM_RESOURCES_GS0 ; break; |
77 | 2.22k | case CallingConv::AMDGPU_PS: RsrcReg = 27 R_028844_SQ_PGM_RESOURCES_PS27 ; break; |
78 | 2.22k | case CallingConv::AMDGPU_VS: RsrcReg = 12 R_028860_SQ_PGM_RESOURCES_VS12 ; break; |
79 | 29 | } |
80 | 29 | } else { |
81 | 29 | // R600 / R700 |
82 | 29 | switch (MF.getFunction().getCallingConv()) { |
83 | 29 | default: 18 LLVM_FALLTHROUGH18 ; |
84 | 18 | case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH; |
85 | 18 | case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH; |
86 | 21 | case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break; |
87 | 18 | case CallingConv::AMDGPU_PS: RsrcReg = 8 R_028850_SQ_PGM_RESOURCES_PS8 ; break; |
88 | 2.29k | } |
89 | 2.29k | } |
90 | 2.29k | |
91 | 2.29k | OutStreamer->EmitIntValue(RsrcReg, 4); |
92 | 2.29k | OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) | |
93 | 2.29k | S_STACK_SIZE(MFI->CFStackSize), 4); |
94 | 2.29k | OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4); |
95 | 2.29k | OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4); |
96 | 2.29k | |
97 | 2.29k | if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) { |
98 | 2.24k | OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4); |
99 | 2.24k | OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4); |
100 | 2.24k | } |
101 | 2.29k | } |
102 | | |
103 | 2.29k | bool R600AsmPrinter::runOnMachineFunction(MachineFunction &MF) { |
104 | 2.29k | |
105 | 2.29k | |
106 | 2.29k | // Functions needs to be cacheline (256B) aligned. |
107 | 2.29k | MF.ensureAlignment(8); |
108 | 2.29k | |
109 | 2.29k | SetupMachineFunction(MF); |
110 | 2.29k | |
111 | 2.29k | MCContext &Context = getObjFileLowering().getContext(); |
112 | 2.29k | MCSectionELF *ConfigSection = |
113 | 2.29k | Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0); |
114 | 2.29k | OutStreamer->SwitchSection(ConfigSection); |
115 | 2.29k | |
116 | 2.29k | EmitProgramInfoR600(MF); |
117 | 2.29k | |
118 | 2.29k | EmitFunctionBody(); |
119 | 2.29k | |
120 | 2.29k | if (isVerbose()) { |
121 | 2.27k | MCSectionELF *CommentSection = |
122 | 2.27k | Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0); |
123 | 2.27k | OutStreamer->SwitchSection(CommentSection); |
124 | 2.27k | |
125 | 2.27k | R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>(); |
126 | 2.27k | OutStreamer->emitRawComment( |
127 | 2.27k | Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize))); |
128 | 2.27k | } |
129 | 2.29k | |
130 | 2.29k | return false; |
131 | 2.29k | } |
132 | | |