1// Copyright 2026 The Go Authors. All rights reserved.
 2// Use of this source code is governed by a BSD-style
 3// license that can be found in the LICENSE file.
 4
 5//go:build darwin && arm64 && gc
 6
 7package cpu
 8
 9func doinit() {
10	setMinimalFeatures()
11
12	// The feature flags are explained in [Instruction Set Detection].
13	// There are some differences between MacOS versions:
14	//
15	// MacOS 11 and 12 do not have "hw.optional" sysctl values for some of the features.
16	//
17	// MacOS 13 changed some of the naming conventions to align with ARM Architecture Reference Manual.
18	// For example "hw.optional.armv8_2_sha512" became "hw.optional.arm.FEAT_SHA512".
19	// It currently checks both to stay compatible with MacOS 11 and 12.
20	// The old names also work with MacOS 13, however it's not clear whether
21	// they will continue working with future OS releases.
22	//
23	// Once MacOS 12 is no longer supported the old names can be removed.
24	//
25	// [Instruction Set Detection]: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
26
27	// Encryption, hashing and checksum capabilities
28
29	// For the following flags there are no MacOS 11 sysctl flags.
30	ARM64.HasAES = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_AES\x00"))
31	ARM64.HasPMULL = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_PMULL\x00"))
32	ARM64.HasSHA1 = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA1\x00"))
33	ARM64.HasSHA2 = true || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA256\x00"))
34
35	ARM64.HasSHA3 = darwinSysctlEnabled([]byte("hw.optional.armv8_2_sha3\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA3\x00"))
36	ARM64.HasSHA512 = darwinSysctlEnabled([]byte("hw.optional.armv8_2_sha512\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SHA512\x00"))
37
38	ARM64.HasCRC32 = darwinSysctlEnabled([]byte("hw.optional.armv8_crc32\x00"))
39
40	// Atomic and memory ordering
41	ARM64.HasATOMICS = darwinSysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_LSE\x00"))
42	ARM64.HasLRCPC = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_LRCPC\x00"))
43
44	// SIMD and floating point capabilities
45	ARM64.HasFPHP = darwinSysctlEnabled([]byte("hw.optional.neon_fp16\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FP16\x00"))
46	ARM64.HasASIMDHP = darwinSysctlEnabled([]byte("hw.optional.neon_hpfp\x00")) || darwinSysctlEnabled([]byte("hw.optional.AdvSIMD_HPFPCvt\x00"))
47	ARM64.HasASIMDRDM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_RDM\x00"))
48	ARM64.HasASIMDDP = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DotProd\x00"))
49	ARM64.HasASIMDFHM = darwinSysctlEnabled([]byte("hw.optional.armv8_2_fhm\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FHM\x00"))
50	ARM64.HasI8MM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_I8MM\x00"))
51
52	ARM64.HasJSCVT = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_JSCVT\x00"))
53	ARM64.HasFCMA = darwinSysctlEnabled([]byte("hw.optional.armv8_3_compnum\x00")) || darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_FCMA\x00"))
54
55	// Miscellaneous
56	ARM64.HasDCPOP = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DPB\x00"))
57	ARM64.HasEVTSTRM = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_ECV\x00"))
58	ARM64.HasDIT = darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_DIT\x00"))
59
60	// Not supported, but added for completeness
61	ARM64.HasCPUID = false
62
63	ARM64.HasSM3 = false  // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SM3\x00"))
64	ARM64.HasSM4 = false  // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SM4\x00"))
65	ARM64.HasSVE = false  // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SVE\x00"))
66	ARM64.HasSVE2 = false // darwinSysctlEnabled([]byte("hw.optional.arm.FEAT_SVE2\x00"))
67}