diff --git a/cpu/cpu_arm64.go b/cpu/cpu_arm64.go index 87dd5e3021..ebab2662ee 100644 --- a/cpu/cpu_arm64.go +++ b/cpu/cpu_arm64.go @@ -41,7 +41,7 @@ func archInit() { switch runtime.GOOS { case "freebsd": readARM64Registers() - case "linux", "netbsd": + case "linux", "netbsd", "darwin": doinit() default: // Most platforms don't seem to allow reading these registers. diff --git a/cpu/cpu_darwin_arm64.go b/cpu/cpu_darwin_arm64.go new file mode 100644 index 0000000000..e1ec145d1d --- /dev/null +++ b/cpu/cpu_darwin_arm64.go @@ -0,0 +1,56 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build arm64 +// +build darwin +// +build !ios + +package cpu + +const ( + commpageHasNeonFP16 = 0x00000008 // ARM v8.2 NEON FP16 supported + commpageHasNeon = 0x00000100 // Advanced SIMD is supported + commpageHasNeonHPFP = 0x00000200 // Advanced SIMD half-precision + commpageHasVfp = 0x00000400 // VFP is supported + commpageHasEvent = 0x00001000 // WFE/SVE and period event wakeup + commpageHasARMv82FHM = 0x00004000 // Optional ARMv8.2 FMLAL/FMLSL instructions (required in ARMv8.4) + commpageHasARMv8Crypto = 0x01000000 // Optional ARMv8 Crypto extensions + commpageHasARMv81Atomics = 0x02000000 // ARMv8.1 Atomic instructions supported + commpageHasARMv8Crc32 = 0x04000000 // Optional ARMv8 crc32 instructions (required in ARMv8.1) + commpageHasARMv82SHA512 = 0x80000000 // Optional ARMv8.2 SHA512 instructions + commpageHasARMv82SHA3 = 0x0000000100000000 // Optional ARMv8.2 SHA3 instructions +) + +func doinit() { + ARM64.HasFP = darwinCheckFeatureEnabled(commpageHasVfp) + ARM64.HasASIMD = darwinCheckFeatureEnabled(commpageHasNeon) + ARM64.HasCRC32 = darwinCheckFeatureEnabled(commpageHasARMv8Crc32) + ARM64.HasATOMICS = darwinCheckFeatureEnabled(commpageHasARMv81Atomics) + ARM64.HasFPHP = darwinCheckFeatureEnabled(commpageHasNeonFP16) + ARM64.HasASIMDHP = darwinCheckFeatureEnabled(commpageHasNeonHPFP) + ARM64.HasSHA3 = darwinCheckFeatureEnabled(commpageHasARMv82SHA3) + ARM64.HasSHA512 = darwinCheckFeatureEnabled(commpageHasARMv82SHA512) + ARM64.HasASIMDFHM = darwinCheckFeatureEnabled(commpageHasARMv82FHM) + ARM64.HasSVE = darwinCheckFeatureEnabled(commpageHasEvent) + + // There are no hw.optional sysctl values for the below features on Mac OS 11.0 + // to detect their supported state dynamically. Assume the CPU features that + // Apple Silicon M1 supports to be available as a minimal set of features + // to all Go programs running on darwin/arm64. + ARM64.HasEVTSTRM = true + ARM64.HasAES = true + ARM64.HasPMULL = true + ARM64.HasSHA1 = true + ARM64.HasSHA2 = true + ARM64.HasCPUID = true + ARM64.HasASIMDRDM = true + ARM64.HasJSCVT = true + ARM64.HasLRCPC = true + ARM64.HasDCPOP = true + ARM64.HasSM3 = true + ARM64.HasSM4 = true + ARM64.HasASIMDDP = true +} + +func darwinCheckFeatureEnabled(feature_vec uint64) bool diff --git a/cpu/cpu_darwin_arm64.s b/cpu/cpu_darwin_arm64.s new file mode 100644 index 0000000000..0de3e54e06 --- /dev/null +++ b/cpu/cpu_darwin_arm64.s @@ -0,0 +1,29 @@ +//go:build arm64 && gc +// +build arm64 +// +build gc + +#include "textflag.h" + +// func darwinCheckFeatureEnabled(feature_vec uint64) bool +TEXT ·darwinCheckFeatureEnabled(SB), NOSPLIT, $0-8 + MOVD feature_vec+0(FP), R0 + MOVD $0, ret+0(FP) // default to false + MOVD $1, R2 // set R2 as true boolean constan + +#ifdef GOOS_darwin // return if not darwin +#ifdef GOARCH_arm64 // return if not amd64 +// These values from: +// https://github.com/apple/darwin-xnu/blob/main/osfmk/arm/cpu_capabilities.h +#define arm_commpage64_base_address 0x0000000fffffc000 +#define arm_commpage64_cpu_capabilities64 (arm_commpage64_base_address+0x010) + MOVD $0xffffc000, R1 + MOVK $(0xf<<32), R1 + MOVD (R1), R1 + AND R1, R0 + CBZ R0, no_feature + MOVD R2, ret+8(FP) + +no_feature: +#endif +#endif + RET diff --git a/cpu/cpu_other_arm64.go b/cpu/cpu_other_arm64.go index f8c484f589..836f8ae19d 100644 --- a/cpu/cpu_other_arm64.go +++ b/cpu/cpu_other_arm64.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !linux && !netbsd && arm64 -// +build !linux,!netbsd,arm64 +//go:build !linux && !netbsd && !darwin && arm64 +// +build !linux,!netbsd,!darwin,arm64 package cpu diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index 5f7f843fe4..ba25551509 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -42,7 +42,7 @@ func TestAVX512HasAVX2AndAVX(t *testing.T) { } func TestARM64minimalFeatures(t *testing.T) { - if runtime.GOARCH != "arm64" || (runtime.GOOS == "darwin" || runtime.GOOS == "ios") { + if runtime.GOARCH != "arm64" || runtime.GOOS == "ios" { return } if !cpu.ARM64.HasASIMD {