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 namespace llvm { 17 18 class MCELFStreamer; 19 class MCSymbol; 20 class formatted_raw_ostream; 21 22 namespace AMDGPU { 23 24 struct AMDGPUMCKernelCodeT; 25 struct MCKernelDescriptor; 26 namespace HSAMD { 27 struct Metadata; 28 } 29 } // namespace AMDGPU 30 31 class AMDGPUTargetStreamer : public MCTargetStreamer { 32 AMDGPUPALMetadata PALMetadata; 33 34 protected: 35 // TODO: Move HSAMetadataStream to AMDGPUTargetStreamer. 36 std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> TargetID; 37 unsigned CodeObjectVersion; 38 39 MCContext &getContext() const { return Streamer.getContext(); } 40 41 public: 42 AMDGPUTargetStreamer(MCStreamer &S) 43 : MCTargetStreamer(S), 44 // Assume the default COV for now, EmitDirectiveAMDHSACodeObjectVersion 45 // will update this if it is encountered. 46 CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {} 47 48 AMDGPUPALMetadata *getPALMetadata() { return &PALMetadata; } 49 50 virtual void EmitDirectiveAMDGCNTarget(){}; 51 52 virtual void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) { 53 CodeObjectVersion = COV; 54 } 55 56 virtual void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) {}; 57 58 virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type){}; 59 60 virtual void emitAMDGPULDS(MCSymbol *Symbol, unsigned Size, Align Alignment) { 61 } 62 63 /// \returns True on success, false on failure. 64 virtual bool EmitISAVersion() { return true; } 65 66 /// \returns True on success, false on failure. 67 virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString); 68 69 /// Emit HSA Metadata 70 /// 71 /// When \p Strict is true, known metadata elements must already be 72 /// well-typed. When \p Strict is false, known types are inferred and 73 /// the \p HSAMetadata structure is updated with the correct types. 74 /// 75 /// \returns True on success, false on failure. 76 virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) { 77 return true; 78 } 79 80 /// \returns True on success, false on failure. 81 virtual bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) { 82 return true; 83 } 84 85 /// \returns True on success, false on failure. 86 virtual bool EmitCodeEnd(const MCSubtargetInfo &STI) { return true; } 87 88 /// \returns True on success, false on failure. 89 virtual bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI, 90 bool TrapEnabled) { 91 return true; 92 } 93 94 virtual void 95 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 96 const AMDGPU::MCKernelDescriptor &KernelDescriptor, 97 const MCExpr *NextVGPR, const MCExpr *NextSGPR, 98 const MCExpr *ReserveVCC, 99 const MCExpr *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(AMDGPU::AMDGPUMCKernelCodeT &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, 150 bool TrapEnabled) override; 151 152 void 153 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 154 const AMDGPU::MCKernelDescriptor &KernelDescriptor, 155 const MCExpr *NextVGPR, const MCExpr *NextSGPR, 156 const MCExpr *ReserveVCC, 157 const MCExpr *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 unsigned getEFlagsV6(); 180 181 public: 182 AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 183 184 MCELFStreamer &getStreamer(); 185 186 void finish() override; 187 188 void EmitDirectiveAMDGCNTarget() override; 189 190 void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override; 191 192 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; 193 194 void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override; 195 196 /// \returns True on success, false on failure. 197 bool EmitISAVersion() override; 198 199 /// \returns True on success, false on failure. 200 bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override; 201 202 /// \returns True on success, false on failure. 203 bool EmitCodeEnd(const MCSubtargetInfo &STI) override; 204 205 /// \returns True on success, false on failure. 206 bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI, 207 bool TrapEnabled) override; 208 209 void 210 EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 211 const AMDGPU::MCKernelDescriptor &KernelDescriptor, 212 const MCExpr *NextVGPR, const MCExpr *NextSGPR, 213 const MCExpr *ReserveVCC, 214 const MCExpr *ReserveFlatScr) override; 215 }; 216 } 217 #endif 218