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