1 //===-- RISCVELFStreamer.h - RISCV ELF 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_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
10 #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
11 
12 #include "RISCVTargetStreamer.h"
13 #include "llvm/MC/MCELFStreamer.h"
14 
15 using namespace llvm;
16 
17 class RISCVELFStreamer : public MCELFStreamer {
18   static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size);
19   static bool requiresFixups(MCContext &C, const MCExpr *Value,
20                              const MCExpr *&LHS, const MCExpr *&RHS);
21   void reset() override;
22 
23 public:
24   RISCVELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
25                    std::unique_ptr<MCObjectWriter> MOW,
26                    std::unique_ptr<MCCodeEmitter> MCE)
27       : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
28 
29   void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
30 };
31 
32 namespace llvm {
33 
34 class RISCVTargetELFStreamer : public RISCVTargetStreamer {
35 private:
36   enum class AttributeType { Hidden, Numeric, Text, NumericAndText };
37 
38   struct AttributeItem {
39     AttributeType Type;
40     unsigned Tag;
41     unsigned IntValue;
42     std::string StringValue;
43   };
44 
45   StringRef CurrentVendor;
46   SmallVector<AttributeItem, 64> Contents;
47 
48   MCSection *AttributeSection = nullptr;
49   const MCSubtargetInfo &STI;
50 
51   AttributeItem *getAttributeItem(unsigned Attribute) {
52     for (size_t i = 0; i < Contents.size(); ++i)
53       if (Contents[i].Tag == Attribute)
54         return &Contents[i];
55     return nullptr;
56   }
57 
58   void setAttributeItem(unsigned Attribute, unsigned Value,
59                         bool OverwriteExisting) {
60     // Look for existing attribute item.
61     if (AttributeItem *Item = getAttributeItem(Attribute)) {
62       if (!OverwriteExisting)
63         return;
64       Item->Type = AttributeType::Numeric;
65       Item->IntValue = Value;
66       return;
67     }
68 
69     // Create new attribute item.
70     Contents.push_back({AttributeType::Numeric, Attribute, Value, ""});
71   }
72 
73   void setAttributeItem(unsigned Attribute, StringRef Value,
74                         bool OverwriteExisting) {
75     // Look for existing attribute item.
76     if (AttributeItem *Item = getAttributeItem(Attribute)) {
77       if (!OverwriteExisting)
78         return;
79       Item->Type = AttributeType::Text;
80       Item->StringValue = std::string(Value);
81       return;
82     }
83 
84     // Create new attribute item.
85     Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)});
86   }
87 
88   void setAttributeItems(unsigned Attribute, unsigned IntValue,
89                          StringRef StringValue, bool OverwriteExisting) {
90     // Look for existing attribute item.
91     if (AttributeItem *Item = getAttributeItem(Attribute)) {
92       if (!OverwriteExisting)
93         return;
94       Item->Type = AttributeType::NumericAndText;
95       Item->IntValue = IntValue;
96       Item->StringValue = std::string(StringValue);
97       return;
98     }
99 
100     // Create new attribute item.
101     Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue,
102                         std::string(StringValue)});
103   }
104 
105   void emitAttribute(unsigned Attribute, unsigned Value) override;
106   void emitTextAttribute(unsigned Attribute, StringRef String) override;
107   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
108                             StringRef StringValue) override;
109   void finishAttributeSection() override;
110   size_t calculateContentSize() const;
111 
112   void reset() override;
113 
114 public:
115   RISCVELFStreamer &getStreamer();
116   RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
117 
118   void emitDirectiveOptionPush() override;
119   void emitDirectiveOptionPop() override;
120   void emitDirectiveOptionPIC() override;
121   void emitDirectiveOptionNoPIC() override;
122   void emitDirectiveOptionRVC() override;
123   void emitDirectiveOptionNoRVC() override;
124   void emitDirectiveOptionRelax() override;
125   void emitDirectiveOptionNoRelax() override;
126   void emitDirectiveVariantCC(MCSymbol &Symbol) override;
127 
128   void finish() override;
129 };
130 
131 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
132                                       std::unique_ptr<MCAsmBackend> MAB,
133                                       std::unique_ptr<MCObjectWriter> MOW,
134                                       std::unique_ptr<MCCodeEmitter> MCE,
135                                       bool RelaxAll);
136 }
137 #endif
138