45 #elif defined(__APPLE__)
46 #include <sys/sysctl.h>
48static int have_feature(
const char *feature)
51 size_t size =
sizeof(supported);
52 if (sysctlbyname(feature, &supported, &
size,
NULL, 0) != 0) {
57 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
61 #define HWCAP_AARCH64_SVE (1 << 22)
62 #define HWCAP2_AARCH64_SME (1 << 23)
66int checkasm_has_sve(
void)
69 #ifdef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE
70 return IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE);
74 #elif defined(__APPLE__)
77 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
84int checkasm_has_sme(
void)
87 #ifdef PF_ARM_SME_INSTRUCTIONS_AVAILABLE
88 return IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE);
92 #elif defined(__APPLE__)
93 return have_feature(
"hw.optional.arm.FEAT_SME");
94 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
105 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
106 #include <sys/auxv.h>
108 #ifndef HWCAP_ARM_VFP
109 #define HWCAP_ARM_VFP (1 << 6)
111 #ifndef HWCAP_ARM_NEON
112 #define HWCAP_ARM_NEON (1 << 12)
114 #ifndef HWCAP_ARM_VFPD32
115 #define HWCAP_ARM_VFPD32 (1 << 19)
124 return checked_call_ptr;
127COLD void checkasm_init_arm(
void)
129 if (checkasm_has_vfp())
130 checked_call_ptr = checkasm_checked_call_vfp;
132 checked_call_ptr = checkasm_checked_call_novfp;
135int checkasm_has_vfpd32(
void)
138 #ifdef PF_ARM_VFP_32_REGISTERS_AVAILABLE
139 return IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE);
143 #elif (defined(__APPLE__) && __ARM_ARCH >= 7)
145 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
153int checkasm_has_vfp(
void)
155 #if defined(__APPLE__) || defined(_WIN32)
157 #elif HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
166#if (ARCH_ARM || ARCH_AARCH64) && (defined(__linux__) || defined(_WIN32))
172struct arm_implementer {
174 const struct arm_core *parts;
181 unsigned implementer;
185COLD static void find_implementer_part(
const struct arm_core_id *core,
186 const char **implementer,
const char **part)
192 for (
int j = 0; cores[j].name; j++) {
193 if (cores[j].
id == core->part) {
194 *part = cores[j].name;
203COLD static size_t print_cores(
char *buf,
size_t buflen,
const struct arm_core_id *cores,
207 for (
unsigned i = 0;
i < nb_cores;
i++) {
210 char buf1[20], buf2[20];
211 snprintf(buf1,
sizeof(buf1),
"Implementer 0x%02x", cores[
i].implementer);
212 snprintf(buf2,
sizeof(buf2),
"Part 0x%03x", cores[
i].part);
213 const char *implementer = buf1, *part = buf2;
214 find_implementer_part(&cores[
i], &implementer, &part);
215 pos += snprintf(buf +
pos, buflen -
pos,
"%s%s %s",
i > 0 ?
", " :
"",
222COLD const char *checkasm_get_arm_cpuinfo(
char *buf,
size_t buflen,
int affinity)
224 FILE *
f = fopen(
"/proc/cpuinfo",
"r");
228 int implementer = -1, part = -1, processor = -1;
229 char model[100] =
"";
230 struct arm_core_id cores[5];
231 unsigned nb_cores = 0;
243 if ((ptr = strchr(
line,
':')) !=
NULL) {
247 const char *
value = ptr + 1;
249 while (isspace(*
value))
252 while (ptr >
line && isspace(ptr[-1]))
255 if (!strcmp(
line,
"CPU implementer")) {
256 implementer = (int) strtol(
value,
NULL, 0);
257 }
else if (!strcmp(
line,
"CPU part")) {
259 }
else if (!strcmp(
line,
"processor")) {
260 processor = (int) strtol(
value,
NULL, 0);
261 }
else if (!strcmp(
line,
"Model")) {
262 snprintf(model,
sizeof(model),
"%s",
value);
264 }
else if (
line[0] ==
'\0') {
267 if (implementer != -1 && part != -1
268 && (affinity < 0 || affinity == processor)) {
269 struct arm_core_id core = { implementer, part };
271 for (
i = 0;
i < nb_cores;
i++)
272 if (memcmp(&cores[
i], &core,
sizeof(core)) == 0)
277 cores[nb_cores++] = core;
280 implementer = part = processor = -1;
286 if (model[0] ==
'\0' && nb_cores == 0)
290 snprintf(buf, buflen,
"%s", model);
294 size_t pos = print_cores(buf, buflen, cores, nb_cores);
296 if (
pos < buflen && model[0] !=
'\0')
297 pos += snprintf(buf +
pos, buflen -
pos,
" (%s)", model);
304COLD const char *checkasm_get_arm_win32_reg(
char *buf,
size_t buflen,
int affinity)
306 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
308 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
309 "Hardware\\Description\\System\\CentralProcessor", 0, KEY_READ,
315 char cpu_name[100] =
"";
316 struct arm_core_id cores[5];
317 unsigned nb_cores = 0;
323 DWORD name_size =
sizeof(
name);
328 unsigned processor = strtoul(
name,
NULL, 0);
330 if (affinity >= 0 && (
unsigned) affinity != processor)
334 DWORD midr_el1_size =
sizeof(midr_el1);
336 if (RegGetValueA(
key,
name,
"CP 4000", RRF_RT_QWORD,
NULL, &midr_el1,
339 unsigned implementer = (midr_el1 >> 24) & 0xff;
340 unsigned part = (midr_el1 >> 4) & 0xfff;
342 struct arm_core_id core = { implementer, part };
344 for (
i = 0;
i < nb_cores;
i++)
345 if (memcmp(&cores[
i], &core,
sizeof(core)) == 0)
350 cores[nb_cores++] = core;
352 DWORD cpu_name_size =
sizeof(cpu_name);
353 if (RegGetValueA(
key,
name,
"ProcessorNameString", RRF_RT_REG_SZ,
NULL, cpu_name,
364 if (cpu_name[0] ==
'\0' && nb_cores == 0)
368 snprintf(buf, buflen,
"%s", cpu_name);
372 size_t pos = print_cores(buf, buflen, cores, nb_cores);
374 if (
pos < buflen && cpu_name[0] !=
'\0')
375 pos += snprintf(buf +
pos, buflen -
pos,
" (%s)", cpu_name);
#define i(width, name, range_min, range_max)
static const struct arm_implementer arm_implementers[]
COLD unsigned long checkasm_getauxval(unsigned long type)