LLVM 20.0.0git
CSKYELFStreamer.cpp
Go to the documentation of this file.
1//===-- CSKYELFStreamer.cpp - CSKY ELF Target Streamer Methods ------------===//
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// This file provides CSKY specific target streamer methods.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CSKYELFStreamer.h"
14#include "CSKYMCTargetDesc.h"
18#include "llvm/MC/MCAssembler.h"
19#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCSymbolELF.h"
25#include "llvm/Support/LEB128.h"
27
28using namespace llvm;
29
30// This part is for ELF object output.
32 const MCSubtargetInfo &STI)
33 : CSKYTargetStreamer(S), CurrentVendor("csky") {
35 const FeatureBitset &Features = STI.getFeatureBits();
36
37 unsigned EFlags = W.getELFHeaderEFlags();
38
39 EFlags |= ELF::EF_CSKY_ABIV2;
40
41 if (Features[CSKY::ProcCK801])
42 EFlags |= ELF::EF_CSKY_801;
43 else if (Features[CSKY::ProcCK802])
44 EFlags |= ELF::EF_CSKY_802;
45 else if (Features[CSKY::ProcCK803])
46 EFlags |= ELF::EF_CSKY_803;
47 else if (Features[CSKY::ProcCK804])
48 EFlags |= ELF::EF_CSKY_803;
49 else if (Features[CSKY::ProcCK805])
50 EFlags |= ELF::EF_CSKY_805;
51 else if (Features[CSKY::ProcCK807])
52 EFlags |= ELF::EF_CSKY_807;
53 else if (Features[CSKY::ProcCK810])
54 EFlags |= ELF::EF_CSKY_810;
55 else if (Features[CSKY::ProcCK860])
56 EFlags |= ELF::EF_CSKY_860;
57 else
58 EFlags |= ELF::EF_CSKY_810;
59
60 if (Features[CSKY::FeatureFPUV2_SF] || Features[CSKY::FeatureFPUV3_SF])
61 EFlags |= ELF::EF_CSKY_FLOAT;
62
63 EFlags |= ELF::EF_CSKY_EFV1;
64
65 W.setELFHeaderEFlags(EFlags);
66}
67
69 return static_cast<MCELFStreamer &>(Streamer);
70}
71
72void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
73 setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
74}
75
76void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute,
78 setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
79}
80
81void CSKYTargetELFStreamer::finishAttributeSection() {
82 if (Contents.empty())
83 return;
84
85 if (AttributeSection) {
86 Streamer.switchSection(AttributeSection);
87 } else {
89 AttributeSection = MCA.getContext().getELFSection(
90 ".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0);
91 Streamer.switchSection(AttributeSection);
93 }
94
95 // Vendor size + Vendor name + '\0'
96 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
97
98 // Tag + Tag Size
99 const size_t TagHeaderSize = 1 + 4;
100
101 const size_t ContentsSize = calculateContentSize();
102
103 Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
104 Streamer.emitBytes(CurrentVendor);
105 Streamer.emitInt8(0); // '\0'
106
108 Streamer.emitInt32(TagHeaderSize + ContentsSize);
109
110 // Size should have been accounted for already, now
111 // emit each field as its type (ULEB or String).
112 for (AttributeItem item : Contents) {
114 switch (item.Type) {
115 default:
116 llvm_unreachable("Invalid attribute type");
117 case AttributeType::Numeric:
118 Streamer.emitULEB128IntValue(item.IntValue);
119 break;
120 case AttributeType::Text:
121 Streamer.emitBytes(item.StringValue);
122 Streamer.emitInt8(0); // '\0'
123 break;
124 case AttributeType::NumericAndText:
125 Streamer.emitULEB128IntValue(item.IntValue);
126 Streamer.emitBytes(item.StringValue);
127 Streamer.emitInt8(0); // '\0'
128 break;
129 }
130 }
131
132 Contents.clear();
133}
134
135size_t CSKYTargetELFStreamer::calculateContentSize() const {
136 size_t Result = 0;
137 for (AttributeItem item : Contents) {
138 switch (item.Type) {
139 case AttributeType::Hidden:
140 break;
141 case AttributeType::Numeric:
142 Result += getULEB128Size(item.Tag);
143 Result += getULEB128Size(item.IntValue);
144 break;
145 case AttributeType::Text:
146 Result += getULEB128Size(item.Tag);
147 Result += item.StringValue.size() + 1; // string + '\0'
148 break;
149 case AttributeType::NumericAndText:
150 Result += getULEB128Size(item.Tag);
151 Result += getULEB128Size(item.IntValue);
152 Result += item.StringValue.size() + 1; // string + '\0';
153 break;
154 }
155 }
156 return Result;
157}
158
159void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) {
160 if (Name == "$d" && State == EMS_Data)
161 return;
162 if (Name == "$t" && State == EMS_Text)
163 return;
164 if (Name == "$t" && State == EMS_None) {
165 State = EMS_Text;
166 return;
167 }
168
169 State = (Name == "$t" ? EMS_Text : EMS_Data);
170
171 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
172 emitLabel(Symbol);
173
174 Symbol->setType(ELF::STT_NOTYPE);
175 Symbol->setBinding(ELF::STB_LOCAL);
176}
177
178void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
179 StringRef CPU = STI.getCPU();
181
182 if (ArchID == CSKY::ArchKind::CK804)
183 ArchID = CSKY::ArchKind::CK803;
184
185 StringRef CPU_ARCH = CSKY::getArchName(ArchID);
186
187 if (ArchID == CSKY::ArchKind::INVALID) {
188 CPU = "ck810";
189 CPU_ARCH = "ck810";
190 }
191 emitTextAttribute(CSKYAttrs::CSKY_ARCH_NAME, CPU_ARCH);
192 emitTextAttribute(CSKYAttrs::CSKY_CPU_NAME, CPU);
193
194 unsigned ISAFlag = 0;
195 if (STI.hasFeature(CSKY::HasE1))
196 ISAFlag |= CSKYAttrs::V2_ISA_E1;
197
198 if (STI.hasFeature(CSKY::HasE2))
199 ISAFlag |= CSKYAttrs::V2_ISA_1E2;
200
201 if (STI.hasFeature(CSKY::Has2E3))
202 ISAFlag |= CSKYAttrs::V2_ISA_2E3;
203
204 if (STI.hasFeature(CSKY::HasMP))
205 ISAFlag |= CSKYAttrs::ISA_MP;
206
207 if (STI.hasFeature(CSKY::Has3E3r1))
208 ISAFlag |= CSKYAttrs::V2_ISA_3E3R1;
209
210 if (STI.hasFeature(CSKY::Has3r1E3r2))
211 ISAFlag |= CSKYAttrs::V2_ISA_3E3R2;
212
213 if (STI.hasFeature(CSKY::Has3r2E3r3))
214 ISAFlag |= CSKYAttrs::V2_ISA_3E3R3;
215
216 if (STI.hasFeature(CSKY::Has3E7))
217 ISAFlag |= CSKYAttrs::V2_ISA_3E7;
218
219 if (STI.hasFeature(CSKY::HasMP1E2))
220 ISAFlag |= CSKYAttrs::ISA_MP_1E2;
221
222 if (STI.hasFeature(CSKY::Has7E10))
223 ISAFlag |= CSKYAttrs::V2_ISA_7E10;
224
225 if (STI.hasFeature(CSKY::Has10E60))
226 ISAFlag |= CSKYAttrs::V2_ISA_10E60;
227
228 if (STI.hasFeature(CSKY::FeatureTrust))
229 ISAFlag |= CSKYAttrs::ISA_TRUST;
230
231 if (STI.hasFeature(CSKY::FeatureJAVA))
232 ISAFlag |= CSKYAttrs::ISA_JAVA;
233
234 if (STI.hasFeature(CSKY::FeatureCache))
235 ISAFlag |= CSKYAttrs::ISA_CACHE;
236
237 if (STI.hasFeature(CSKY::FeatureNVIC))
238 ISAFlag |= CSKYAttrs::ISA_NVIC;
239
240 if (STI.hasFeature(CSKY::FeatureDSP))
241 ISAFlag |= CSKYAttrs::ISA_DSP;
242
243 if (STI.hasFeature(CSKY::HasDSP1E2))
244 ISAFlag |= CSKYAttrs::ISA_DSP_1E2;
245
246 if (STI.hasFeature(CSKY::HasDSPE60))
247 ISAFlag |= CSKYAttrs::V2_ISA_DSPE60;
248
249 if (STI.hasFeature(CSKY::FeatureDSPV2))
251
252 if (STI.hasFeature(CSKY::FeatureDSP_Silan))
253 ISAFlag |= CSKYAttrs::ISA_DSP_SILAN;
254
255 if (STI.hasFeature(CSKY::FeatureVDSPV1_128))
256 ISAFlag |= CSKYAttrs::ISA_VDSP;
257
258 if (STI.hasFeature(CSKY::FeatureVDSPV2))
259 ISAFlag |= CSKYAttrs::ISA_VDSP_2;
260
261 if (STI.hasFeature(CSKY::HasVDSP2E3))
262 ISAFlag |= CSKYAttrs::ISA_VDSP_2E3;
263
264 if (STI.hasFeature(CSKY::HasVDSP2E60F))
265 ISAFlag |= CSKYAttrs::ISA_VDSP_2E60F;
266
267 emitAttribute(CSKYAttrs::CSKY_ISA_FLAGS, ISAFlag);
268
269 unsigned ISAExtFlag = 0;
270 if (STI.hasFeature(CSKY::HasFLOATE1))
271 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_E1;
272
273 if (STI.hasFeature(CSKY::HasFLOAT1E2))
274 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E2;
275
276 if (STI.hasFeature(CSKY::HasFLOAT1E3))
277 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E3;
278
279 if (STI.hasFeature(CSKY::HasFLOAT3E4))
280 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_3E4;
281
282 if (STI.hasFeature(CSKY::HasFLOAT7E60))
283 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_7E60;
284
285 emitAttribute(CSKYAttrs::CSKY_ISA_EXT_FLAGS, ISAExtFlag);
286
287 if (STI.hasFeature(CSKY::FeatureDSP))
288 emitAttribute(CSKYAttrs::CSKY_DSP_VERSION,
290 if (STI.hasFeature(CSKY::FeatureDSPV2))
292
293 if (STI.hasFeature(CSKY::FeatureVDSPV2))
295
296 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
297 STI.hasFeature(CSKY::FeatureFPUV2_DF))
299 else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) ||
300 STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
301 STI.hasFeature(CSKY::FeatureFPUV3_DF))
303
304 bool hasAnyFloatExt = STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
305 STI.hasFeature(CSKY::FeatureFPUV2_DF) ||
306 STI.hasFeature(CSKY::FeatureFPUV3_HF) ||
307 STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
308 STI.hasFeature(CSKY::FeatureFPUV3_DF);
309
310 if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat) &&
311 STI.hasFeature(CSKY::ModeHardFloatABI))
313 else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat))
315 else
317
318 unsigned HardFPFlag = 0;
319 if (STI.hasFeature(CSKY::FeatureFPUV3_HF))
320 HardFPFlag |= CSKYAttrs::FPU_HARDFP_HALF;
321 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
322 STI.hasFeature(CSKY::FeatureFPUV3_SF))
323 HardFPFlag |= CSKYAttrs::FPU_HARDFP_SINGLE;
324 if (STI.hasFeature(CSKY::FeatureFPUV2_DF) ||
325 STI.hasFeature(CSKY::FeatureFPUV3_DF))
326 HardFPFlag |= CSKYAttrs::FPU_HARDFP_DOUBLE;
327
328 if (HardFPFlag != 0) {
331 emitTextAttribute(CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754");
332 emitAttribute(CSKYAttrs::CSKY_FPU_HARDFP, HardFPFlag);
333 }
334}
std::string Name
ElfMappingSymbol State
CSKYTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
Container class for subtarget features.
MCContext & getContext() const
Definition: MCAssembler.h:182
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:551
ELFObjectWriter & getWriter()
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCAssembler & getAssembler()
Streaming machine code generation interface.
Definition: MCStreamer.h:213
MCContext & getContext() const
Definition: MCStreamer.h:300
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
Definition: MCStreamer.cpp:161
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:719
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:717
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
StringRef getCPU() const
MCStreamer & Streamer
Definition: MCStreamer.h:96
bool empty() const
Definition: SmallVector.h:94
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ArchKind parseCPUArch(StringRef CPU)
StringRef getArchName(ArchKind AK)
@ EF_CSKY_ABIV2
Definition: ELF.h:972
@ EF_CSKY_807
Definition: ELF.h:966
@ EF_CSKY_802
Definition: ELF.h:963
@ EF_CSKY_FLOAT
Definition: ELF.h:970
@ EF_CSKY_801
Definition: ELF.h:962
@ EF_CSKY_EFV1
Definition: ELF.h:973
@ EF_CSKY_805
Definition: ELF.h:965
@ EF_CSKY_860
Definition: ELF.h:968
@ EF_CSKY_803
Definition: ELF.h:964
@ EF_CSKY_810
Definition: ELF.h:967
@ STT_NOTYPE
Definition: ELF.h:1330
@ SHT_CSKY_ATTRIBUTES
Definition: ELF.h:1150
@ STB_LOCAL
Definition: ELF.h:1318
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition: LEB128.cpp:19