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 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 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 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 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 int64_t MappingSymbolCounter = 0; 103 104 void EmitMappingSymbol(StringRef Name); 105 106 public: 107 friend class CSKYTargetELFStreamer; 108 109 enum ElfMappingSymbol { EMS_None, EMS_Text, EMS_Data }; 110 111 ElfMappingSymbol State; 112 113 CSKYELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 114 std::unique_ptr<MCObjectWriter> OW, 115 std::unique_ptr<MCCodeEmitter> Emitter) 116 : MCELFStreamer(Context, std::move(TAB), std::move(OW), 117 std::move(Emitter)), 118 State(EMS_None) {} 119 120 ~CSKYELFStreamer() override = default; 121 122 void emitFill(const MCExpr &NumBytes, uint64_t FillValue, 123 SMLoc Loc) override { 124 EmitMappingSymbol("$d"); 125 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc); 126 } 127 void emitBytes(StringRef Data) override { 128 EmitMappingSymbol("$d"); 129 MCELFStreamer::emitBytes(Data); 130 } 131 void emitInstruction(const MCInst &Inst, 132 const MCSubtargetInfo &STI) override { 133 EmitMappingSymbol("$t"); 134 MCELFStreamer::emitInstruction(Inst, STI); 135 } 136 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 137 EmitMappingSymbol("$d"); 138 MCELFStreamer::emitValueImpl(Value, Size, Loc); 139 } 140 void reset() override { 141 MappingSymbolCounter = 0; 142 State = EMS_None; 143 MCELFStreamer::reset(); 144 } 145 }; 146 147 } // namespace llvm 148 #endif 149