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 /// \returns True on success, false on failure.
64 virtual bool EmitISAVersion() { return true; }
65
66 /// \returns True on success, false on failure.
67 virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString);
68
69 /// Emit HSA Metadata
70 ///
71 /// When \p Strict is true, known metadata elements must already be
72 /// well-typed. When \p Strict is false, known types are inferred and
73 /// the \p HSAMetadata structure is updated with the correct types.
74 ///
75 /// \returns True on success, false on failure.
76 virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) {
77 return true;
78 }
79
80 /// \returns True on success, false on failure.
81 virtual bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) {
82 return true;
83 }
84
85 /// \returns True on success, false on failure.
86 virtual bool EmitCodeEnd(const MCSubtargetInfo &STI) { return true; }
87
88 /// \returns True on success, false on failure.
89 virtual bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI,
90 bool TrapEnabled) {
91 return true;
92 }
93
94 virtual void
95 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
96 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
97 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
98 const MCExpr *ReserveVCC,
99 const MCExpr *ReserveFlatScr) {}
100
101 static StringRef getArchNameFromElfMach(unsigned ElfMach);
102 static unsigned getElfMach(StringRef GPU);
103
104 const std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() const {
105 return TargetID;
106 }
107 std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() {
108 return TargetID;
109 }
110 void initializeTargetID(const MCSubtargetInfo &STI) {
111 assert(TargetID == std::nullopt && "TargetID can only be initialized once");
112 TargetID.emplace(args: STI);
113 }
114 void initializeTargetID(const MCSubtargetInfo &STI, StringRef FeatureString) {
115 initializeTargetID(STI);
116
117 assert(getTargetID() != std::nullopt && "TargetID is None");
118 getTargetID()->setTargetIDFromFeaturesString(FeatureString);
119 }
120};
121
122class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer {
123 formatted_raw_ostream &OS;
124public:
125 AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
126
127 void finish() override;
128
129 void EmitDirectiveAMDGCNTarget() override;
130
131 void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) override;
132
133 void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
134
135 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
136
137 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
138
139 /// \returns True on success, false on failure.
140 bool EmitISAVersion() override;
141
142 /// \returns True on success, false on failure.
143 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
144
145 /// \returns True on success, false on failure.
146 bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
147
148 /// \returns True on success, false on failure.
149 bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI,
150 bool TrapEnabled) override;
151
152 void
153 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
154 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
155 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
156 const MCExpr *ReserveVCC,
157 const MCExpr *ReserveFlatScr) override;
158};
159
160class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer {
161 const MCSubtargetInfo &STI;
162 MCStreamer &Streamer;
163
164 void EmitNote(StringRef Name, const MCExpr *DescSize, unsigned NoteType,
165 function_ref<void(MCELFStreamer &)> EmitDesc);
166
167 unsigned getEFlags();
168
169 unsigned getEFlagsR600();
170 unsigned getEFlagsAMDGCN();
171
172 unsigned getEFlagsUnknownOS();
173 unsigned getEFlagsAMDHSA();
174 unsigned getEFlagsAMDPAL();
175 unsigned getEFlagsMesa3D();
176
177 unsigned getEFlagsV3();
178 unsigned getEFlagsV4();
179 unsigned getEFlagsV6();
180
181public:
182 AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
183
184 MCELFStreamer &getStreamer();
185
186 void finish() override;
187
188 void EmitDirectiveAMDGCNTarget() override;
189
190 void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
191
192 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
193
194 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
195
196 /// \returns True on success, false on failure.
197 bool EmitISAVersion() override;
198
199 /// \returns True on success, false on failure.
200 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
201
202 /// \returns True on success, false on failure.
203 bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
204
205 /// \returns True on success, false on failure.
206 bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI,
207 bool TrapEnabled) override;
208
209 void
210 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
211 const AMDGPU::MCKernelDescriptor &KernelDescriptor,
212 const MCExpr *NextVGPR, const MCExpr *NextSGPR,
213 const MCExpr *ReserveVCC,
214 const MCExpr *ReserveFlatScr) override;
215};
216}
217#endif
218