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