diff options
Diffstat (limited to 'internal/cpu/cpu_amd64.go')
| -rw-r--r-- | internal/cpu/cpu_amd64.go | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/internal/cpu/cpu_amd64.go b/internal/cpu/cpu_amd64.go new file mode 100644 index 00000000..7fe59633 --- /dev/null +++ b/internal/cpu/cpu_amd64.go @@ -0,0 +1,34 @@ +//go:build amd64 && !purego + +package cpu + +const ( + cpuidOSXSAVE = 1 << 27 + cpuidAVX = 1 << 28 + cpuidAVX2 = 1 << 5 +) + +// cpuid is implemented in cpu_amd64.s. +func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) + +// xgetbv with ecx = 0 is implemented in cpu_amd64.s. +func xgetbv() (eax, edx uint32) + +func init() { //nolint:gochecknoinits + maxID, _, _, _ := cpuid(0, 0) + if maxID < 7 { + return + } + + _, _, ecx1, _ := cpuid(1, 0) + + osSupportsAVX := false + + if ecx1&cpuidOSXSAVE != 0 { + eax, _ := xgetbv() + osSupportsAVX = eax&(1<<1) != 0 && eax&(1<<2) != 0 + } + + _, ebx7, _, _ := cpuid(7, 0) + X86.HasAVX2 = osSupportsAVX && ecx1&cpuidAVX != 0 && ebx7&cpuidAVX2 != 0 +} |
