Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFStreamer.cpp
35294 views
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"
15
#include "MCTargetDesc/CSKYAsmBackend.h"
16
#include "MCTargetDesc/CSKYBaseInfo.h"
17
#include "llvm/BinaryFormat/ELF.h"
18
#include "llvm/MC/MCAssembler.h"
19
#include "llvm/MC/MCContext.h"
20
#include "llvm/MC/MCSectionELF.h"
21
#include "llvm/MC/MCSubtargetInfo.h"
22
#include "llvm/MC/MCSymbolELF.h"
23
#include "llvm/Support/CSKYAttributes.h"
24
#include "llvm/Support/Casting.h"
25
#include "llvm/Support/LEB128.h"
26
#include "llvm/TargetParser/CSKYTargetParser.h"
27
28
using namespace llvm;
29
30
// This part is for ELF object output.
31
CSKYTargetELFStreamer::CSKYTargetELFStreamer(MCStreamer &S,
32
const MCSubtargetInfo &STI)
33
: CSKYTargetStreamer(S), CurrentVendor("csky") {
34
ELFObjectWriter &W = getStreamer().getWriter();
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
68
MCELFStreamer &CSKYTargetELFStreamer::getStreamer() {
69
return static_cast<MCELFStreamer &>(Streamer);
70
}
71
72
void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
73
setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
74
}
75
76
void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute,
77
StringRef String) {
78
setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
79
}
80
81
void CSKYTargetELFStreamer::finishAttributeSection() {
82
if (Contents.empty())
83
return;
84
85
if (AttributeSection) {
86
Streamer.switchSection(AttributeSection);
87
} else {
88
MCAssembler &MCA = getStreamer().getAssembler();
89
AttributeSection = MCA.getContext().getELFSection(
90
".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0);
91
Streamer.switchSection(AttributeSection);
92
Streamer.emitInt8(ELFAttrs::Format_Version);
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
107
Streamer.emitInt8(ELFAttrs::File);
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) {
113
Streamer.emitULEB128IntValue(item.Tag);
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
135
size_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
159
void 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
178
void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
179
StringRef CPU = STI.getCPU();
180
CSKY::ArchKind ArchID = CSKY::parseCPUArch(CPU);
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))
250
ISAFlag |= CSKYAttrs::ISA_DSP_ENHANCE;
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,
289
CSKYAttrs::DSP_VERSION_EXTENSION);
290
if (STI.hasFeature(CSKY::FeatureDSPV2))
291
emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, CSKYAttrs::DSP_VERSION_2);
292
293
if (STI.hasFeature(CSKY::FeatureVDSPV2))
294
emitAttribute(CSKYAttrs::CSKY_VDSP_VERSION, CSKYAttrs::VDSP_VERSION_2);
295
296
if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||
297
STI.hasFeature(CSKY::FeatureFPUV2_DF))
298
emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_2);
299
else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) ||
300
STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
301
STI.hasFeature(CSKY::FeatureFPUV3_DF))
302
emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_3);
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))
312
emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_HARD);
313
else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat))
314
emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFTFP);
315
else
316
emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFT);
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) {
329
emitAttribute(CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NEEDED);
330
emitAttribute(CSKYAttrs::CSKY_FPU_EXCEPTION, CSKYAttrs::NEEDED);
331
emitTextAttribute(CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754");
332
emitAttribute(CSKYAttrs::CSKY_FPU_HARDFP, HardFPFlag);
333
}
334
}
335
336