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.
emitAll(MCStreamer & 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
addEntry(MCStreamer & Streamer,const MCExpr * Value,unsigned Size,SMLoc Loc,const MCExpr * AdjustExpr)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
empty()74 bool CSKYConstantPool::empty() { return Entries.empty(); }
75
clearCache()76 void CSKYConstantPool::clearCache() {
77 CurrentSection = nullptr;
78 CachedEntries.clear();
79 }
80
CSKYTargetStreamer(MCStreamer & S)81 CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)
82 : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}
83
84 const MCExpr *
addConstantPoolEntry(const MCExpr * Expr,SMLoc Loc,const MCExpr * AdjustExpr)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
emitCurrentConstantPool()112 void CSKYTargetStreamer::emitCurrentConstantPool() {
113 ConstantPool->emitAll(Streamer);
114 ConstantPool->clearCache();
115 }
116
117 // finish() - write out any non-empty assembler constant pools.
finish()118 void CSKYTargetStreamer::finish() {
119 if (ConstantCounter != 0) {
120 ConstantPool->emitAll(Streamer);
121 }
122
123 finishAttributeSection();
124 }
125
emitTargetAttributes(const MCSubtargetInfo & STI)126 void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}
127
emitAttribute(unsigned Attribute,unsigned Value)128 void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
emitTextAttribute(unsigned Attribute,StringRef String)129 void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,
130 StringRef String) {}
finishAttributeSection()131 void CSKYTargetStreamer::finishAttributeSection() {}
132
emitAttribute(unsigned Attribute,unsigned Value)133 void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
134 OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
135 }
136
emitTextAttribute(unsigned Attribute,StringRef String)137 void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
138 StringRef String) {
139 OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
140 }
141
finishAttributeSection()142 void CSKYTargetAsmStreamer::finishAttributeSection() {}
143