1*81ad6265SDimitry Andric //===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===// 2*81ad6265SDimitry Andric // 3*81ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*81ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*81ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*81ad6265SDimitry Andric // 7*81ad6265SDimitry Andric //===----------------------------------------------------------------------===// 8*81ad6265SDimitry Andric 9*81ad6265SDimitry Andric #ifndef LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H 10*81ad6265SDimitry Andric #define LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H 11*81ad6265SDimitry Andric 12*81ad6265SDimitry Andric #include "MCTargetDesc/CSKYMCExpr.h" 13*81ad6265SDimitry Andric #include "llvm/MC/ConstantPools.h" 14*81ad6265SDimitry Andric #include "llvm/MC/MCStreamer.h" 15*81ad6265SDimitry Andric 16*81ad6265SDimitry Andric namespace llvm { 17*81ad6265SDimitry Andric 18*81ad6265SDimitry Andric class CSKYConstantPool { 19*81ad6265SDimitry Andric using EntryVecTy = SmallVector<ConstantPoolEntry, 4>; 20*81ad6265SDimitry Andric EntryVecTy Entries; 21*81ad6265SDimitry Andric std::map<int64_t, const MCSymbolRefExpr *> CachedEntries; 22*81ad6265SDimitry Andric 23*81ad6265SDimitry Andric MCSection *CurrentSection = nullptr; 24*81ad6265SDimitry Andric 25*81ad6265SDimitry Andric public: 26*81ad6265SDimitry Andric // Initialize a new empty constant pool 27*81ad6265SDimitry Andric CSKYConstantPool() = default; 28*81ad6265SDimitry Andric 29*81ad6265SDimitry Andric // Add a new entry to the constant pool in the next slot. 30*81ad6265SDimitry Andric // \param Value is the new entry to put in the constant pool. 31*81ad6265SDimitry Andric // \param Size is the size in bytes of the entry 32*81ad6265SDimitry Andric // 33*81ad6265SDimitry Andric // \returns a MCExpr that references the newly inserted value 34*81ad6265SDimitry Andric const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Value, 35*81ad6265SDimitry Andric unsigned Size, SMLoc Loc, const MCExpr *AdjustExpr); 36*81ad6265SDimitry Andric 37*81ad6265SDimitry Andric void emitAll(MCStreamer &Streamer); 38*81ad6265SDimitry Andric 39*81ad6265SDimitry Andric // Return true if the constant pool is empty 40*81ad6265SDimitry Andric bool empty(); 41*81ad6265SDimitry Andric 42*81ad6265SDimitry Andric void clearCache(); 43*81ad6265SDimitry Andric }; 44*81ad6265SDimitry Andric 45*81ad6265SDimitry Andric class CSKYTargetStreamer : public MCTargetStreamer { 46*81ad6265SDimitry Andric public: 47*81ad6265SDimitry Andric typedef struct { 48*81ad6265SDimitry Andric const MCSymbol *sym; 49*81ad6265SDimitry Andric CSKYMCExpr::VariantKind kind; 50*81ad6265SDimitry Andric } SymbolIndex; 51*81ad6265SDimitry Andric 52*81ad6265SDimitry Andric protected: 53*81ad6265SDimitry Andric std::unique_ptr<CSKYConstantPool> ConstantPool; 54*81ad6265SDimitry Andric 55*81ad6265SDimitry Andric DenseMap<SymbolIndex, const MCExpr *> ConstantMap; 56*81ad6265SDimitry Andric 57*81ad6265SDimitry Andric unsigned ConstantCounter = 0; 58*81ad6265SDimitry Andric 59*81ad6265SDimitry Andric public: 60*81ad6265SDimitry Andric CSKYTargetStreamer(MCStreamer &S); 61*81ad6265SDimitry Andric 62*81ad6265SDimitry Andric virtual void emitTextAttribute(unsigned Attribute, StringRef String); 63*81ad6265SDimitry Andric virtual void emitAttribute(unsigned Attribute, unsigned Value); 64*81ad6265SDimitry Andric virtual void finishAttributeSection(); 65*81ad6265SDimitry Andric 66*81ad6265SDimitry Andric virtual void emitTargetAttributes(const MCSubtargetInfo &STI); 67*81ad6265SDimitry Andric /// Add a new entry to the constant pool for the current section and return an 68*81ad6265SDimitry Andric /// MCExpr that can be used to refer to the constant pool location. 69*81ad6265SDimitry Andric const MCExpr *addConstantPoolEntry(const MCExpr *, SMLoc Loc, 70*81ad6265SDimitry Andric const MCExpr *AdjustExpr = nullptr); 71*81ad6265SDimitry Andric 72*81ad6265SDimitry Andric void emitCurrentConstantPool(); 73*81ad6265SDimitry Andric 74*81ad6265SDimitry Andric void finish() override; 75*81ad6265SDimitry Andric }; 76*81ad6265SDimitry Andric 77*81ad6265SDimitry Andric template <> struct DenseMapInfo<CSKYTargetStreamer::SymbolIndex> { 78*81ad6265SDimitry Andric static inline CSKYTargetStreamer::SymbolIndex getEmptyKey() { 79*81ad6265SDimitry Andric return {nullptr, CSKYMCExpr::VK_CSKY_Invalid}; 80*81ad6265SDimitry Andric } 81*81ad6265SDimitry Andric static inline CSKYTargetStreamer::SymbolIndex getTombstoneKey() { 82*81ad6265SDimitry Andric return {nullptr, CSKYMCExpr::VK_CSKY_Invalid}; 83*81ad6265SDimitry Andric } 84*81ad6265SDimitry Andric static unsigned getHashValue(const CSKYTargetStreamer::SymbolIndex &V) { 85*81ad6265SDimitry Andric return hash_combine(DenseMapInfo<const MCSymbol *>::getHashValue(V.sym), 86*81ad6265SDimitry Andric DenseMapInfo<int>::getHashValue(V.kind)); 87*81ad6265SDimitry Andric } 88*81ad6265SDimitry Andric static bool isEqual(const CSKYTargetStreamer::SymbolIndex &A, 89*81ad6265SDimitry Andric const CSKYTargetStreamer::SymbolIndex &B) { 90*81ad6265SDimitry Andric return A.sym == B.sym && A.kind == B.kind; 91*81ad6265SDimitry Andric } 92*81ad6265SDimitry Andric }; 93*81ad6265SDimitry Andric 94*81ad6265SDimitry Andric class formatted_raw_ostream; 95*81ad6265SDimitry Andric 96*81ad6265SDimitry Andric class CSKYTargetAsmStreamer : public CSKYTargetStreamer { 97*81ad6265SDimitry Andric formatted_raw_ostream &OS; 98*81ad6265SDimitry Andric 99*81ad6265SDimitry Andric void emitAttribute(unsigned Attribute, unsigned Value) override; 100*81ad6265SDimitry Andric void emitTextAttribute(unsigned Attribute, StringRef String) override; 101*81ad6265SDimitry Andric void finishAttributeSection() override; 102*81ad6265SDimitry Andric 103*81ad6265SDimitry Andric public: 104*81ad6265SDimitry Andric CSKYTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) 105*81ad6265SDimitry Andric : CSKYTargetStreamer(S), OS(OS) {} 106*81ad6265SDimitry Andric }; 107*81ad6265SDimitry Andric 108*81ad6265SDimitry Andric } // namespace llvm 109*81ad6265SDimitry Andric 110*81ad6265SDimitry Andric #endif // LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H 111