1//===-- AMDGPUTargetStreamer.h - AMDGPU Target Streamer --------*- C++ -*--===//
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#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
10#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
11
12#include "Utils/AMDGPUBaseInfo.h"
13#include "Utils/AMDGPUPALMetadata.h"
14#include "llvm/MC/MCStreamer.h"
15
16namespace llvm {
17
18class MCELFStreamer;
19class MCSymbol;
20class formatted_raw_ostream;
21
22namespace AMDGPU {
23
24struct AMDGPUMCKernelCodeT;
25struct MCKernelDescriptor;
26namespace HSAMD {
27struct Metadata;
28}
29} // namespace AMDGPU
30
31class AMDGPUTargetStreamer : public MCTargetStreamer {
32 AMDGPUPALMetadata PALMetadata;
33
34protected:
35 // TODO: Move HSAMetadataStream to AMDGPUTargetStreamer.
36 std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> TargetID;
37 unsigned CodeObjectVersion;
38
39 MCContext &getContext() const { return Streamer.getContext(); }
40
41public:
42 AMDGPUTargetStreamer(MCStreamer &S)
43 : MCTargetStreamer(S),
44 // Assume the default COV for now, EmitDirectiveAMDHSACodeObjectVersion
45 // will update this if it is encountered.
46 CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {}
47
48 AMDGPUPALMetadata *getPALMetadata() { return &PALMetadata; }
49
50 virtual void EmitDirectiveAMDGCNTarget(){};
51
52 virtual void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) {
53 CodeObjectVersion = COV;
54 }
55
56 virtual void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) {};
57
58 virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type){};
59
60 virtual void emitAMDGPULDS(MCSymbol *Symbol, unsigned Size, Align Alignment) {
61 }
62
63 virtual void EmitMCResourceInfo(
64 const MCSymbol *NumVGPR, const MCSymbol *NumAGPR,
65 const MCSymbol *NumExplicitSGPR, const MCSymbol *NumNamedBarrier,
66 const MCSymbol *PrivateSegmentSize, const MCSymbol *UsesVCC,
67 const MCSymbol *UsesFlatScratch, const MCSymbol *HasDynamicallySizedStack,
68 const MCSymbol *HasRecursion, const MCSymbol *HasIndirectCall) {};
69
70 virtual void EmitMCResourceMaximums(const MCSymbol *MaxVGPR,
71 const MCSymbol *MaxAGPR,
72 const MCSymbol *MaxSGPR,
73 const MCSymbol *MaxNamedBarrier) {};
74
75 /// \returns True on success, false on failure.
76 virtual bool EmitISAVersion() { return true; }
77
78 /// \returns True on success, false on failure.
79 virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString);
80
81 /// Emit HSA Metadata
82 ///
83 /// When \p Strict is true, known metadata elements must already be
84 /// well-typed. When \p Strict is false, known types are inferred and
85 /// the \p HSAMetadata structure is updated with the correct types.
86 ///
87 /// \returns True on success, false on failure.
88 virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) {
89 return true;
90 }
91
92 /// \returns True on success, false on failure.
93 virtual bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) {
94 return true;
95 }
96
97 /// \returns True on success, false on failure.
98 virtual bool EmitCodeEnd(const MCSubtargetInfo &STI) { return true; }
99
100 virtual void
101 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
102 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
103 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
104 const MCExpr *ReserveVCC,
105 const MCExpr *ReserveFlatScr) {}
106
107 static StringRef getArchNameFromElfMach(unsigned ElfMach);
108 static unsigned getElfMach(StringRef GPU);
109
110 const std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() const {
111 return TargetID;
112 }
113 std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() {
114 return TargetID;
115 }
116 void initializeTargetID(const MCSubtargetInfo &STI) {
117 assert(TargetID == std::nullopt && "TargetID can only be initialized once");
118 TargetID.emplace(args: STI);
119 }
120 void initializeTargetID(const MCSubtargetInfo &STI, StringRef FeatureString) {
121 initializeTargetID(STI);
122
123 assert(getTargetID() != std::nullopt && "TargetID is None");
124 getTargetID()->setTargetIDFromFeaturesString(FeatureString);
125 }
126};
127
128class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer {
129 formatted_raw_ostream &OS;
130public:
131 AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
132
133 void finish() override;
134
135 void EmitDirectiveAMDGCNTarget() override;
136
137 void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) override;
138
139 void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
140
141 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
142
143 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
144
145 void EmitMCResourceInfo(
146 const MCSymbol *NumVGPR, const MCSymbol *NumAGPR,
147 const MCSymbol *NumExplicitSGPR, const MCSymbol *NumNamedBarrier,
148 const MCSymbol *PrivateSegmentSize, const MCSymbol *UsesVCC,
149 const MCSymbol *UsesFlatScratch, const MCSymbol *HasDynamicallySizedStack,
150 const MCSymbol *HasRecursion, const MCSymbol *HasIndirectCall) override;
151
152 void EmitMCResourceMaximums(const MCSymbol *MaxVGPR, const MCSymbol *MaxAGPR,
153 const MCSymbol *MaxSGPR,
154 const MCSymbol *MaxNamedBarrier) override;
155
156 /// \returns True on success, false on failure.
157 bool EmitISAVersion() override;
158
159 /// \returns True on success, false on failure.
160 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
161
162 /// \returns True on success, false on failure.
163 bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
164
165 void
166 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
167 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
168 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
169 const MCExpr *ReserveVCC,
170 const MCExpr *ReserveFlatScr) override;
171};
172
173class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer {
174 const MCSubtargetInfo &STI;
175 MCStreamer &Streamer;
176
177 void EmitNote(StringRef Name, const MCExpr *DescSize, unsigned NoteType,
178 function_ref<void(MCELFStreamer &)> EmitDesc);
179
180 unsigned getEFlags();
181
182 unsigned getEFlagsR600();
183 unsigned getEFlagsAMDGCN();
184
185 unsigned getEFlagsUnknownOS();
186 unsigned getEFlagsAMDHSA();
187 unsigned getEFlagsAMDPAL();
188 unsigned getEFlagsMesa3D();
189
190 unsigned getEFlagsV3();
191 unsigned getEFlagsV4();
192 unsigned getEFlagsV6();
193
194public:
195 AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
196
197 MCELFStreamer &getStreamer();
198
199 void finish() override;
200
201 void EmitDirectiveAMDGCNTarget() override;
202
203 void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
204
205 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
206
207 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
208
209 /// \returns True on success, false on failure.
210 bool EmitISAVersion() override;
211
212 /// \returns True on success, false on failure.
213 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
214
215 /// \returns True on success, false on failure.
216 bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
217
218 void
219 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
220 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
221 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
222 const MCExpr *ReserveVCC,
223 const MCExpr *ReserveFlatScr) override;
224};
225}
226#endif
227