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