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