//===-- RISCVELFStreamer.h - RISC-V ELF Target Streamer ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H #include "RISCVTargetStreamer.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCELFStreamer.h" namespace llvm { class RISCVELFStreamer : public MCELFStreamer { void reset() override; void emitDataMappingSymbol(); void emitInstructionsMappingSymbol(); void emitMappingSymbol(StringRef Name); enum ElfMappingSymbol { EMS_None, EMS_Instructions, EMS_Data }; DenseMap LastMappingSymbols; ElfMappingSymbol LastEMS = EMS_None; // Active ISA string propagated from RISCVTargetELFStreamer. When non-empty, // it is used as the suffix for "$x" mapping symbols. std::string MappingSymbolArch; // ISA suffix last emitted via "$x" in the current section, and the // per-section history preserved across changeSection. A new mapping symbol // is emitted whenever LastEMS != EMS_Instructions or // LastEmittedArch != MappingSymbolArch, so the ISA in effect at each // instruction run is always recorded. std::string LastEmittedArch; DenseMap LastEmittedArchInSection; public: RISCVELFStreamer(MCContext &C, std::unique_ptr MAB, std::unique_ptr MOW, std::unique_ptr MCE); void changeSection(MCSection *Section, uint32_t Subsection) override; void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; void emitBytes(StringRef Data) override; void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc) override; void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override; void setMappingSymbolArch(StringRef Arch); }; class RISCVTargetELFStreamer : public RISCVTargetStreamer { private: StringRef CurrentVendor; // Initial ISA string derived from the subtarget features in the constructor. // Used to re-establish state on reset(). std::string InitialArchString; // Current ISA string, kept in sync with each .option arch/rvc/norvc/pop // and .attribute arch directive. Used to avoid propagating redundant ISA // updates to the streamer when the ISA does not actually change (e.g., // .option rvc when C is already enabled). std::string ArchString; SmallVector ArchStringStack; MCSection *AttributeSection = nullptr; void emitAttribute(unsigned Attribute, unsigned Value) override; void emitTextAttribute(unsigned Attribute, StringRef String) override; void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) override; void finishAttributeSection() override; void reset() override; public: RISCVELFStreamer &getStreamer(); RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); // Update ArchString and propagate the change to the streamer so the next // instruction-run emits an ISA-specific mapping symbol. A no-op when // Arch == ArchString (deduplication). void setArchString(StringRef Arch) override; void emitDirectiveOptionExact() override; void emitDirectiveOptionNoExact() override; void emitDirectiveOptionPIC() override; void emitDirectiveOptionNoPIC() override; void emitDirectiveOptionPop() override; void emitDirectiveOptionPush() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; void emitDirectiveOptionRVC() override; void emitDirectiveOptionNoRVC() override; void emitDirectiveVariantCC(MCSymbol &Symbol) override; void emitNoteGnuPropertySection(const uint32_t Feature1And); void finish() override; }; MCStreamer *createRISCVELFStreamer(const Triple &, MCContext &C, std::unique_ptr &&MAB, std::unique_ptr &&MOW, std::unique_ptr &&MCE); } // namespace llvm #endif // LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H