//===-- 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 "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(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(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(Expr)) { Expr = CE->getSubExpr(); ELFRefKind = CE->getKind(); } if (const MCSymbolRefExpr *SymExpr = dyn_cast(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() {}