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_RISCVELFSTREAMER_H 10 #define LLVM_LIB_TARGET_RISCV_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