Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/riscv.c
213799 views
1
//=== cpu_model/riscv.c - Update RISC-V Feature Bits Structure -*- 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 "cpu_model.h"
10
11
#define RISCV_FEATURE_BITS_LENGTH 2
12
struct {
13
unsigned length;
14
unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
15
} __riscv_feature_bits __attribute__((visibility("hidden"), nocommon));
16
17
struct {
18
unsigned mvendorid;
19
unsigned long long marchid;
20
unsigned long long mimpid;
21
} __riscv_cpu_model __attribute__((visibility("hidden"), nocommon));
22
23
// NOTE: Should sync-up with RISCVFeatures.td
24
// TODO: Maybe generate a header from tablegen then include it.
25
#define A_GROUPID 0
26
#define A_BITMASK (1ULL << 0)
27
#define B_GROUPID 0
28
#define B_BITMASK (1ULL << 1)
29
#define C_GROUPID 0
30
#define C_BITMASK (1ULL << 2)
31
#define D_GROUPID 0
32
#define D_BITMASK (1ULL << 3)
33
#define E_GROUPID 0
34
#define E_BITMASK (1ULL << 4)
35
#define F_GROUPID 0
36
#define F_BITMASK (1ULL << 5)
37
#define H_GROUPID 0
38
#define H_BITMASK (1ULL << 7)
39
#define I_GROUPID 0
40
#define I_BITMASK (1ULL << 8)
41
#define M_GROUPID 0
42
#define M_BITMASK (1ULL << 12)
43
#define Q_GROUPID 0
44
#define Q_BITMASK (1ULL << 16)
45
#define V_GROUPID 0
46
#define V_BITMASK (1ULL << 21)
47
#define ZACAS_GROUPID 0
48
#define ZACAS_BITMASK (1ULL << 26)
49
#define ZBA_GROUPID 0
50
#define ZBA_BITMASK (1ULL << 27)
51
#define ZBB_GROUPID 0
52
#define ZBB_BITMASK (1ULL << 28)
53
#define ZBC_GROUPID 0
54
#define ZBC_BITMASK (1ULL << 29)
55
#define ZBKB_GROUPID 0
56
#define ZBKB_BITMASK (1ULL << 30)
57
#define ZBKC_GROUPID 0
58
#define ZBKC_BITMASK (1ULL << 31)
59
#define ZBKX_GROUPID 0
60
#define ZBKX_BITMASK (1ULL << 32)
61
#define ZBS_GROUPID 0
62
#define ZBS_BITMASK (1ULL << 33)
63
#define ZFA_GROUPID 0
64
#define ZFA_BITMASK (1ULL << 34)
65
#define ZFH_GROUPID 0
66
#define ZFH_BITMASK (1ULL << 35)
67
#define ZFHMIN_GROUPID 0
68
#define ZFHMIN_BITMASK (1ULL << 36)
69
#define ZICBOZ_GROUPID 0
70
#define ZICBOZ_BITMASK (1ULL << 37)
71
#define ZICOND_GROUPID 0
72
#define ZICOND_BITMASK (1ULL << 38)
73
#define ZIHINTNTL_GROUPID 0
74
#define ZIHINTNTL_BITMASK (1ULL << 39)
75
#define ZIHINTPAUSE_GROUPID 0
76
#define ZIHINTPAUSE_BITMASK (1ULL << 40)
77
#define ZKND_GROUPID 0
78
#define ZKND_BITMASK (1ULL << 41)
79
#define ZKNE_GROUPID 0
80
#define ZKNE_BITMASK (1ULL << 42)
81
#define ZKNH_GROUPID 0
82
#define ZKNH_BITMASK (1ULL << 43)
83
#define ZKSED_GROUPID 0
84
#define ZKSED_BITMASK (1ULL << 44)
85
#define ZKSH_GROUPID 0
86
#define ZKSH_BITMASK (1ULL << 45)
87
#define ZKT_GROUPID 0
88
#define ZKT_BITMASK (1ULL << 46)
89
#define ZTSO_GROUPID 0
90
#define ZTSO_BITMASK (1ULL << 47)
91
#define ZVBB_GROUPID 0
92
#define ZVBB_BITMASK (1ULL << 48)
93
#define ZVBC_GROUPID 0
94
#define ZVBC_BITMASK (1ULL << 49)
95
#define ZVFH_GROUPID 0
96
#define ZVFH_BITMASK (1ULL << 50)
97
#define ZVFHMIN_GROUPID 0
98
#define ZVFHMIN_BITMASK (1ULL << 51)
99
#define ZVKB_GROUPID 0
100
#define ZVKB_BITMASK (1ULL << 52)
101
#define ZVKG_GROUPID 0
102
#define ZVKG_BITMASK (1ULL << 53)
103
#define ZVKNED_GROUPID 0
104
#define ZVKNED_BITMASK (1ULL << 54)
105
#define ZVKNHA_GROUPID 0
106
#define ZVKNHA_BITMASK (1ULL << 55)
107
#define ZVKNHB_GROUPID 0
108
#define ZVKNHB_BITMASK (1ULL << 56)
109
#define ZVKSED_GROUPID 0
110
#define ZVKSED_BITMASK (1ULL << 57)
111
#define ZVKSH_GROUPID 0
112
#define ZVKSH_BITMASK (1ULL << 58)
113
#define ZVKT_GROUPID 0
114
#define ZVKT_BITMASK (1ULL << 59)
115
#define ZVE32X_GROUPID 0
116
#define ZVE32X_BITMASK (1ULL << 60)
117
#define ZVE32F_GROUPID 0
118
#define ZVE32F_BITMASK (1ULL << 61)
119
#define ZVE64X_GROUPID 0
120
#define ZVE64X_BITMASK (1ULL << 62)
121
#define ZVE64F_GROUPID 0
122
#define ZVE64F_BITMASK (1ULL << 63)
123
#define ZVE64D_GROUPID 1
124
#define ZVE64D_BITMASK (1ULL << 0)
125
#define ZIMOP_GROUPID 1
126
#define ZIMOP_BITMASK (1ULL << 1)
127
#define ZCA_GROUPID 1
128
#define ZCA_BITMASK (1ULL << 2)
129
#define ZCB_GROUPID 1
130
#define ZCB_BITMASK (1ULL << 3)
131
#define ZCD_GROUPID 1
132
#define ZCD_BITMASK (1ULL << 4)
133
#define ZCF_GROUPID 1
134
#define ZCF_BITMASK (1ULL << 5)
135
#define ZCMOP_GROUPID 1
136
#define ZCMOP_BITMASK (1ULL << 6)
137
#define ZAWRS_GROUPID 1
138
#define ZAWRS_BITMASK (1ULL << 7)
139
#define ZILSD_GROUPID 1
140
#define ZILSD_BITMASK (1ULL << 8)
141
#define ZCLSD_GROUPID 1
142
#define ZCLSD_BITMASK (1ULL << 9)
143
#define ZCMP_GROUPID 1
144
#define ZCMP_BITMASK (1ULL << 10)
145
146
#if defined(__linux__)
147
148
// The RISC-V hwprobe interface is documented here:
149
// <https://docs.kernel.org/arch/riscv/hwprobe.html>.
150
151
static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
152
long arg4, long arg5) {
153
register long a7 __asm__("a7") = number;
154
register long a0 __asm__("a0") = arg1;
155
register long a1 __asm__("a1") = arg2;
156
register long a2 __asm__("a2") = arg3;
157
register long a3 __asm__("a3") = arg4;
158
register long a4 __asm__("a4") = arg5;
159
__asm__ __volatile__("ecall\n\t"
160
: "=r"(a0)
161
: "r"(a7), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
162
: "memory");
163
return a0;
164
}
165
166
#define RISCV_HWPROBE_KEY_MVENDORID 0
167
#define RISCV_HWPROBE_KEY_MARCHID 1
168
#define RISCV_HWPROBE_KEY_MIMPID 2
169
#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
170
#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1ULL << 0)
171
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
172
#define RISCV_HWPROBE_IMA_FD (1ULL << 0)
173
#define RISCV_HWPROBE_IMA_C (1ULL << 1)
174
#define RISCV_HWPROBE_IMA_V (1ULL << 2)
175
#define RISCV_HWPROBE_EXT_ZBA (1ULL << 3)
176
#define RISCV_HWPROBE_EXT_ZBB (1ULL << 4)
177
#define RISCV_HWPROBE_EXT_ZBS (1ULL << 5)
178
#define RISCV_HWPROBE_EXT_ZICBOZ (1ULL << 6)
179
#define RISCV_HWPROBE_EXT_ZBC (1ULL << 7)
180
#define RISCV_HWPROBE_EXT_ZBKB (1ULL << 8)
181
#define RISCV_HWPROBE_EXT_ZBKC (1ULL << 9)
182
#define RISCV_HWPROBE_EXT_ZBKX (1ULL << 10)
183
#define RISCV_HWPROBE_EXT_ZKND (1ULL << 11)
184
#define RISCV_HWPROBE_EXT_ZKNE (1ULL << 12)
185
#define RISCV_HWPROBE_EXT_ZKNH (1ULL << 13)
186
#define RISCV_HWPROBE_EXT_ZKSED (1ULL << 14)
187
#define RISCV_HWPROBE_EXT_ZKSH (1ULL << 15)
188
#define RISCV_HWPROBE_EXT_ZKT (1ULL << 16)
189
#define RISCV_HWPROBE_EXT_ZVBB (1ULL << 17)
190
#define RISCV_HWPROBE_EXT_ZVBC (1ULL << 18)
191
#define RISCV_HWPROBE_EXT_ZVKB (1ULL << 19)
192
#define RISCV_HWPROBE_EXT_ZVKG (1ULL << 20)
193
#define RISCV_HWPROBE_EXT_ZVKNED (1ULL << 21)
194
#define RISCV_HWPROBE_EXT_ZVKNHA (1ULL << 22)
195
#define RISCV_HWPROBE_EXT_ZVKNHB (1ULL << 23)
196
#define RISCV_HWPROBE_EXT_ZVKSED (1ULL << 24)
197
#define RISCV_HWPROBE_EXT_ZVKSH (1ULL << 25)
198
#define RISCV_HWPROBE_EXT_ZVKT (1ULL << 26)
199
#define RISCV_HWPROBE_EXT_ZFH (1ULL << 27)
200
#define RISCV_HWPROBE_EXT_ZFHMIN (1ULL << 28)
201
#define RISCV_HWPROBE_EXT_ZIHINTNTL (1ULL << 29)
202
#define RISCV_HWPROBE_EXT_ZVFH (1ULL << 30)
203
#define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31)
204
#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
205
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
206
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
207
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
208
#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
209
#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
210
#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
211
#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
212
#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
213
#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
214
#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
215
#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
216
#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
217
#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
218
#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
219
#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
220
#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
221
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
222
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
223
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
224
#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
225
#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
226
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
227
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
228
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
229
/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
230
231
struct riscv_hwprobe {
232
long long key;
233
unsigned long long value;
234
};
235
236
#define __NR_riscv_hwprobe 258
237
static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
238
return syscall_impl_5_args(__NR_riscv_hwprobe, (long)Hwprobes, len, 0, 0, 0);
239
}
240
241
#define SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(EXTNAME) \
242
SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_EXT_##EXTNAME, EXTNAME)
243
244
#define SET_SINGLE_IMAEXT_RISCV_FEATURE(HWPROBE_BITMASK, EXT) \
245
SET_SINGLE_RISCV_FEATURE(IMAEXT0Value &HWPROBE_BITMASK, EXT)
246
247
#define SET_SINGLE_RISCV_FEATURE(COND, EXT) \
248
if (COND) { \
249
SET_RISCV_FEATURE(EXT); \
250
}
251
252
#define SET_RISCV_FEATURE(EXT) features[EXT##_GROUPID] |= EXT##_BITMASK
253
254
static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
255
256
// Note: If a hwprobe key is unknown to the kernel, its key field
257
// will be cleared to -1, and its value set to 0.
258
// This unsets all extension bitmask bits.
259
260
// Init VendorID, ArchID, ImplID
261
__riscv_cpu_model.mvendorid = Hwprobes[2].value;
262
__riscv_cpu_model.marchid = Hwprobes[3].value;
263
__riscv_cpu_model.mimpid = Hwprobes[4].value;
264
265
// Init standard extension
266
// TODO: Maybe Extension implied generate from tablegen?
267
268
unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
269
int i;
270
271
for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
272
features[i] = 0;
273
274
// Check RISCV_HWPROBE_KEY_BASE_BEHAVIOR
275
unsigned long long BaseValue = Hwprobes[0].value;
276
if (BaseValue & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) {
277
SET_RISCV_FEATURE(I);
278
SET_RISCV_FEATURE(M);
279
SET_RISCV_FEATURE(A);
280
}
281
282
// Check RISCV_HWPROBE_KEY_IMA_EXT_0
283
unsigned long long IMAEXT0Value = Hwprobes[1].value;
284
if (IMAEXT0Value & RISCV_HWPROBE_IMA_FD) {
285
SET_RISCV_FEATURE(F);
286
SET_RISCV_FEATURE(D);
287
}
288
289
SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_C, C);
290
SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_V, V);
291
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBA);
292
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBB);
293
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBS);
294
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICBOZ);
295
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBC);
296
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKB);
297
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKC);
298
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBKX);
299
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKND);
300
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNE);
301
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKNH);
302
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSED);
303
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKSH);
304
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZKT);
305
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBB);
306
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVBC);
307
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKB);
308
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKG);
309
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNED);
310
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHA);
311
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKNHB);
312
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSED);
313
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKSH);
314
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVKT);
315
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFH);
316
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFHMIN);
317
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTNTL);
318
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHINTPAUSE);
319
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFH);
320
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFHMIN);
321
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFA);
322
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO);
323
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS);
324
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND);
325
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X);
326
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F);
327
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X);
328
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F);
329
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D);
330
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP);
331
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA);
332
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB);
333
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD);
334
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
335
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
336
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
337
338
for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
339
__riscv_feature_bits.features[i] = features[i];
340
}
341
342
#endif // defined(__linux__)
343
344
static int FeaturesBitCached = 0;
345
346
void __init_riscv_feature_bits(void *);
347
static void __init_riscv_feature_bits_ctor(void) CONSTRUCTOR_ATTRIBUTE;
348
349
// A constructor function that sets __riscv_feature_bits
350
// to the right values. This needs to run only once. This constructor is given
351
// the highest priority and it should run before constructors without the
352
// priority set. However, it still runs after ifunc initializers and needs to
353
// be called explicitly there.
354
355
static void CONSTRUCTOR_ATTRIBUTE __init_riscv_feature_bits_ctor(void) {
356
__init_riscv_feature_bits(0);
357
}
358
359
// PlatformArgs allows the platform to provide pre-computed data and access it
360
// without extra effort. For example, Linux could pass the vDSO object to avoid
361
// an extra system call.
362
void __init_riscv_feature_bits(void *PlatformArgs) {
363
364
if (FeaturesBitCached)
365
return;
366
367
__riscv_feature_bits.length = RISCV_FEATURE_BITS_LENGTH;
368
369
#if defined(__linux__)
370
struct riscv_hwprobe Hwprobes[] = {
371
{RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0}, {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
372
{RISCV_HWPROBE_KEY_MVENDORID, 0}, {RISCV_HWPROBE_KEY_MARCHID, 0},
373
{RISCV_HWPROBE_KEY_MIMPID, 0},
374
};
375
if (initHwProbe(Hwprobes, sizeof(Hwprobes) / sizeof(Hwprobes[0])))
376
return;
377
378
initRISCVFeature(Hwprobes);
379
#endif // defined(__linux__)
380
381
FeaturesBitCached = 1;
382
}
383
384