1 //===-- R600AsmPrinter.cpp - R600 Assembly printer ------------------------===//
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
7 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
17 #include "R600AsmPrinter.h"
18 #include "MCTargetDesc/R600MCTargetDesc.h"
19 #include "R600Defines.h"
20 #include "R600MachineFunctionInfo.h"
21 #include "R600Subtarget.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"
31 llvm::createR600AsmPrinterPass(TargetMachine
&TM
,
32 std::unique_ptr
<MCStreamer
> &&Streamer
) {
33 return new R600AsmPrinter(TM
, std::move(Streamer
));
36 R600AsmPrinter::R600AsmPrinter(TargetMachine
&TM
,
37 std::unique_ptr
<MCStreamer
> Streamer
)
38 : AsmPrinter(TM
, std::move(Streamer
)) { }
40 StringRef
R600AsmPrinter::getPassName() const {
41 return "R600 Assembly Printer";
44 void R600AsmPrinter::EmitProgramInfoR600(const MachineFunction
&MF
) {
46 bool killPixel
= false;
47 const R600Subtarget
&STM
= MF
.getSubtarget
<R600Subtarget
>();
48 const R600RegisterInfo
*RI
= STM
.getRegisterInfo();
49 const R600MachineFunctionInfo
*MFI
= MF
.getInfo
<R600MachineFunctionInfo
>();
51 for (const MachineBasicBlock
&MBB
: MF
) {
52 for (const MachineInstr
&MI
: MBB
) {
53 if (MI
.getOpcode() == R600::KILLGT
)
55 unsigned numOperands
= MI
.getNumOperands();
56 for (unsigned op_idx
= 0; op_idx
< numOperands
; op_idx
++) {
57 const MachineOperand
&MO
= MI
.getOperand(op_idx
);
60 unsigned HWReg
= RI
->getHWRegIndex(MO
.getReg());
62 // Register with value > 127 aren't GPR
65 MaxGPR
= std::max(MaxGPR
, HWReg
);
71 if (STM
.getGeneration() >= AMDGPUSubtarget::EVERGREEN
) {
72 // Evergreen / Northern Islands
73 switch (MF
.getFunction().getCallingConv()) {
74 default: [[fallthrough
]];
75 case CallingConv::AMDGPU_CS
: RsrcReg
= R_0288D4_SQ_PGM_RESOURCES_LS
; break;
76 case CallingConv::AMDGPU_GS
: RsrcReg
= R_028878_SQ_PGM_RESOURCES_GS
; break;
77 case CallingConv::AMDGPU_PS
: RsrcReg
= R_028844_SQ_PGM_RESOURCES_PS
; break;
78 case CallingConv::AMDGPU_VS
: RsrcReg
= R_028860_SQ_PGM_RESOURCES_VS
; break;
82 switch (MF
.getFunction().getCallingConv()) {
83 default: [[fallthrough
]];
84 case CallingConv::AMDGPU_GS
: [[fallthrough
]];
85 case CallingConv::AMDGPU_CS
: [[fallthrough
]];
86 case CallingConv::AMDGPU_VS
: RsrcReg
= R_028868_SQ_PGM_RESOURCES_VS
; break;
87 case CallingConv::AMDGPU_PS
: RsrcReg
= R_028850_SQ_PGM_RESOURCES_PS
; break;
91 OutStreamer
->emitInt32(RsrcReg
);
92 OutStreamer
->emitIntValue(S_NUM_GPRS(MaxGPR
+ 1) |
93 S_STACK_SIZE(MFI
->CFStackSize
), 4);
94 OutStreamer
->emitInt32(R_02880C_DB_SHADER_CONTROL
);
95 OutStreamer
->emitInt32(S_02880C_KILL_ENABLE(killPixel
));
97 if (AMDGPU::isCompute(MF
.getFunction().getCallingConv())) {
98 OutStreamer
->emitInt32(R_0288E8_SQ_LDS_ALLOC
);
99 OutStreamer
->emitIntValue(alignTo(MFI
->getLDSSize(), 4) >> 2, 4);
103 bool R600AsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
106 // Functions needs to be cacheline (256B) aligned.
107 MF
.ensureAlignment(Align(256));
109 SetupMachineFunction(MF
);
111 MCContext
&Context
= getObjFileLowering().getContext();
112 MCSectionELF
*ConfigSection
=
113 Context
.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS
, 0);
114 OutStreamer
->switchSection(ConfigSection
);
116 EmitProgramInfoR600(MF
);
121 MCSectionELF
*CommentSection
=
122 Context
.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS
, 0);
123 OutStreamer
->switchSection(CommentSection
);
125 R600MachineFunctionInfo
*MFI
= MF
.getInfo
<R600MachineFunctionInfo
>();
126 OutStreamer
->emitRawComment(
127 Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI
->CFStackSize
)));