#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVELFSTREAMER_H
#include "RISCVTargetStreamer.h"
#include "llvm/MC/MCELFStreamer.h"
namespace llvm {
class RISCVTargetELFStreamer : public RISCVTargetStreamer {
private:
enum class AttributeType { Hidden, Numeric, Text, NumericAndText };
struct AttributeItem {
AttributeType Type;
unsigned Tag;
unsigned IntValue;
std::string StringValue;
};
StringRef CurrentVendor;
SmallVector<AttributeItem, 64> Contents;
MCSection *AttributeSection = nullptr;
const MCSubtargetInfo &STI;
AttributeItem *getAttributeItem(unsigned Attribute) {
for (size_t i = 0; i < Contents.size(); ++i)
if (Contents[i].Tag == Attribute)
return &Contents[i];
return nullptr;
}
void setAttributeItem(unsigned Attribute, unsigned Value,
bool OverwriteExisting) {
if (AttributeItem *Item = getAttributeItem(Attribute)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeType::Numeric;
Item->IntValue = Value;
return;
}
Contents.push_back({AttributeType::Numeric, Attribute, Value, ""});
}
void setAttributeItem(unsigned Attribute, StringRef Value,
bool OverwriteExisting) {
if (AttributeItem *Item = getAttributeItem(Attribute)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeType::Text;
Item->StringValue = std::string(Value);
return;
}
Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)});
}
void setAttributeItems(unsigned Attribute, unsigned IntValue,
StringRef StringValue, bool OverwriteExisting) {
if (AttributeItem *Item = getAttributeItem(Attribute)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeType::NumericAndText;
Item->IntValue = IntValue;
Item->StringValue = std::string(StringValue);
return;
}
Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue,
std::string(StringValue)});
}
void emitAttribute(unsigned Attribute, unsigned Value) override;
void emitTextAttribute(unsigned Attribute, StringRef String) override;
void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
StringRef StringValue) override;
void finishAttributeSection() override;
size_t calculateContentSize() const;
void reset() override;
public:
MCELFStreamer &getStreamer();
RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
void emitDirectiveOptionPush() override;
void emitDirectiveOptionPop() override;
void emitDirectiveOptionPIC() override;
void emitDirectiveOptionNoPIC() override;
void emitDirectiveOptionRVC() override;
void emitDirectiveOptionNoRVC() override;
void emitDirectiveOptionRelax() override;
void emitDirectiveOptionNoRelax() override;
void finish() override;
};
MCELFStreamer *createRISCVELFStreamer(MCContext &C,
std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> MOW,
std::unique_ptr<MCCodeEmitter> MCE,
bool RelaxAll);
}
#endif