Skip to content

Commit 7942793

Browse files
committed
cpu: support darwin/arm64 CPU feature detection
Support ARM64 features detection. The CPU features which are supported by Apple Silicon M1 are assumed as the minimal set of features for Go programs running on darwin/arm64. The ARM64 supporting features are referred to https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features
1 parent 0f9fa26 commit 7942793

File tree

5 files changed

+89
-4
lines changed

5 files changed

+89
-4
lines changed

cpu/cpu_arm64.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func archInit() {
4141
switch runtime.GOOS {
4242
case "freebsd":
4343
readARM64Registers()
44-
case "linux", "netbsd":
44+
case "linux", "netbsd", "darwin":
4545
doinit()
4646
default:
4747
// Most platforms don't seem to allow reading these registers.

cpu/cpu_darwin_arm64.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2021 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+
// +build arm64
6+
// +build darwin
7+
// +build !ios
8+
9+
package cpu
10+
11+
const (
12+
commpageHasNeonFP16 = 0x00000008 // ARM v8.2 NEON FP16 supported
13+
commpageHasNeon = 0x00000100 // Advanced SIMD is supported
14+
commpageHasNeonHPFP = 0x00000200 // Advanced SIMD half-precision
15+
commpageHasVfp = 0x00000400 // VFP is supported
16+
commpageHasEvent = 0x00001000 // WFE/SVE and period event wakeup
17+
commpageHasARMv82FHM = 0x00004000 // Optional ARMv8.2 FMLAL/FMLSL instructions (required in ARMv8.4)
18+
commpageHasARMv8Crypto = 0x01000000 // Optional ARMv8 Crypto extensions
19+
commpageHasARMv81Atomics = 0x02000000 // ARMv8.1 Atomic instructions supported
20+
commpageHasARMv8Crc32 = 0x04000000 // Optional ARMv8 crc32 instructions (required in ARMv8.1)
21+
commpageHasARMv82SHA512 = 0x80000000 // Optional ARMv8.2 SHA512 instructions
22+
commpageHasARMv82SHA3 = 0x0000000100000000 // Optional ARMv8.2 SHA3 instructions
23+
)
24+
25+
func doinit() {
26+
ARM64.HasFP = darwinCheckFeatureEnabled(commpageHasVfp)
27+
ARM64.HasASIMD = darwinCheckFeatureEnabled(commpageHasNeon)
28+
ARM64.HasCRC32 = darwinCheckFeatureEnabled(commpageHasARMv8Crc32)
29+
ARM64.HasATOMICS = darwinCheckFeatureEnabled(commpageHasARMv81Atomics)
30+
ARM64.HasFPHP = darwinCheckFeatureEnabled(commpageHasNeonFP16)
31+
ARM64.HasASIMDHP = darwinCheckFeatureEnabled(commpageHasNeonHPFP)
32+
ARM64.HasSHA3 = darwinCheckFeatureEnabled(commpageHasARMv82SHA3)
33+
ARM64.HasSHA512 = darwinCheckFeatureEnabled(commpageHasARMv82SHA512)
34+
ARM64.HasASIMDFHM = darwinCheckFeatureEnabled(commpageHasARMv82FHM)
35+
ARM64.HasSVE = darwinCheckFeatureEnabled(commpageHasEvent)
36+
37+
// There are no hw.optional sysctl values for the below features on Mac OS 11.0
38+
// to detect their supported state dynamically. Assume the CPU features that
39+
// Apple Silicon M1 supports to be available as a minimal set of features
40+
// to all Go programs running on darwin/arm64.
41+
ARM64.HasEVTSTRM = true
42+
ARM64.HasAES = true
43+
ARM64.HasPMULL = true
44+
ARM64.HasSHA1 = true
45+
ARM64.HasSHA2 = true
46+
ARM64.HasCPUID = true
47+
ARM64.HasASIMDRDM = true
48+
ARM64.HasJSCVT = true
49+
ARM64.HasLRCPC = true
50+
ARM64.HasDCPOP = true
51+
ARM64.HasSM3 = true
52+
ARM64.HasSM4 = true
53+
ARM64.HasASIMDDP = true
54+
}
55+
56+
func darwinCheckFeatureEnabled(feature_vec uint64) bool

cpu/cpu_darwin_arm64.s

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//go:build arm64 && gc
2+
// +build arm64
3+
// +build gc
4+
5+
#include "textflag.h"
6+
7+
// func darwinCheckFeatureEnabled(feature_vec uint64) bool
8+
TEXT ·darwinCheckFeatureEnabled(SB), NOSPLIT, $0-8
9+
MOVD feature_vec+0(FP), R0
10+
MOVD $0, ret+0(FP) // default to false
11+
MOVD $1, R2 // set R2 as true boolean constan
12+
13+
#ifdef GOOS_darwin // return if not darwin
14+
#ifdef GOARCH_arm64 // return if not arm64
15+
// These values from:
16+
// https://github.com/apple/darwin-xnu/blob/main/osfmk/arm/cpu_capabilities.h
17+
#define arm_commpage64_base_address 0x0000000fffffc000
18+
#define arm_commpage64_cpu_capabilities64 (arm_commpage64_base_address+0x010)
19+
MOVD $0xffffc000, R1
20+
MOVK $(0xf<<32), R1
21+
MOVD (R1), R1
22+
AND R1, R0
23+
CBZ R0, no_feature
24+
MOVD R2, ret+8(FP)
25+
26+
no_feature:
27+
#endif
28+
#endif
29+
RET

cpu/cpu_other_arm64.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build !linux && !netbsd && arm64
6-
// +build !linux,!netbsd,arm64
5+
//go:build !linux && !netbsd && !darwin && arm64
6+
// +build !linux,!netbsd,!darwin,arm64
77

88
package cpu
99

cpu/cpu_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestAVX512HasAVX2AndAVX(t *testing.T) {
4242
}
4343

4444
func TestARM64minimalFeatures(t *testing.T) {
45-
if runtime.GOARCH != "arm64" || (runtime.GOOS == "darwin" || runtime.GOOS == "ios") {
45+
if runtime.GOARCH != "arm64" || runtime.GOOS == "ios" {
4646
return
4747
}
4848
if !cpu.ARM64.HasASIMD {

0 commit comments

Comments
 (0)