144 lines
4.6 KiB
C++
144 lines
4.6 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CSKYTargetStreamer.h"
|
|
#include "CSKYSubtarget.h"
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCSectionELF.h"
|
|
#include "llvm/Support/FormattedStream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
//
|
|
// ConstantPool implementation
|
|
//
|
|
// Emit the contents of the constant pool using the provided streamer.
|
|
void CSKYConstantPool::emitAll(MCStreamer &Streamer) {
|
|
if (Entries.empty())
|
|
return;
|
|
|
|
if (CurrentSection != nullptr)
|
|
Streamer.switchSection(CurrentSection);
|
|
|
|
Streamer.emitDataRegion(MCDR_DataRegion);
|
|
for (const ConstantPoolEntry &Entry : Entries) {
|
|
Streamer.emitCodeAlignment(
|
|
Align(Entry.Size),
|
|
Streamer.getContext().getSubtargetInfo()); // align naturally
|
|
Streamer.emitLabel(Entry.Label);
|
|
Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
|
|
}
|
|
Streamer.emitDataRegion(MCDR_DataRegionEnd);
|
|
Entries.clear();
|
|
}
|
|
|
|
const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer,
|
|
const MCExpr *Value, unsigned Size,
|
|
SMLoc Loc, const MCExpr *AdjustExpr) {
|
|
if (CurrentSection == nullptr)
|
|
CurrentSection = Streamer.getCurrentSectionOnly();
|
|
|
|
auto &Context = Streamer.getContext();
|
|
|
|
const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);
|
|
|
|
// Check if there is existing entry for the same constant. If so, reuse it.
|
|
auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
|
|
if (Itr != CachedEntries.end())
|
|
return Itr->second;
|
|
|
|
MCSymbol *CPEntryLabel = Context.createTempSymbol();
|
|
const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
|
|
|
|
if (AdjustExpr) {
|
|
const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value);
|
|
|
|
Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);
|
|
Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);
|
|
Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), Context);
|
|
}
|
|
|
|
Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
|
|
|
|
if (C)
|
|
CachedEntries[C->getValue()] = SymRef;
|
|
return SymRef;
|
|
}
|
|
|
|
bool CSKYConstantPool::empty() { return Entries.empty(); }
|
|
|
|
void CSKYConstantPool::clearCache() {
|
|
CurrentSection = nullptr;
|
|
CachedEntries.clear();
|
|
}
|
|
|
|
CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)
|
|
: MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}
|
|
|
|
const MCExpr *
|
|
CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc,
|
|
const MCExpr *AdjustExpr) {
|
|
auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid;
|
|
ConstantCounter++;
|
|
|
|
const MCExpr *OrigExpr = Expr;
|
|
|
|
if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) {
|
|
Expr = CE->getSubExpr();
|
|
ELFRefKind = CE->getKind();
|
|
}
|
|
|
|
if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
|
const MCSymbol *Sym = &SymExpr->getSymbol();
|
|
|
|
SymbolIndex Index = {Sym, ELFRefKind};
|
|
|
|
if (ConstantMap.find(Index) == ConstantMap.end()) {
|
|
ConstantMap[Index] =
|
|
ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);
|
|
}
|
|
return ConstantMap[Index];
|
|
}
|
|
|
|
return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);
|
|
}
|
|
|
|
void CSKYTargetStreamer::emitCurrentConstantPool() {
|
|
ConstantPool->emitAll(Streamer);
|
|
ConstantPool->clearCache();
|
|
}
|
|
|
|
// finish() - write out any non-empty assembler constant pools.
|
|
void CSKYTargetStreamer::finish() {
|
|
if (ConstantCounter != 0) {
|
|
ConstantPool->emitAll(Streamer);
|
|
}
|
|
|
|
finishAttributeSection();
|
|
}
|
|
|
|
void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}
|
|
|
|
void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
|
|
void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,
|
|
StringRef String) {}
|
|
void CSKYTargetStreamer::finishAttributeSection() {}
|
|
|
|
void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
|
|
OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
|
|
}
|
|
|
|
void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
|
|
StringRef String) {
|
|
OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
|
|
}
|
|
|
|
void CSKYTargetAsmStreamer::finishAttributeSection() {}
|