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