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