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