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