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 98 static StringRef getArchNameFromElfMach(unsigned ElfMach); 99 static unsigned getElfMach(StringRef GPU); 100 101 const std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() const { 102 return TargetID; 103 } 104 std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() { 105 return TargetID; 106 } 107 void initializeTargetID(const MCSubtargetInfo &STI) { 108 assert(TargetID == std::nullopt && "TargetID can only be initialized once"); 109 TargetID.emplace(STI); 110 } 111 void initializeTargetID(const MCSubtargetInfo &STI, StringRef FeatureString) { 112 initializeTargetID(STI); 113 114 assert(getTargetID() != std::nullopt && "TargetID is None"); 115 getTargetID()->setTargetIDFromFeaturesString(FeatureString); 116 } 117 }; 118 119 class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer { 120 formatted_raw_ostream &OS; 121 public: 122 AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); 123 124 void finish() override; 125 126 void EmitDirectiveAMDGCNTarget() override; 127 128 void EmitDirectiveHSACodeObjectVersion(uint32_t Major, 129 uint32_t Minor) override; 130 131 void EmitDirectiveHSACodeObjectISAV2(uint32_t Major, uint32_t Minor, 132 uint32_t Stepping, StringRef VendorName, 133 StringRef ArchName) override; 134 135 void EmitAMDKernelCodeT(const amd_kernel_code_t &Header) override; 136 137 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; 138 139 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override; 140 141 /// \returns True on success, false on failure. 142 bool EmitISAVersion() override; 143 144 /// \returns True on success, false on failure. 145 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override; 146 147 /// \returns True on success, false on failure. 148 bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override; 149 150 /// \returns True on success, false on failure. 151 bool EmitCodeEnd(const MCSubtargetInfo &STI) override; 152 153 void EmitAmdhsaKernelDescriptor( 154 const MCSubtargetInfo &STI, StringRef KernelName, 155 const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, 156 uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr) override; 157 }; 158 159 class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer { 160 const MCSubtargetInfo &STI; 161 MCStreamer &Streamer; 162 163 void EmitNote(StringRef Name, const MCExpr *DescSize, unsigned NoteType, 164 function_ref<void(MCELFStreamer &)> EmitDesc); 165 166 unsigned getEFlags(); 167 168 unsigned getEFlagsR600(); 169 unsigned getEFlagsAMDGCN(); 170 171 unsigned getEFlagsUnknownOS(); 172 unsigned getEFlagsAMDHSA(); 173 unsigned getEFlagsAMDPAL(); 174 unsigned getEFlagsMesa3D(); 175 176 unsigned getEFlagsV3(); 177 unsigned getEFlagsV4(); 178 179 public: 180 AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 181 182 MCELFStreamer &getStreamer(); 183 184 void finish() override; 185 186 void EmitDirectiveAMDGCNTarget() override; 187 188 void EmitDirectiveHSACodeObjectVersion(uint32_t Major, 189 uint32_t Minor) override; 190 191 void EmitDirectiveHSACodeObjectISAV2(uint32_t Major, uint32_t Minor, 192 uint32_t Stepping, StringRef VendorName, 193 StringRef ArchName) override; 194 195 void EmitAMDKernelCodeT(const amd_kernel_code_t &Header) override; 196 197 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; 198 199 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override; 200 201 /// \returns True on success, false on failure. 202 bool EmitISAVersion() override; 203 204 /// \returns True on success, false on failure. 205 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override; 206 207 /// \returns True on success, false on failure. 208 bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override; 209 210 /// \returns True on success, false on failure. 211 bool EmitCodeEnd(const MCSubtargetInfo &STI) override; 212 213 void EmitAmdhsaKernelDescriptor( 214 const MCSubtargetInfo &STI, StringRef KernelName, 215 const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, 216 uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr) override; 217 }; 218 219 } 220 #endif 221