xref: /openbsd-src/gnu/llvm/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- RISCVELFStreamer.h - RISCV ELF Target Streamer ---------*- C++ -*--===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
9*d415bd75Srobert #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
10*d415bd75Srobert #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
1109467b48Spatrick 
1209467b48Spatrick #include "RISCVTargetStreamer.h"
1309467b48Spatrick #include "llvm/MC/MCELFStreamer.h"
1409467b48Spatrick 
15*d415bd75Srobert using namespace llvm;
16*d415bd75Srobert 
17*d415bd75Srobert class RISCVELFStreamer : public MCELFStreamer {
18*d415bd75Srobert   static std::pair<unsigned, unsigned> getRelocPairForSize(unsigned Size);
19*d415bd75Srobert   static bool requiresFixups(MCContext &C, const MCExpr *Value,
20*d415bd75Srobert                              const MCExpr *&LHS, const MCExpr *&RHS);
21*d415bd75Srobert   void reset() override;
22*d415bd75Srobert 
23*d415bd75Srobert public:
RISCVELFStreamer(MCContext & C,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> MOW,std::unique_ptr<MCCodeEmitter> MCE)24*d415bd75Srobert   RISCVELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
25*d415bd75Srobert                    std::unique_ptr<MCObjectWriter> MOW,
26*d415bd75Srobert                    std::unique_ptr<MCCodeEmitter> MCE)
27*d415bd75Srobert       : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
28*d415bd75Srobert 
29*d415bd75Srobert   void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
30*d415bd75Srobert };
31*d415bd75Srobert 
3209467b48Spatrick namespace llvm {
3309467b48Spatrick 
3409467b48Spatrick class RISCVTargetELFStreamer : public RISCVTargetStreamer {
35097a140dSpatrick private:
36097a140dSpatrick   enum class AttributeType { Hidden, Numeric, Text, NumericAndText };
37097a140dSpatrick 
38097a140dSpatrick   struct AttributeItem {
39097a140dSpatrick     AttributeType Type;
40097a140dSpatrick     unsigned Tag;
41097a140dSpatrick     unsigned IntValue;
42097a140dSpatrick     std::string StringValue;
43097a140dSpatrick   };
44097a140dSpatrick 
45097a140dSpatrick   StringRef CurrentVendor;
46097a140dSpatrick   SmallVector<AttributeItem, 64> Contents;
47097a140dSpatrick 
48097a140dSpatrick   MCSection *AttributeSection = nullptr;
49*d415bd75Srobert   const MCSubtargetInfo &STI;
50097a140dSpatrick 
getAttributeItem(unsigned Attribute)51097a140dSpatrick   AttributeItem *getAttributeItem(unsigned Attribute) {
52097a140dSpatrick     for (size_t i = 0; i < Contents.size(); ++i)
53097a140dSpatrick       if (Contents[i].Tag == Attribute)
54097a140dSpatrick         return &Contents[i];
55097a140dSpatrick     return nullptr;
56097a140dSpatrick   }
57097a140dSpatrick 
setAttributeItem(unsigned Attribute,unsigned Value,bool OverwriteExisting)58097a140dSpatrick   void setAttributeItem(unsigned Attribute, unsigned Value,
59097a140dSpatrick                         bool OverwriteExisting) {
60097a140dSpatrick     // Look for existing attribute item.
61097a140dSpatrick     if (AttributeItem *Item = getAttributeItem(Attribute)) {
62097a140dSpatrick       if (!OverwriteExisting)
63097a140dSpatrick         return;
64097a140dSpatrick       Item->Type = AttributeType::Numeric;
65097a140dSpatrick       Item->IntValue = Value;
66097a140dSpatrick       return;
67097a140dSpatrick     }
68097a140dSpatrick 
69097a140dSpatrick     // Create new attribute item.
70097a140dSpatrick     Contents.push_back({AttributeType::Numeric, Attribute, Value, ""});
71097a140dSpatrick   }
72097a140dSpatrick 
setAttributeItem(unsigned Attribute,StringRef Value,bool OverwriteExisting)73097a140dSpatrick   void setAttributeItem(unsigned Attribute, StringRef Value,
74097a140dSpatrick                         bool OverwriteExisting) {
75097a140dSpatrick     // Look for existing attribute item.
76097a140dSpatrick     if (AttributeItem *Item = getAttributeItem(Attribute)) {
77097a140dSpatrick       if (!OverwriteExisting)
78097a140dSpatrick         return;
79097a140dSpatrick       Item->Type = AttributeType::Text;
80097a140dSpatrick       Item->StringValue = std::string(Value);
81097a140dSpatrick       return;
82097a140dSpatrick     }
83097a140dSpatrick 
84097a140dSpatrick     // Create new attribute item.
85097a140dSpatrick     Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)});
86097a140dSpatrick   }
87097a140dSpatrick 
setAttributeItems(unsigned Attribute,unsigned IntValue,StringRef StringValue,bool OverwriteExisting)88097a140dSpatrick   void setAttributeItems(unsigned Attribute, unsigned IntValue,
89097a140dSpatrick                          StringRef StringValue, bool OverwriteExisting) {
90097a140dSpatrick     // Look for existing attribute item.
91097a140dSpatrick     if (AttributeItem *Item = getAttributeItem(Attribute)) {
92097a140dSpatrick       if (!OverwriteExisting)
93097a140dSpatrick         return;
94097a140dSpatrick       Item->Type = AttributeType::NumericAndText;
95097a140dSpatrick       Item->IntValue = IntValue;
96097a140dSpatrick       Item->StringValue = std::string(StringValue);
97097a140dSpatrick       return;
98097a140dSpatrick     }
99097a140dSpatrick 
100097a140dSpatrick     // Create new attribute item.
101097a140dSpatrick     Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue,
102097a140dSpatrick                         std::string(StringValue)});
103097a140dSpatrick   }
104097a140dSpatrick 
105097a140dSpatrick   void emitAttribute(unsigned Attribute, unsigned Value) override;
106097a140dSpatrick   void emitTextAttribute(unsigned Attribute, StringRef String) override;
107097a140dSpatrick   void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
108097a140dSpatrick                             StringRef StringValue) override;
109097a140dSpatrick   void finishAttributeSection() override;
110097a140dSpatrick   size_t calculateContentSize() const;
111097a140dSpatrick 
112*d415bd75Srobert   void reset() override;
113*d415bd75Srobert 
11409467b48Spatrick public:
115*d415bd75Srobert   RISCVELFStreamer &getStreamer();
11609467b48Spatrick   RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
11709467b48Spatrick 
118097a140dSpatrick   void emitDirectiveOptionPush() override;
119097a140dSpatrick   void emitDirectiveOptionPop() override;
120097a140dSpatrick   void emitDirectiveOptionPIC() override;
121097a140dSpatrick   void emitDirectiveOptionNoPIC() override;
122097a140dSpatrick   void emitDirectiveOptionRVC() override;
123097a140dSpatrick   void emitDirectiveOptionNoRVC() override;
124097a140dSpatrick   void emitDirectiveOptionRelax() override;
125097a140dSpatrick   void emitDirectiveOptionNoRelax() override;
126*d415bd75Srobert   void emitDirectiveVariantCC(MCSymbol &Symbol) override;
127*d415bd75Srobert 
128*d415bd75Srobert   void finish() override;
12909467b48Spatrick };
13073471bf0Spatrick 
13173471bf0Spatrick MCELFStreamer *createRISCVELFStreamer(MCContext &C,
13273471bf0Spatrick                                       std::unique_ptr<MCAsmBackend> MAB,
13373471bf0Spatrick                                       std::unique_ptr<MCObjectWriter> MOW,
13473471bf0Spatrick                                       std::unique_ptr<MCCodeEmitter> MCE,
13573471bf0Spatrick                                       bool RelaxAll);
13609467b48Spatrick }
13709467b48Spatrick #endif
138