146 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_TARGET_CSKY_CSKYELFSTREAMER_H10#define LLVM_LIB_TARGET_CSKY_CSKYELFSTREAMER_H11 12#include "CSKYTargetStreamer.h"13#include "llvm/MC/MCCodeEmitter.h"14#include "llvm/MC/MCELFStreamer.h"15#include "llvm/MC/MCObjectWriter.h"16 17namespace llvm {18 19class CSKYTargetELFStreamer : public CSKYTargetStreamer {20private: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 96public:97 MCELFStreamer &getStreamer();98 CSKYTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);99};100 101class CSKYELFStreamer : public MCELFStreamer {102 void EmitMappingSymbol(StringRef Name);103 104public:105 friend class CSKYTargetELFStreamer;106 107 enum ElfMappingSymbol { EMS_None, EMS_Text, EMS_Data };108 109 ElfMappingSymbol State;110 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 120 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,121 SMLoc Loc) override {122 EmitMappingSymbol("$d");123 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);124 }125 void emitBytes(StringRef Data) override {126 EmitMappingSymbol("$d");127 MCELFStreamer::emitBytes(Data);128 }129 void emitInstruction(const MCInst &Inst,130 const MCSubtargetInfo &STI) override {131 EmitMappingSymbol("$t");132 MCELFStreamer::emitInstruction(Inst, STI);133 }134 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {135 EmitMappingSymbol("$d");136 MCELFStreamer::emitValueImpl(Value, Size, Loc);137 }138 void reset() override {139 State = EMS_None;140 MCELFStreamer::reset();141 }142};143 144} // namespace llvm145#endif146