1#include <zircon/features.h>
2#include <zircon/syscalls.h>
3
4void __init_cpu_features_resolver() {
5  if (__aarch64_cpu_features.features)
6    return;
7
8    // This ensures the vDSO is a direct link-time dependency of anything that
9    // needs this initializer code.
10#pragma comment(lib, "zircon")
11  uint32_t features;
12  zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features);
13  if (status != ZX_OK)
14    return;
15
16#define setCPUFeature(cpu_feature)                                             \
17  __aarch64_cpu_features.features |= 1ULL << cpu_feature
18
19  if (features & ZX_ARM64_FEATURE_ISA_FP)
20    setCPUFeature(FEAT_FP);
21  if (features & ZX_ARM64_FEATURE_ISA_ASIMD)
22    setCPUFeature(FEAT_SIMD);
23  if (features & ZX_ARM64_FEATURE_ISA_AES)
24    setCPUFeature(FEAT_AES);
25  if (features & ZX_ARM64_FEATURE_ISA_PMULL)
26    setCPUFeature(FEAT_PMULL);
27  if (features & ZX_ARM64_FEATURE_ISA_SHA1)
28    setCPUFeature(FEAT_SHA1);
29  if (features & ZX_ARM64_FEATURE_ISA_SHA256)
30    setCPUFeature(FEAT_SHA2);
31  if (features & ZX_ARM64_FEATURE_ISA_CRC32)
32    setCPUFeature(FEAT_CRC);
33  if (features & ZX_ARM64_FEATURE_ISA_RDM)
34    setCPUFeature(FEAT_RDM);
35  if (features & ZX_ARM64_FEATURE_ISA_SHA3)
36    setCPUFeature(FEAT_SHA3);
37  if (features & ZX_ARM64_FEATURE_ISA_SM4)
38    setCPUFeature(FEAT_SM4);
39  if (features & ZX_ARM64_FEATURE_ISA_DP)
40    setCPUFeature(FEAT_DOTPROD);
41  if (features & ZX_ARM64_FEATURE_ISA_FHM)
42    setCPUFeature(FEAT_FP16FML);
43  if (features & ZX_ARM64_FEATURE_ISA_SHA512)
44    setCPUFeature(FEAT_SHA3);
45  if (features & ZX_ARM64_FEATURE_ISA_I8MM)
46    setCPUFeature(FEAT_I8MM);
47  if (features & ZX_ARM64_FEATURE_ISA_SVE)
48    setCPUFeature(FEAT_SVE);
49
50  setCPUFeature(FEAT_INIT);
51}
52