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