xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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