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