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