132977589SZi Xuan Wu //===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===//
232977589SZi Xuan Wu //
332977589SZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
432977589SZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
532977589SZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
632977589SZi Xuan Wu //
732977589SZi Xuan Wu //===----------------------------------------------------------------------===//
832977589SZi Xuan Wu
932977589SZi Xuan Wu #include "CSKYTargetStreamer.h"
1032977589SZi Xuan Wu #include "CSKYSubtarget.h"
11989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
1232977589SZi Xuan Wu #include "llvm/CodeGen/TargetSubtargetInfo.h"
1332977589SZi Xuan Wu #include "llvm/MC/MCContext.h"
1432977589SZi Xuan Wu #include "llvm/MC/MCSectionELF.h"
1532977589SZi Xuan Wu #include "llvm/Support/FormattedStream.h"
1632977589SZi Xuan Wu
1732977589SZi Xuan Wu using namespace llvm;
1832977589SZi Xuan Wu
1932977589SZi Xuan Wu //
2032977589SZi Xuan Wu // ConstantPool implementation
2132977589SZi Xuan Wu //
2232977589SZi Xuan Wu // Emit the contents of the constant pool using the provided streamer.
emitAll(MCStreamer & Streamer)2332977589SZi Xuan Wu void CSKYConstantPool::emitAll(MCStreamer &Streamer) {
2432977589SZi Xuan Wu if (Entries.empty())
2532977589SZi Xuan Wu return;
2632977589SZi Xuan Wu
2732977589SZi Xuan Wu if (CurrentSection != nullptr)
28*adf4142fSFangrui Song Streamer.switchSection(CurrentSection);
2932977589SZi Xuan Wu
3032977589SZi Xuan Wu Streamer.emitDataRegion(MCDR_DataRegion);
3132977589SZi Xuan Wu for (const ConstantPoolEntry &Entry : Entries) {
3232977589SZi Xuan Wu Streamer.emitCodeAlignment(
3332977589SZi Xuan Wu Entry.Size,
3432977589SZi Xuan Wu Streamer.getContext().getSubtargetInfo()); // align naturally
3532977589SZi Xuan Wu Streamer.emitLabel(Entry.Label);
3632977589SZi Xuan Wu Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
3732977589SZi Xuan Wu }
3832977589SZi Xuan Wu Streamer.emitDataRegion(MCDR_DataRegionEnd);
3932977589SZi Xuan Wu Entries.clear();
4032977589SZi Xuan Wu }
4132977589SZi Xuan Wu
addEntry(MCStreamer & Streamer,const MCExpr * Value,unsigned Size,SMLoc Loc,const MCExpr * AdjustExpr)4232977589SZi Xuan Wu const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer,
4332977589SZi Xuan Wu const MCExpr *Value, unsigned Size,
4432977589SZi Xuan Wu SMLoc Loc, const MCExpr *AdjustExpr) {
4532977589SZi Xuan Wu if (CurrentSection == nullptr)
4632977589SZi Xuan Wu CurrentSection = Streamer.getCurrentSectionOnly();
4732977589SZi Xuan Wu
4832977589SZi Xuan Wu auto &Context = Streamer.getContext();
4932977589SZi Xuan Wu
5032977589SZi Xuan Wu const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);
5132977589SZi Xuan Wu
5232977589SZi Xuan Wu // Check if there is existing entry for the same constant. If so, reuse it.
5332977589SZi Xuan Wu auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
5432977589SZi Xuan Wu if (Itr != CachedEntries.end())
5532977589SZi Xuan Wu return Itr->second;
5632977589SZi Xuan Wu
5732977589SZi Xuan Wu MCSymbol *CPEntryLabel = Context.createTempSymbol();
5832977589SZi Xuan Wu const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
5932977589SZi Xuan Wu
6032977589SZi Xuan Wu if (AdjustExpr) {
6132977589SZi Xuan Wu const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value);
6232977589SZi Xuan Wu
6332977589SZi Xuan Wu Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);
6432977589SZi Xuan Wu Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);
6532977589SZi Xuan Wu Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), Context);
6632977589SZi Xuan Wu }
6732977589SZi Xuan Wu
6832977589SZi Xuan Wu Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
6932977589SZi Xuan Wu
7032977589SZi Xuan Wu if (C)
7132977589SZi Xuan Wu CachedEntries[C->getValue()] = SymRef;
7232977589SZi Xuan Wu return SymRef;
7332977589SZi Xuan Wu }
7432977589SZi Xuan Wu
empty()7532977589SZi Xuan Wu bool CSKYConstantPool::empty() { return Entries.empty(); }
7632977589SZi Xuan Wu
clearCache()7732977589SZi Xuan Wu void CSKYConstantPool::clearCache() {
7832977589SZi Xuan Wu CurrentSection = nullptr;
7932977589SZi Xuan Wu CachedEntries.clear();
8032977589SZi Xuan Wu }
8132977589SZi Xuan Wu
CSKYTargetStreamer(MCStreamer & S)8232977589SZi Xuan Wu CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)
8332977589SZi Xuan Wu : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}
8432977589SZi Xuan Wu
8532977589SZi Xuan Wu const MCExpr *
addConstantPoolEntry(const MCExpr * Expr,SMLoc Loc,const MCExpr * AdjustExpr)8632977589SZi Xuan Wu CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc,
8732977589SZi Xuan Wu const MCExpr *AdjustExpr) {
8832977589SZi Xuan Wu auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid;
8932977589SZi Xuan Wu ConstantCounter++;
9032977589SZi Xuan Wu
9132977589SZi Xuan Wu const MCExpr *OrigExpr = Expr;
9232977589SZi Xuan Wu
9332977589SZi Xuan Wu if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) {
9432977589SZi Xuan Wu Expr = CE->getSubExpr();
9532977589SZi Xuan Wu ELFRefKind = CE->getKind();
9632977589SZi Xuan Wu }
9732977589SZi Xuan Wu
9832977589SZi Xuan Wu if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
9932977589SZi Xuan Wu const MCSymbol *Sym = &SymExpr->getSymbol();
10032977589SZi Xuan Wu
10132977589SZi Xuan Wu SymbolIndex Index = {Sym, ELFRefKind};
10232977589SZi Xuan Wu
10332977589SZi Xuan Wu if (ConstantMap.find(Index) == ConstantMap.end()) {
10432977589SZi Xuan Wu ConstantMap[Index] =
10532977589SZi Xuan Wu ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);
10632977589SZi Xuan Wu }
10732977589SZi Xuan Wu return ConstantMap[Index];
10832977589SZi Xuan Wu }
10932977589SZi Xuan Wu
11032977589SZi Xuan Wu return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);
11132977589SZi Xuan Wu }
11232977589SZi Xuan Wu
emitCurrentConstantPool()11332977589SZi Xuan Wu void CSKYTargetStreamer::emitCurrentConstantPool() {
11432977589SZi Xuan Wu ConstantPool->emitAll(Streamer);
11532977589SZi Xuan Wu ConstantPool->clearCache();
11632977589SZi Xuan Wu }
11732977589SZi Xuan Wu
11832977589SZi Xuan Wu // finish() - write out any non-empty assembler constant pools.
finish()11932977589SZi Xuan Wu void CSKYTargetStreamer::finish() {
12032977589SZi Xuan Wu if (ConstantCounter != 0) {
12132977589SZi Xuan Wu ConstantPool->emitAll(Streamer);
12232977589SZi Xuan Wu }
12332977589SZi Xuan Wu
12432977589SZi Xuan Wu finishAttributeSection();
12532977589SZi Xuan Wu }
12632977589SZi Xuan Wu
emitTargetAttributes(const MCSubtargetInfo & STI)12732977589SZi Xuan Wu void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}
12832977589SZi Xuan Wu
emitAttribute(unsigned Attribute,unsigned Value)12932977589SZi Xuan Wu void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
emitTextAttribute(unsigned Attribute,StringRef String)13032977589SZi Xuan Wu void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,
13132977589SZi Xuan Wu StringRef String) {}
finishAttributeSection()13232977589SZi Xuan Wu void CSKYTargetStreamer::finishAttributeSection() {}
13332977589SZi Xuan Wu
emitAttribute(unsigned Attribute,unsigned Value)13432977589SZi Xuan Wu void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
13532977589SZi Xuan Wu OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
13632977589SZi Xuan Wu }
13732977589SZi Xuan Wu
emitTextAttribute(unsigned Attribute,StringRef String)13832977589SZi Xuan Wu void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
13932977589SZi Xuan Wu StringRef String) {
14032977589SZi Xuan Wu OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
14132977589SZi Xuan Wu }
14232977589SZi Xuan Wu
finishAttributeSection()14332977589SZi Xuan Wu void CSKYTargetAsmStreamer::finishAttributeSection() {}
144