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