xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1*81ad6265SDimitry Andric //===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===//
2*81ad6265SDimitry Andric //
3*81ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*81ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*81ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*81ad6265SDimitry Andric //
7*81ad6265SDimitry Andric //===----------------------------------------------------------------------===//
8*81ad6265SDimitry Andric 
9*81ad6265SDimitry Andric #include "CSKYTargetStreamer.h"
10*81ad6265SDimitry Andric #include "CSKYSubtarget.h"
11*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
12*81ad6265SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
13*81ad6265SDimitry Andric #include "llvm/MC/MCContext.h"
14*81ad6265SDimitry Andric #include "llvm/MC/MCSectionELF.h"
15*81ad6265SDimitry Andric #include "llvm/Support/FormattedStream.h"
16*81ad6265SDimitry Andric 
17*81ad6265SDimitry Andric using namespace llvm;
18*81ad6265SDimitry Andric 
19*81ad6265SDimitry Andric //
20*81ad6265SDimitry Andric // ConstantPool implementation
21*81ad6265SDimitry Andric //
22*81ad6265SDimitry Andric // Emit the contents of the constant pool using the provided streamer.
23*81ad6265SDimitry Andric void CSKYConstantPool::emitAll(MCStreamer &Streamer) {
24*81ad6265SDimitry Andric   if (Entries.empty())
25*81ad6265SDimitry Andric     return;
26*81ad6265SDimitry Andric 
27*81ad6265SDimitry Andric   if (CurrentSection != nullptr)
28*81ad6265SDimitry Andric     Streamer.switchSection(CurrentSection);
29*81ad6265SDimitry Andric 
30*81ad6265SDimitry Andric   Streamer.emitDataRegion(MCDR_DataRegion);
31*81ad6265SDimitry Andric   for (const ConstantPoolEntry &Entry : Entries) {
32*81ad6265SDimitry Andric     Streamer.emitCodeAlignment(
33*81ad6265SDimitry Andric         Entry.Size,
34*81ad6265SDimitry Andric         Streamer.getContext().getSubtargetInfo()); // align naturally
35*81ad6265SDimitry Andric     Streamer.emitLabel(Entry.Label);
36*81ad6265SDimitry Andric     Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
37*81ad6265SDimitry Andric   }
38*81ad6265SDimitry Andric   Streamer.emitDataRegion(MCDR_DataRegionEnd);
39*81ad6265SDimitry Andric   Entries.clear();
40*81ad6265SDimitry Andric }
41*81ad6265SDimitry Andric 
42*81ad6265SDimitry Andric const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer,
43*81ad6265SDimitry Andric                                          const MCExpr *Value, unsigned Size,
44*81ad6265SDimitry Andric                                          SMLoc Loc, const MCExpr *AdjustExpr) {
45*81ad6265SDimitry Andric   if (CurrentSection == nullptr)
46*81ad6265SDimitry Andric     CurrentSection = Streamer.getCurrentSectionOnly();
47*81ad6265SDimitry Andric 
48*81ad6265SDimitry Andric   auto &Context = Streamer.getContext();
49*81ad6265SDimitry Andric 
50*81ad6265SDimitry Andric   const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);
51*81ad6265SDimitry Andric 
52*81ad6265SDimitry Andric   // Check if there is existing entry for the same constant. If so, reuse it.
53*81ad6265SDimitry Andric   auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
54*81ad6265SDimitry Andric   if (Itr != CachedEntries.end())
55*81ad6265SDimitry Andric     return Itr->second;
56*81ad6265SDimitry Andric 
57*81ad6265SDimitry Andric   MCSymbol *CPEntryLabel = Context.createTempSymbol();
58*81ad6265SDimitry Andric   const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
59*81ad6265SDimitry Andric 
60*81ad6265SDimitry Andric   if (AdjustExpr) {
61*81ad6265SDimitry Andric     const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value);
62*81ad6265SDimitry Andric 
63*81ad6265SDimitry Andric     Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);
64*81ad6265SDimitry Andric     Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);
65*81ad6265SDimitry Andric     Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), Context);
66*81ad6265SDimitry Andric   }
67*81ad6265SDimitry Andric 
68*81ad6265SDimitry Andric   Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
69*81ad6265SDimitry Andric 
70*81ad6265SDimitry Andric   if (C)
71*81ad6265SDimitry Andric     CachedEntries[C->getValue()] = SymRef;
72*81ad6265SDimitry Andric   return SymRef;
73*81ad6265SDimitry Andric }
74*81ad6265SDimitry Andric 
75*81ad6265SDimitry Andric bool CSKYConstantPool::empty() { return Entries.empty(); }
76*81ad6265SDimitry Andric 
77*81ad6265SDimitry Andric void CSKYConstantPool::clearCache() {
78*81ad6265SDimitry Andric   CurrentSection = nullptr;
79*81ad6265SDimitry Andric   CachedEntries.clear();
80*81ad6265SDimitry Andric }
81*81ad6265SDimitry Andric 
82*81ad6265SDimitry Andric CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)
83*81ad6265SDimitry Andric     : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}
84*81ad6265SDimitry Andric 
85*81ad6265SDimitry Andric const MCExpr *
86*81ad6265SDimitry Andric CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc,
87*81ad6265SDimitry Andric                                          const MCExpr *AdjustExpr) {
88*81ad6265SDimitry Andric   auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid;
89*81ad6265SDimitry Andric   ConstantCounter++;
90*81ad6265SDimitry Andric 
91*81ad6265SDimitry Andric   const MCExpr *OrigExpr = Expr;
92*81ad6265SDimitry Andric 
93*81ad6265SDimitry Andric   if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) {
94*81ad6265SDimitry Andric     Expr = CE->getSubExpr();
95*81ad6265SDimitry Andric     ELFRefKind = CE->getKind();
96*81ad6265SDimitry Andric   }
97*81ad6265SDimitry Andric 
98*81ad6265SDimitry Andric   if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
99*81ad6265SDimitry Andric     const MCSymbol *Sym = &SymExpr->getSymbol();
100*81ad6265SDimitry Andric 
101*81ad6265SDimitry Andric     SymbolIndex Index = {Sym, ELFRefKind};
102*81ad6265SDimitry Andric 
103*81ad6265SDimitry Andric     if (ConstantMap.find(Index) == ConstantMap.end()) {
104*81ad6265SDimitry Andric       ConstantMap[Index] =
105*81ad6265SDimitry Andric           ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);
106*81ad6265SDimitry Andric     }
107*81ad6265SDimitry Andric     return ConstantMap[Index];
108*81ad6265SDimitry Andric   }
109*81ad6265SDimitry Andric 
110*81ad6265SDimitry Andric   return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);
111*81ad6265SDimitry Andric }
112*81ad6265SDimitry Andric 
113*81ad6265SDimitry Andric void CSKYTargetStreamer::emitCurrentConstantPool() {
114*81ad6265SDimitry Andric   ConstantPool->emitAll(Streamer);
115*81ad6265SDimitry Andric   ConstantPool->clearCache();
116*81ad6265SDimitry Andric }
117*81ad6265SDimitry Andric 
118*81ad6265SDimitry Andric // finish() - write out any non-empty assembler constant pools.
119*81ad6265SDimitry Andric void CSKYTargetStreamer::finish() {
120*81ad6265SDimitry Andric   if (ConstantCounter != 0) {
121*81ad6265SDimitry Andric     ConstantPool->emitAll(Streamer);
122*81ad6265SDimitry Andric   }
123*81ad6265SDimitry Andric 
124*81ad6265SDimitry Andric   finishAttributeSection();
125*81ad6265SDimitry Andric }
126*81ad6265SDimitry Andric 
127*81ad6265SDimitry Andric void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}
128*81ad6265SDimitry Andric 
129*81ad6265SDimitry Andric void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
130*81ad6265SDimitry Andric void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,
131*81ad6265SDimitry Andric                                            StringRef String) {}
132*81ad6265SDimitry Andric void CSKYTargetStreamer::finishAttributeSection() {}
133*81ad6265SDimitry Andric 
134*81ad6265SDimitry Andric void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
135*81ad6265SDimitry Andric   OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
136*81ad6265SDimitry Andric }
137*81ad6265SDimitry Andric 
138*81ad6265SDimitry Andric void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
139*81ad6265SDimitry Andric                                               StringRef String) {
140*81ad6265SDimitry Andric   OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
141*81ad6265SDimitry Andric }
142*81ad6265SDimitry Andric 
143*81ad6265SDimitry Andric void CSKYTargetAsmStreamer::finishAttributeSection() {}
144