8000 Merge branch 'master' into windows-conin · golang/sys@2f88dfd · GitHub
[go: up one dir, main page]

Skip to content

Commit 2f88dfd

Browse files
authored
Merge branch 'master' into windows-conin
2 parents 1ba63fc + b215a1c commit 2f88dfd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2473
-613
lines changed

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@
55
This repository holds supplemental Go packages for low-level interactions with
66
the operating system.
77

8-
## Download/Install
9-
10-
The easiest way to install is to run `go get -u golang.org/x/sys`. You can
11-
also manually git clone the repository to `$GOPATH/src/golang.org/x/sys`.
12-
138
## Report Issues / Send Patches
149

1510
This repository uses Gerrit for code changes. To learn how to submit changes to
16-
this repository, see https://golang.org/doc/contribute.html.
11+
this repository, see https://go.dev/doc/contribute.
12+
13+
The git repository is https://go.googlesource.com/sys.
1714

1815
The main issue tracker for the sys repository is located at
19-
https://github.com/golang/go/issues. Prefix your issue with "x/sys:" in the
16+
https://go.dev/issues. Prefix your issue with "x/sys:" in the
2017
subject line, so it is easy to find.

cpu/asm_darwin_x86_gc.s

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2024 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 && amd64 && gc
6+
7+
#include "textflag.h"
8+
9+
TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
10+
JMP libc_sysctl(SB)
11+
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
12+
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
13+
14+
TEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0
15+
JMP libc_sysctlbyname(SB)
16+
GLOBL ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8
17+
DATA ·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB)

cpu/cpu.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ var X86 struct {
7272
HasSSSE3 bool // Supplemental streaming SIMD extension 3
7373
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
7474
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
75+
HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add
76+
HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions
77+
HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions
7578
_ CacheLinePad
7679
}
7780

cpu/cpu_darwin_x86.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2024 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 && amd64 && gc
6+
7+
package cpu
8+
9+
// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl
10+
// call (see issue 43089). It also restricts AVX512 support for Darwin to
11+
// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233).
12+
//
13+
// Background:
14+
// Darwin implements a special mechanism to economize on thread state when
15+
// AVX512 specific registers are not in use. This scheme minimizes state when
16+
// preempting threads that haven't yet used any AVX512 instructions, but adds
17+
// special requirements to check for AVX512 hardware support at runtime (e.g.
18+
// via sysctl call or commpage inspection). See issue 43089 and link below for
19+
// full background:
20+
// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240
21+
//
22+
// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0
23+
// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption
24+
// of the AVX512 mask registers (K0-K7) upon signal return. For this reason
25+
// AVX512 is considered unsafe to use on Darwin for kernel versions prior to
26+
// 21.3.0, where a fix has been confirmed. See issue 49233 for full background.
27+
func darwinSupportsAVX512() bool {
28+
return darwinSysctlEnabled([]byte("hw.optional.avx512f\x00")) && darwinKernelVersionCheck(21, 3, 0)
29+
}
30+
31+
// Ensure Darwin kernel version is at least major.minor.patch, avoiding dependencies
32+
func darwinKernelVersionCheck(major, minor, patch int) bool {
33+
var release [256]byte
34+
err := darwinOSRelease(&release)
35+
if err != nil {
36+
return false
37+
}
38+
39+
var mmp [3]int
40+
c := 0
41+
Loop:
42+
for _, b := range release[:] {
43+
switch {
44+
case b >= '0' && b <= '9':
45+
mmp[c] = 10*mmp[c] + int(b-'0')
46+
case b == '.':
47+
c++
48+
if c > 2 {
49+
return false
50+
}
51+
case b == 0:
52+
break Loop
53+
default:
54+
return false
55+
}
56+
}
57+
if c != 2 {
58+
return false
59+
}
60+
return mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] == minor && mmp[2] >= patch)
61+
}

cpu/cpu_gc_x86.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
package cpu
88

9-
// cpuid is implemented in cpu_x86.s for gc compiler
9+
// cpuid is implemented in cpu_gc_x86.s for gc compiler
1010
// and in cpu_gccgo.c for gccgo.
1111
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
1212

13-
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
13+
// xgetbv with ecx = 0 is implemented in cpu_gc_x86.s for gc compiler
1414
// and in cpu_gccgo.c for gccgo.
1515
func xgetbv() (eax, edx uint32)

cpu/cpu_x86.s renamed to cpu/cpu_gc_x86.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ TEXT ·cpuid(SB), NOSPLIT, $0-24
1818
RET
1919

2020
// func xgetbv() (eax, edx uint32)
21-
TEXT ·xgetbv(SB),NOSPLIT,$0-8
21+
TEXT ·xgetbv(SB), NOSPLIT, $0-8
2222
MOVL $0, CX
2323
XGETBV
2424
MOVL AX, eax+0(FP)

cpu/cpu_gccgo_x86.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,3 @@ func xgetbv() (eax, edx uint32) {
2323
gccgoXgetbv(&a, &d)
2424
return a, d
2525
}
26-
27-
// gccgo doesn't build on Darwin, per:
28-
// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76
29-
func darwinSupportsAVX512() bool {
30-
return false
31-
}

