cpuid_AVX = 1 << 28
// ebx bits
- cpuid_BMI1 = 1 << 3
- cpuid_AVX2 = 1 << 5
- cpuid_BMI2 = 1 << 8
- cpuid_ERMS = 1 << 9
- cpuid_ADX = 1 << 19
- cpuid_SHA = 1 << 29
+ cpuid_BMI1 = 1 << 3
+ cpuid_AVX2 = 1 << 5
+ cpuid_BMI2 = 1 << 8
+ cpuid_ERMS = 1 << 9
+ cpuid_AVX512F = 1 << 16
+ cpuid_ADX = 1 << 19
+ cpuid_SHA = 1 << 29
+ cpuid_AVX512BW = 1 << 30
+ cpuid_AVX512VL = 1 << 31
// edx bits for CPUID 0x80000001
cpuid_RDTSCP = 1 << 27
option{Name: "bmi2", Feature: &X86.HasBMI2},
option{Name: "fma", Feature: &X86.HasFMA})
}
+ if level < 4 {
+ // These options are required at level 4. At lower levels
+ // they can be turned off.
+ options = append(options,
+ option{Name: "avx512f", Feature: &X86.HasAVX512F},
+ option{Name: "avx512bw", Feature: &X86.HasAVX512BW},
+ option{Name: "avx512vl", Feature: &X86.HasAVX512VL},
+ )
+ }
maxID, _, _, _ := cpuid(0, 0)
X86.HasFMA = isSet(ecx1, cpuid_FMA) && X86.HasOSXSAVE
osSupportsAVX := false
+ osSupportsAVX512 := false
// For XGETBV, OSXSAVE bit is required and sufficient.
if X86.HasOSXSAVE {
eax, _ := xgetbv()
// Check if XMM and YMM registers have OS support.
osSupportsAVX = isSet(eax, 1<<1) && isSet(eax, 1<<2)
+
+ // AVX512 detection does not work on Darwin,
+ // see https://github.com/golang/go/issues/49233
+ //
+ // Check if opmask, ZMMhi256 and Hi16_ZMM have OS support.
+ osSupportsAVX512 = osSupportsAVX && isSet(eax, 1<<5) && isSet(eax, 1<<6) && isSet(eax, 1<<7)
}
X86.HasAVX = isSet(ecx1, cpuid_AVX) && osSupportsAVX
X86.HasADX = isSet(ebx7, cpuid_ADX)
X86.HasSHA = isSet(ebx7, cpuid_SHA)
+ X86.HasAVX512F = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512
+ if X86.HasAVX512F {
+ X86.HasAVX512BW = isSet(ebx7, cpuid_AVX512BW)
+ X86.HasAVX512VL = isSet(ebx7, cpuid_AVX512VL)
+ }
+
var maxExtendedInformation uint32
maxExtendedInformation, _, _, _ = cpuid(0x80000000, 0)
}
}
+func TestX86ifAVX512FhasAVX2(t *testing.T) {
+ if X86.HasAVX512F && !X86.HasAVX2 {
+ t.Fatalf("HasAVX2 expected true when HasAVX512F is true, got false")
+ }
+}
+
+func TestX86ifAVX512BWhasAVX512F(t *testing.T) {
+ if X86.HasAVX512BW && !X86.HasAVX512F {
+ t.Fatalf("HasAVX512F expected true when HasAVX512BW is true, got false")
+ }
+}
+
+func TestX86ifAVX512VLhasAVX512F(t *testing.T) {
+ if X86.HasAVX512VL && !X86.HasAVX512F {
+ t.Fatalf("HasAVX512F expected true when HasAVX512VL is true, got false")
+ }
+}
+
func TestDisableSSE3(t *testing.T) {
if GetGOAMD64level() > 1 {
t.Skip("skipping test: can't run on GOAMD64>v1 machines")
#define commpage64_base_address 0x00007fffffe00000
#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
#define commpage64_version (commpage64_base_address+0x01E)
-#define hasAVX512F 0x0000004000000000
-#define hasAVX512CD 0x0000008000000000
-#define hasAVX512DQ 0x0000010000000000
-#define hasAVX512BW 0x0000020000000000
-#define hasAVX512VL 0x0000100000000000
-#define NEED_DARWIN_SUPPORT (hasAVX512F | hasAVX512DQ | hasAVX512CD | hasAVX512BW | hasAVX512VL)
+#define AVX512F 0x0000004000000000
+#define AVX512CD 0x0000008000000000
+#define AVX512DQ 0x0000010000000000
+#define AVX512BW 0x0000020000000000
+#define AVX512VL 0x0000100000000000
+#define NEED_DARWIN_SUPPORT (AVX512F | AVX512DQ | AVX512CD | AVX512BW | AVX512VL)
#else
#define NEED_OS_SUPPORT_AX V4_OS_SUPPORT_AX
#endif