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