LLVM 24.0.0git
CSKYTargetStreamer.cpp
Go to the documentation of this file.
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
10#include "CSKYMCTargetDesc.h"
14#include "llvm/MC/MCContext.h"
20
21using namespace llvm;
22
23//
24// ConstantPool implementation
25//
26// Emit the contents of the constant pool using the provided streamer.
28 if (Entries.empty())
29 return;
30
31 if (CurrentSection != nullptr)
32 Streamer.switchSection(CurrentSection);
33
35 for (const ConstantPoolEntry &Entry : Entries) {
36 Streamer.emitCodeAlignment(
37 Align(Entry.Size),
38 *Streamer.getContext().getSubtargetInfo()); // align naturally
39 Streamer.emitLabel(Entry.Label);
40 Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);
41 }
43 Entries.clear();
44}
45
47 const MCExpr *Value, unsigned Size,
48 SMLoc Loc, const MCExpr *AdjustExpr) {
49 if (CurrentSection == nullptr)
50 CurrentSection = Streamer.getCurrentSectionOnly();
51
52 auto &Context = Streamer.getContext();
53
55
56 // Check if there is existing entry for the same constant. If so, reuse it.
57 auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();
58 if (Itr != CachedEntries.end())
59 return Itr->second;
60
61 MCSymbol *CPEntryLabel = Context.createTempSymbol();
62 const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);
63
64 if (AdjustExpr) {
65 auto *CSKYExpr = cast<MCSpecifierExpr>(Value);
66
67 Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);
68 Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);
69 Value = MCSpecifierExpr::create(Value, CSKYExpr->getSpecifier(), Context);
70 }
71
72 Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));
73
74 if (C)
75 CachedEntries[C->getValue()] = SymRef;
76 return SymRef;
77}
78
79bool CSKYConstantPool::empty() { return Entries.empty(); }
80
82 CurrentSection = nullptr;
83 CachedEntries.clear();
84}
85
88
89const MCExpr *
91 const MCExpr *AdjustExpr) {
92 uint8_t ELFRefKind = CSKY::S_Invalid;
94
95 const MCExpr *OrigExpr = Expr;
96
97 if (auto *CE = dyn_cast<MCSpecifierExpr>(Expr)) {
98 Expr = CE->getSubExpr();
99 ELFRefKind = CE->getSpecifier();
100 }
101
102 if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
103 const MCSymbol *Sym = &SymExpr->getSymbol();
104
105 SymbolIndex Index = {Sym, ELFRefKind};
106
107 if (ConstantMap.find(Index) == ConstantMap.end()) {
108 ConstantMap[Index] =
109 ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);
110 }
111 return ConstantMap[Index];
112 }
113
114 return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);
115}
116
121
122// finish() - write out any non-empty assembler constant pools.
124 if (ConstantCounter != 0) {
125 ConstantPool->emitAll(Streamer);
126 }
127
129}
130
132 bool HardFloatABI) {
133 // AsmPrinter emits the attributes once for the module. Ignore the repeated
134 // requests from the parser instantiated for each inline asm block, which
135 // knows neither the CPU nor the float ABI selected for the module.
137 return;
139
140 StringRef CPU = STI.getCPU();
142
143 if (ArchID == CSKY::ArchKind::CK804)
144 ArchID = CSKY::ArchKind::CK803;
145
146 StringRef CPU_ARCH = CSKY::getArchName(ArchID);
147
148 if (ArchID == CSKY::ArchKind::INVALID) {
149 CPU = "ck810";
150 CPU_ARCH = "ck810";
151 }
154
155 unsigned ISAFlag = 0;
156 if (STI.hasFeature(CSKY::HasE1))
157 ISAFlag |= CSKYAttrs::V2_ISA_E1;
158
159 if (STI.hasFeature(CSKY::HasE2))
160 ISAFlag |= CSKYAttrs::V2_ISA_1E2;
161
162 if (STI.hasFeature(CSKY::Has2E3))
163 ISAFlag |= CSKYAttrs::V2_ISA_2E3;
164
165 if (STI.hasFeature(CSKY::HasMP))
166 ISAFlag |= CSKYAttrs::ISA_MP;
167
168 if (STI.hasFeature(CSKY::Has3E3r1))
169 ISAFlag |= CSKYAttrs::V2_ISA_3E3R1;
170
171 if (STI.hasFeature(CSKY::Has3r1E3r2))
172 ISAFlag |= CSKYAttrs::V2_ISA_3E3R2;
173
174 if (STI.hasFeature(CSKY::Has3r2E3r3))
175 ISAFlag |= CSKYAttrs::V2_ISA_3E3R3;
176
177 if (STI.hasFeature(CSKY::Has3E7))
178 ISAFlag |= CSKYAttrs::V2_ISA_3E7;
179
180 if (STI.hasFeature(CSKY::HasMP1E2))
181 ISAFlag |= CSKYAttrs::ISA_MP_1E2;
182
183 if (STI.hasFeature(CSKY::Has7E10))
184 ISAFlag |= CSKYAttrs::V2_ISA_7E10;
185
186 if (STI.hasFeature(CSKY::Has10E60))
187 ISAFlag |= CSKYAttrs::V2_ISA_10E60;
188
189 if (STI.hasFeature(CSKY::FeatureTrust))
190 ISAFlag |= CSKYAttrs::ISA_TRUST;
191
192 if (STI.hasFeature(CSKY::FeatureJAVA))
193 ISAFlag |= CSKYAttrs::ISA_JAVA;
194
195 if (STI.hasFeature(CSKY::FeatureCache))
196 ISAFlag |= CSKYAttrs::ISA_CACHE;
197
198 if (STI.hasFeature(CSKY::FeatureNVIC))
199 ISAFlag |= CSKYAttrs::ISA_NVIC;
200
201 if (STI.hasFeature(CSKY::FeatureDSP))
202 ISAFlag |= CSKYAttrs::ISA_DSP;
203
204 if (STI.hasFeature(CSKY::HasDSP1E2))
205 ISAFlag |= CSKYAttrs::ISA_DSP_1E2;
206
207 if (STI.hasFeature(CSKY::HasDSPE60))
208 ISAFlag |= CSKYAttrs::V2_ISA_DSPE60;
209
210 if (STI.hasFeature(CSKY::FeatureDSPV2))
212
213 if (STI.hasFeature(CSKY::FeatureDSP_Silan))
214 ISAFlag |= CSKYAttrs::ISA_DSP_SILAN;
215
216 if (STI.hasFeature(CSKY::FeatureVDSPV1_128))
217 ISAFlag |= CSKYAttrs::ISA_VDSP;
218
219 if (STI.hasFeature(CSKY::FeatureVDSPV2))
220 ISAFlag |= CSKYAttrs::ISA_VDSP_2;
221
222 if (STI.hasFeature(CSKY::HasVDSP2E3))
223 ISAFlag |= CSKYAttrs::ISA_VDSP_2E3;
224
225 if (STI.hasFeature(CSKY::HasVDSP2E60F))
226 ISAFlag |= CSKYAttrs::ISA_VDSP_2E60F;
227
229
230 unsigned ISAExtFlag = 0;
231 if (STI.hasFeature(CSKY::HasFLOATE1))
232 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_E1;
233
234 if (STI.hasFeature(CSKY::HasFLOAT1E2))
235 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E2;
236
237 if (STI.hasFeature(CSKY::HasFLOAT1E3))
238 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E3;
239
240 if (STI.hasFeature(CSKY::HasFLOAT3E4))
241 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_3E4;
242
243 if (STI.hasFeature(CSKY::HasFLOAT7E60))
244 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_7E60;
245
247
248 if (STI.hasFeature(CSKY::FeatureDSP))
251 if (STI.hasFeature(CSKY::FeatureDSPV2))
253
254 if (STI.hasFeature(CSKY::FeatureVDSPV2))
256
257 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
258 STI.hasFeature(CSKY::FeatureFPUV2_DF))
260 else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) ||
261 STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
262 STI.hasFeature(CSKY::FeatureFPUV3_DF))
264
265 bool hasAnyFloatExt = STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
266 STI.hasFeature(CSKY::FeatureFPUV2_DF) ||
267 STI.hasFeature(CSKY::FeatureFPUV3_HF) ||
268 STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
269 STI.hasFeature(CSKY::FeatureFPUV3_DF);
270
271 // The hard-float *ABI* (FP values in FP registers at call boundaries) is
272 // selected by the "float-abi" module flag, resolved by the caller; it does
273 // not depend on ModeHardFloat, which only distinguishes the soft-float ABI
274 // that still uses hard-float instructions (SOFTFP) from pure soft float.
275 if (hasAnyFloatExt && HardFloatABI)
277 else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat))
279 else
281
282 unsigned HardFPFlag = 0;
283 if (STI.hasFeature(CSKY::FeatureFPUV3_HF))
284 HardFPFlag |= CSKYAttrs::FPU_HARDFP_HALF;
285 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
286 STI.hasFeature(CSKY::FeatureFPUV3_SF))
287 HardFPFlag |= CSKYAttrs::FPU_HARDFP_SINGLE;
288 if (STI.hasFeature(CSKY::FeatureFPUV2_DF) ||
289 STI.hasFeature(CSKY::FeatureFPUV3_DF))
290 HardFPFlag |= CSKYAttrs::FPU_HARDFP_DOUBLE;
291
292 if (HardFPFlag != 0) {
297 }
298}
299
304
305void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
306 OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
307}
308
309void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
311 OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";
312}
313
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
void emitAll(MCStreamer &Streamer)
const MCExpr * addEntry(MCStreamer &Streamer, const MCExpr *Value, unsigned Size, SMLoc Loc, const MCExpr *AdjustExpr)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
DenseMap< SymbolIndex, const MCExpr * > ConstantMap
void emitTargetAttributes(const MCSubtargetInfo &STI, bool HardFloatABI)
const MCExpr * addConstantPoolEntry(const MCExpr *, SMLoc Loc, const MCExpr *AdjustExpr=nullptr)
Add a new entry to the constant pool for the current section and return an MCExpr that can be used to...
std::unique_ptr< CSKYConstantPool > ConstantPool
virtual void emitAttribute(unsigned Attribute, unsigned Value)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:427
const MCSubtargetInfo * getSubtargetInfo() const
Definition MCContext.h:415
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo &STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
MCContext & getContext() const
Definition MCStreamer.h:326
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitDataRegion(MCDataRegionType Kind)
Note in the output the specified region Kind.
Definition MCStreamer.h:512
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:438
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
StringRef getCPU() const
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
MCStreamer & getStreamer()
Definition MCStreamer.h:103
MCStreamer & Streamer
Definition MCStreamer.h:97
MCTargetStreamer(MCStreamer &S)
Represents a location in source code.
Definition SMLoc.h:22
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI ArchKind parseCPUArch(StringRef CPU)
LLVM_ABI StringRef getArchName(ArchKind AK)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ MCDR_DataRegionEnd
.end_data_region
@ MCDR_DataRegion
.data_region
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39