cpu/cpu_other_x86.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2024 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 386 || amd64p32 || (amd64 && (!darwin || !gc))
6+
7+
package cpu
8+
9+
func darwinSupportsAVX512() bool {
10+
panic("only implemented for gc && amd64 && darwin")
11+
}

cpu/cpu_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,40 @@ func TestAVX512HasAVX2AndAVX(t *testing.T) {
4141
}
4242
}
4343

44+
func TestAVX512BF16HasAVX512(t *testing.T) {
45+
if runtime.GOARCH == "amd64" {
46+
if cpu.X86.HasAVX512BF16 && !cpu.X86.HasAVX512 {
47+
t.Fatal("HasAVX512 expected true, got false")
48+
}
49+
}
50+
}
51+
52+
func TestAVXVNNIHasAVX(t *testing.T) {
53+
if cpu.X86.HasAVXVNNI && !cpu.X86.HasAVX {
54+
t.Fatal("HasAVX expected true, got false")
55+
}
56+
}
57+
58+
func TestAVXIFMAHasAVXVNNIAndAVX(t *testing.T) {
59+
if cpu.X86.HasAVXIFMA && !cpu.X86.HasAVX {
60+
t.Fatal("HasAVX expected true, got false")
61+
}
62+
63+
if cpu.X86.HasAVXIFMA && !cpu.X86.HasAVXVNNI {
64+
t.Fatal("HasAVXVNNI expected true, got false")
65+
}
66+
}
67+
68+
func TestAVXVNNIInt8HasAVXVNNIAndAVX(t *testing.T) {
69+
if cpu.X86.HasAVXVNNIInt8 && !cpu.X86.HasAVXVNNI {
70+
t.Fatal("HasAVXVNNI expected true, got false")
71+
}
72+
73+
if cpu.X86.HasAVXVNNIInt8 && !cpu.X86.HasAVX {
74+
t.Fatal("HasAVX expected true, got false")
75+
}
76+
}
77+
4478
func TestARM64minimalFeatures(t *testing.T) {
4579
if runtime.GOARCH != "arm64" || runtime.GOOS == "ios" {
4680
return

cpu/cpu_x86.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func initOptions() {
5353
{Name: "sse41", Feature: &X86.HasSSE41},
5454
{Name: "sse42", Feature: &X86.HasSSE42},
5555
{Name: "ssse3", Feature: &X86.HasSSSE3},
56+
{Name: "avxifma", Feature: &X86.HasAVXIFMA},
57+
{Name: "avxvnni", Feature: &X86.HasAVXVNNI},
58+
{Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8},
5659

5760
// These capabilities should always be enabled on amd64:
5861
{Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
@@ -92,10 +95,8 @@ func archInit() {
9295
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
9396

9497
if runtime.GOOS == "darwin" {
95-
// Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers.
96-
// Since users can't rely on mask register contents, let's not advertise AVX-512 support.
97-
// See issue 49233.
98-
osSupportsAVX512 = false
98+
// Darwin requires special AVX512 checks, see cpu_darwin_x86.go
99+
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
99100
} else {
100101
// Check if OPMASK and ZMM registers have OS support.
101102
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
@@ -108,7 +109,7 @@ func archInit() {
108109
return
109110
}
110111

111-
_, ebx7, ecx7, edx7 := cpuid(7, 0)
112+
eax7, ebx7, ecx7, edx7 := cpuid(7, 0)
112113
X86.HasBMI1 = isSet(3, ebx7)
113114
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
114115
X86.HasBMI2 = isSet(8, ebx7)
@@ -136,14 +137,24 @@ func archInit() {
136137
X86.HasAVX512VAES = isSet(9, ecx7)
137138
X86.HasAVX512VBMI2 = isSet(6, ecx7)
138139
X86.HasAVX512BITALG = isSet(12, ecx7)
139-
140-
eax71, _, _, _ := cpuid(7, 1)
141-
X86.HasAVX512BF16 = isSet(5, eax71)
142140
}
143141

144142
X86.HasAMXTile = isSet(24, edx7)
145143
X86.HasAMXInt8 = isSet(25, edx7)
146144
X86.HasAMXBF16 = isSet(22, edx7)
145+
146+
// These features depend on the second level of extended features.
147+
if eax7 >= 1 {
148+
eax71, _, _, edx71 := cpuid(7, 1)
149+
if X86.HasAVX512 {
150+
X86.HasAVX512BF16 = isSet(5, eax71)
151+
}
152+
if X86.HasAVX {
153+
X86.HasAVXIFMA = isSet(23, eax71)
154+
X86.HasAVXVNNI = isSet(4, eax71)
155+
X86.HasAVXVNNIInt8 = isSet(4, edx71)
156+
}
157+
}
147158
}
148159

149160
func isSet(bitpos uint, value uint32) bool {

0 commit comments

Comments
 (0)
0