10b57cec5SDimitry Andric //===-- AMDGPUTargetStreamer.h - AMDGPU Target Streamer --------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H 100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H 110b57cec5SDimitry Andric 12fe6060f1SDimitry Andric #include "Utils/AMDGPUBaseInfo.h" 130b57cec5SDimitry Andric #include "Utils/AMDGPUPALMetadata.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 15e8d8bef9SDimitry Andric 160b57cec5SDimitry Andric namespace llvm { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric class MCELFStreamer; 190b57cec5SDimitry Andric class MCSymbol; 20fe6060f1SDimitry Andric class formatted_raw_ostream; 210b57cec5SDimitry Andric 22e8d8bef9SDimitry Andric namespace AMDGPU { 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric struct AMDGPUMCKernelCodeT; 25*0fca6ea1SDimitry Andric struct MCKernelDescriptor; 26e8d8bef9SDimitry Andric namespace HSAMD { 27e8d8bef9SDimitry Andric struct Metadata; 28e8d8bef9SDimitry Andric } 29e8d8bef9SDimitry Andric } // namespace AMDGPU 30e8d8bef9SDimitry Andric 310b57cec5SDimitry Andric class AMDGPUTargetStreamer : public MCTargetStreamer { 320b57cec5SDimitry Andric AMDGPUPALMetadata PALMetadata; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric protected: 35fe6060f1SDimitry Andric // TODO: Move HSAMetadataStream to AMDGPUTargetStreamer. 36bdd1243dSDimitry Andric std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> TargetID; 377a6dacacSDimitry Andric unsigned CodeObjectVersion; 38fe6060f1SDimitry Andric getContext()390b57cec5SDimitry Andric MCContext &getContext() const { return Streamer.getContext(); } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric public: AMDGPUTargetStreamer(MCStreamer & S)427a6dacacSDimitry Andric AMDGPUTargetStreamer(MCStreamer &S) 437a6dacacSDimitry Andric : MCTargetStreamer(S), 447a6dacacSDimitry Andric // Assume the default COV for now, EmitDirectiveAMDHSACodeObjectVersion 457a6dacacSDimitry Andric // will update this if it is encountered. 467a6dacacSDimitry Andric CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {} 470b57cec5SDimitry Andric getPALMetadata()480b57cec5SDimitry Andric AMDGPUPALMetadata *getPALMetadata() { return &PALMetadata; } 490b57cec5SDimitry Andric EmitDirectiveAMDGCNTarget()50bdd1243dSDimitry Andric virtual void EmitDirectiveAMDGCNTarget(){}; 510b57cec5SDimitry Andric EmitDirectiveAMDHSACodeObjectVersion(unsigned COV)527a6dacacSDimitry Andric virtual void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) { 537a6dacacSDimitry Andric CodeObjectVersion = COV; 547a6dacacSDimitry Andric } 550b57cec5SDimitry Andric EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT & Header)56*0fca6ea1SDimitry Andric virtual void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) {}; 570b57cec5SDimitry Andric EmitAMDGPUSymbolType(StringRef SymbolName,unsigned Type)58bdd1243dSDimitry Andric virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type){}; 590b57cec5SDimitry Andric emitAMDGPULDS(MCSymbol * Symbol,unsigned Size,Align Alignment)60bdd1243dSDimitry Andric virtual void emitAMDGPULDS(MCSymbol *Symbol, unsigned Size, Align Alignment) { 61bdd1243dSDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// \returns True on success, false on failure. EmitISAVersion()64bdd1243dSDimitry Andric virtual bool EmitISAVersion() { return true; } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// \returns True on success, false on failure. 670b57cec5SDimitry Andric virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString); 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric /// Emit HSA Metadata 700b57cec5SDimitry Andric /// 710b57cec5SDimitry Andric /// When \p Strict is true, known metadata elements must already be 720b57cec5SDimitry Andric /// well-typed. When \p Strict is false, known types are inferred and 730b57cec5SDimitry Andric /// the \p HSAMetadata structure is updated with the correct types. 740b57cec5SDimitry Andric /// 750b57cec5SDimitry Andric /// \returns True on success, false on failure. EmitHSAMetadata(msgpack::Document & HSAMetadata,bool Strict)76bdd1243dSDimitry Andric virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) { 77bdd1243dSDimitry Andric return true; 78bdd1243dSDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// \returns True on success, false on failure. EmitHSAMetadata(const AMDGPU::HSAMD::Metadata & HSAMetadata)81bdd1243dSDimitry Andric virtual bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) { 82bdd1243dSDimitry Andric return true; 83bdd1243dSDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// \returns True on success, false on failure. EmitCodeEnd(const MCSubtargetInfo & STI)86bdd1243dSDimitry Andric virtual bool EmitCodeEnd(const MCSubtargetInfo &STI) { return true; } 870b57cec5SDimitry Andric 885f757f3fSDimitry Andric /// \returns True on success, false on failure. EmitKernargPreloadHeader(const MCSubtargetInfo & STI,bool TrapEnabled)89*0fca6ea1SDimitry Andric virtual bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI, 90*0fca6ea1SDimitry Andric bool TrapEnabled) { 915f757f3fSDimitry Andric return true; 925f757f3fSDimitry Andric } 935f757f3fSDimitry Andric 94*0fca6ea1SDimitry Andric virtual void EmitAmdhsaKernelDescriptor(const MCSubtargetInfo & STI,StringRef KernelName,const AMDGPU::MCKernelDescriptor & KernelDescriptor,const MCExpr * NextVGPR,const MCExpr * NextSGPR,const MCExpr * ReserveVCC,const MCExpr * ReserveFlatScr)95*0fca6ea1SDimitry Andric EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 96*0fca6ea1SDimitry Andric const AMDGPU::MCKernelDescriptor &KernelDescriptor, 97*0fca6ea1SDimitry Andric const MCExpr *NextVGPR, const MCExpr *NextSGPR, 98*0fca6ea1SDimitry Andric const MCExpr *ReserveVCC, 99*0fca6ea1SDimitry Andric const MCExpr *ReserveFlatScr) {} 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric static StringRef getArchNameFromElfMach(unsigned ElfMach); 1020b57cec5SDimitry Andric static unsigned getElfMach(StringRef GPU); 103fe6060f1SDimitry Andric getTargetID()104bdd1243dSDimitry Andric const std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() const { 105fe6060f1SDimitry Andric return TargetID; 106fe6060f1SDimitry Andric } getTargetID()107bdd1243dSDimitry Andric std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() { 108fe6060f1SDimitry Andric return TargetID; 109fe6060f1SDimitry Andric } initializeTargetID(const MCSubtargetInfo & STI)1107a6dacacSDimitry Andric void initializeTargetID(const MCSubtargetInfo &STI) { 111bdd1243dSDimitry Andric assert(TargetID == std::nullopt && "TargetID can only be initialized once"); 112fe6060f1SDimitry Andric TargetID.emplace(STI); 113fe6060f1SDimitry Andric } initializeTargetID(const MCSubtargetInfo & STI,StringRef FeatureString)1147a6dacacSDimitry Andric void initializeTargetID(const MCSubtargetInfo &STI, StringRef FeatureString) { 1157a6dacacSDimitry Andric initializeTargetID(STI); 116fe6060f1SDimitry Andric 117bdd1243dSDimitry Andric assert(getTargetID() != std::nullopt && "TargetID is None"); 118fe6060f1SDimitry Andric getTargetID()->setTargetIDFromFeaturesString(FeatureString); 119fe6060f1SDimitry Andric } 1200b57cec5SDimitry Andric }; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer { 1230b57cec5SDimitry Andric formatted_raw_ostream &OS; 1240b57cec5SDimitry Andric public: 1250b57cec5SDimitry Andric AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric void finish() override; 1280b57cec5SDimitry Andric 129fe6060f1SDimitry Andric void EmitDirectiveAMDGCNTarget() override; 1300b57cec5SDimitry Andric 1317a6dacacSDimitry Andric void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) override; 1320b57cec5SDimitry Andric 133*0fca6ea1SDimitry Andric void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; 1360b57cec5SDimitry Andric 1375ffd83dbSDimitry Andric void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// \returns True on success, false on failure. 140fe6060f1SDimitry Andric bool EmitISAVersion() override; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /// \returns True on success, false on failure. 1430b57cec5SDimitry Andric bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric /// \returns True on success, false on failure. 146fe6060f1SDimitry Andric bool EmitCodeEnd(const MCSubtargetInfo &STI) override; 1470b57cec5SDimitry Andric 1485f757f3fSDimitry Andric /// \returns True on success, false on failure. 149*0fca6ea1SDimitry Andric bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI, 150*0fca6ea1SDimitry Andric bool TrapEnabled) override; 1515f757f3fSDimitry Andric 152*0fca6ea1SDimitry Andric void 153*0fca6ea1SDimitry Andric EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 154*0fca6ea1SDimitry Andric const AMDGPU::MCKernelDescriptor &KernelDescriptor, 155*0fca6ea1SDimitry Andric const MCExpr *NextVGPR, const MCExpr *NextSGPR, 156*0fca6ea1SDimitry Andric const MCExpr *ReserveVCC, 157*0fca6ea1SDimitry Andric const MCExpr *ReserveFlatScr) override; 1580b57cec5SDimitry Andric }; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer { 161fe6060f1SDimitry Andric const MCSubtargetInfo &STI; 1620b57cec5SDimitry Andric MCStreamer &Streamer; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric void EmitNote(StringRef Name, const MCExpr *DescSize, unsigned NoteType, 1650b57cec5SDimitry Andric function_ref<void(MCELFStreamer &)> EmitDesc); 1660b57cec5SDimitry Andric 167fe6060f1SDimitry Andric unsigned getEFlags(); 168fe6060f1SDimitry Andric 169fe6060f1SDimitry Andric unsigned getEFlagsR600(); 170fe6060f1SDimitry Andric unsigned getEFlagsAMDGCN(); 171fe6060f1SDimitry Andric 172fe6060f1SDimitry Andric unsigned getEFlagsUnknownOS(); 173fe6060f1SDimitry Andric unsigned getEFlagsAMDHSA(); 174fe6060f1SDimitry Andric unsigned getEFlagsAMDPAL(); 175fe6060f1SDimitry Andric unsigned getEFlagsMesa3D(); 176fe6060f1SDimitry Andric 177fe6060f1SDimitry Andric unsigned getEFlagsV3(); 178fe6060f1SDimitry Andric unsigned getEFlagsV4(); 179*0fca6ea1SDimitry Andric unsigned getEFlagsV6(); 180fe6060f1SDimitry Andric 1810b57cec5SDimitry Andric public: 1820b57cec5SDimitry Andric AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric MCELFStreamer &getStreamer(); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void finish() override; 1870b57cec5SDimitry Andric 188fe6060f1SDimitry Andric void EmitDirectiveAMDGCNTarget() override; 1890b57cec5SDimitry Andric 190*0fca6ea1SDimitry Andric void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; 1930b57cec5SDimitry Andric 1945ffd83dbSDimitry Andric void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// \returns True on success, false on failure. 197fe6060f1SDimitry Andric bool EmitISAVersion() override; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// \returns True on success, false on failure. 2000b57cec5SDimitry Andric bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// \returns True on success, false on failure. 203fe6060f1SDimitry Andric bool EmitCodeEnd(const MCSubtargetInfo &STI) override; 2040b57cec5SDimitry Andric 2055f757f3fSDimitry Andric /// \returns True on success, false on failure. 206*0fca6ea1SDimitry Andric bool EmitKernargPreloadHeader(const MCSubtargetInfo &STI, 207*0fca6ea1SDimitry Andric bool TrapEnabled) override; 2085f757f3fSDimitry Andric 209*0fca6ea1SDimitry Andric void 210*0fca6ea1SDimitry Andric EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, 211*0fca6ea1SDimitry Andric const AMDGPU::MCKernelDescriptor &KernelDescriptor, 212*0fca6ea1SDimitry Andric const MCExpr *NextVGPR, const MCExpr *NextSGPR, 213*0fca6ea1SDimitry Andric const MCExpr *ReserveVCC, 214*0fca6ea1SDimitry Andric const MCExpr *ReserveFlatScr) override; 2150b57cec5SDimitry Andric }; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric #endif 218