1 //===-- CSKYELFStreamer.h - CSKY 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_CSKY_CSKYELFSTREAMER_H 10 #define LLVM_LIB_TARGET_CSKY_CSKYELFSTREAMER_H 11 12 #include "CSKYTargetStreamer.h" 13 #include "llvm/MC/MCCodeEmitter.h" 14 #include "llvm/MC/MCELFStreamer.h" 15 #include "llvm/MC/MCObjectWriter.h" 16 17 namespace llvm { 18 19 class CSKYTargetELFStreamer : public CSKYTargetStreamer { 20 private: 21 enum class AttributeType { Hidden, Numeric, Text, NumericAndText }; 22 23 struct AttributeItem { 24 AttributeType Type; 25 unsigned Tag; 26 unsigned IntValue; 27 std::string StringValue; 28 }; 29 30 StringRef CurrentVendor; 31 SmallVector<AttributeItem, 64> Contents; 32 33 MCSection *AttributeSection = nullptr; 34 getAttributeItem(unsigned Attribute)35 AttributeItem *getAttributeItem(unsigned Attribute) { 36 for (size_t i = 0; i < Contents.size(); ++i) 37 if (Contents[i].Tag == Attribute) 38 return &Contents[i]; 39 return nullptr; 40 } 41 setAttributeItem(unsigned Attribute,unsigned Value,bool OverwriteExisting)42 void setAttributeItem(unsigned Attribute, unsigned Value, 43 bool OverwriteExisting) { 44 // Look for existing attribute item. 45 if (AttributeItem *Item = getAttributeItem(Attribute)) { 46 if (!OverwriteExisting) 47 return; 48 Item->Type = AttributeType::Numeric; 49 Item->IntValue = Value; 50 return; 51 } 52 53 // Create new attribute item. 54 Contents.push_back({AttributeType::Numeric, Attribute, Value, ""}); 55 } 56 setAttributeItem(unsigned Attribute,StringRef Value,bool OverwriteExisting)57 void setAttributeItem(unsigned Attribute, StringRef Value, 58 bool OverwriteExisting) { 59 // Look for existing attribute item. 60 if (AttributeItem *Item = getAttributeItem(Attribute)) { 61 if (!OverwriteExisting) 62 return; 63 Item->Type = AttributeType::Text; 64 Item->StringValue = std::string(Value); 65 return; 66 } 67 68 // Create new attribute item. 69 Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)}); 70 } 71 setAttributeItems(unsigned Attribute,unsigned IntValue,StringRef StringValue,bool OverwriteExisting)72 void setAttributeItems(unsigned Attribute, unsigned IntValue, 73 StringRef StringValue, bool OverwriteExisting) { 74 // Look for existing attribute item. 75 if (AttributeItem *Item = getAttributeItem(Attribute)) { 76 if (!OverwriteExisting) 77 return; 78 Item->Type = AttributeType::NumericAndText; 79 Item->IntValue = IntValue; 80 Item->StringValue = std::string(StringValue); 81 return; 82 } 83 84 // Create new attribute item. 85 Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue, 86 std::string(StringValue)}); 87 } 88 89 void emitAttribute(unsigned Attribute, unsigned Value) override; 90 void emitTextAttribute(unsigned Attribute, StringRef String) override; 91 void finishAttributeSection() override; 92 size_t calculateContentSize() const; 93 94 void emitTargetAttributes(const MCSubtargetInfo &STI) override; 95 96 public: 97 MCELFStreamer &getStreamer(); 98 CSKYTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); 99 }; 100 101 class CSKYELFStreamer : public MCELFStreamer { 102 void EmitMappingSymbol(StringRef Name); 103 104 public: 105 friend class CSKYTargetELFStreamer; 106 107 enum ElfMappingSymbol { EMS_None, EMS_Text, EMS_Data }; 108 109 ElfMappingSymbol State; 110 CSKYELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)111 CSKYELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 112 std::unique_ptr<MCObjectWriter> OW, 113 std::unique_ptr<MCCodeEmitter> Emitter) 114 : MCELFStreamer(Context, std::move(TAB), std::move(OW), 115 std::move(Emitter)), 116 State(EMS_None) {} 117 118 ~CSKYELFStreamer() override = default; 119 emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)120 void emitFill(const MCExpr &NumBytes, uint64_t FillValue, 121 SMLoc Loc) override { 122 EmitMappingSymbol("$d"); 123 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc); 124 } emitBytes(StringRef Data)125 void emitBytes(StringRef Data) override { 126 EmitMappingSymbol("$d"); 127 MCELFStreamer::emitBytes(Data); 128 } emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)129 void emitInstruction(const MCInst &Inst, 130 const MCSubtargetInfo &STI) override { 131 EmitMappingSymbol("$t"); 132 MCELFStreamer::emitInstruction(Inst, STI); 133 } emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)134 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 135 EmitMappingSymbol("$d"); 136 MCELFStreamer::emitValueImpl(Value, Size, Loc); 137 } reset()138 void reset() override { 139 State = EMS_None; 140 MCELFStreamer::reset(); 141 } 142 }; 143 144 } // namespace llvm 145 #endif 146