llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.h
Zi Xuan Wu 3297758901 [CSKY] Enable TargetAsmStreamer/ELFStreamer and support asm directive of csky_attribute
Add support of parsing .csky_attribute directive and emit related target attributes in .csky.attribute section.
It does not emit attribute directive in assembly code, so only emit target attributes in ELF streamer.
In ELF streamer, it handles the header EFlag and the csky_attribute section which contains some attribute items.
The EFlag and attribute items are calculated from feature bits based on Subtarget.
2022-03-08 14:00:38 +08:00

111 lines
3.5 KiB
C++

//===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H
#define LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H
#include "MCTargetDesc/CSKYMCExpr.h"
#include "llvm/MC/ConstantPools.h"
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class CSKYConstantPool {
using EntryVecTy = SmallVector<ConstantPoolEntry, 4>;
EntryVecTy Entries;
std::map<int64_t, const MCSymbolRefExpr *> CachedEntries;
MCSection *CurrentSection = nullptr;
public:
// Initialize a new empty constant pool
CSKYConstantPool() = default;
// Add a new entry to the constant pool in the next slot.
// \param Value is the new entry to put in the constant pool.
// \param Size is the size in bytes of the entry
//
// \returns a MCExpr that references the newly inserted value
const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Value,
unsigned Size, SMLoc Loc, const MCExpr *AdjustExpr);
void emitAll(MCStreamer &Streamer);
// Return true if the constant pool is empty
bool empty();
void clearCache();
};
class CSKYTargetStreamer : public MCTargetStreamer {
public:
typedef struct {
const MCSymbol *sym;
CSKYMCExpr::VariantKind kind;
} SymbolIndex;
protected:
std::unique_ptr<CSKYConstantPool> ConstantPool;
DenseMap<SymbolIndex, const MCExpr *> ConstantMap;
unsigned ConstantCounter = 0;
public:
CSKYTargetStreamer(MCStreamer &S);
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
virtual void finishAttributeSection();
virtual void emitTargetAttributes(const MCSubtargetInfo &STI);
/// Add a new entry to the constant pool for the current section and return an
/// MCExpr that can be used to refer to the constant pool location.
const MCExpr *addConstantPoolEntry(const MCExpr *, SMLoc Loc,
const MCExpr *AdjustExpr = nullptr);
void emitCurrentConstantPool();
void finish() override;
};
template <> struct DenseMapInfo<CSKYTargetStreamer::SymbolIndex> {
static inline CSKYTargetStreamer::SymbolIndex getEmptyKey() {
return {nullptr, CSKYMCExpr::VK_CSKY_Invalid};
}
static inline CSKYTargetStreamer::SymbolIndex getTombstoneKey() {
return {nullptr, CSKYMCExpr::VK_CSKY_Invalid};
}
static unsigned getHashValue(const CSKYTargetStreamer::SymbolIndex &V) {
return hash_combine(DenseMapInfo<const MCSymbol *>::getHashValue(V.sym),
DenseMapInfo<int>::getHashValue(V.kind));
}
static bool isEqual(const CSKYTargetStreamer::SymbolIndex &A,
const CSKYTargetStreamer::SymbolIndex &B) {
return A.sym == B.sym && A.kind == B.kind;
}
};
class formatted_raw_ostream;
class CSKYTargetAsmStreamer : public CSKYTargetStreamer {
formatted_raw_ostream &OS;
void emitAttribute(unsigned Attribute, unsigned Value) override;
void emitTextAttribute(unsigned Attribute, StringRef String) override;
void finishAttributeSection() override;
public:
CSKYTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: CSKYTargetStreamer(S), OS(OS) {}
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_CSKY_CSKYTARGETSTREAMER_H