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