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