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