1 #include <stdlib.h>
2 #include <cpuid.h>
3 
4 /* Check if the OS supports executing AVX512FP16 instructions.  */
5 
6 #define XCR_XFEATURE_ENABLED_MASK	0x0
7 
8 #define XSTATE_FP	0x1
9 #define XSTATE_SSE	0x2
10 #define XSTATE_YMM	0x4
11 #define XSTATE_OPMASK	0x20
12 #define XSTATE_ZMM	0x40
13 #define XSTATE_HI_ZMM	0x80
14 
15 static int
check_osxsave(void)16 check_osxsave (void)
17 {
18   unsigned int eax, ebx, ecx, edx;
19 
20   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
21     return 0;
22 
23   return (ecx & bit_OSXSAVE) != 0;
24 }
25 
26 static int
avx512fp16_os_support(void)27 avx512fp16_os_support (void)
28 {
29   unsigned int eax, edx;
30   unsigned int ecx = XCR_XFEATURE_ENABLED_MASK;
31   unsigned int mask = XSTATE_MASK;
32 
33   if (!check_osxsave ())
34     return 0;
35 
36   __asm__ ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (ecx));
37 
38   return ((eax & mask) == mask);
39 }
40 
41 static void do_test (void);
42 
43 int
main()44 main ()
45 {
46   unsigned int eax, ebx, ecx, edx;
47 
48   if (!avx512fp16_os_support ())
49     return 0;
50 
51   if (__get_cpuid_max (0, NULL) < 7)
52     return 0;
53 
54   __cpuid_count (7, 0, eax, ebx, ecx, edx);
55 
56     /* Run AVX512FP16 test only if host has ISA support.  */
57   if (((ebx & (bit_AVX512F | bit_AVX512BW))
58        == (bit_AVX512F | bit_AVX512BW))
59       && (edx & bit_AVX512FP16)
60       && AVX512VL (ebx))
61     {
62       do_test ();
63 #ifdef DEBUG
64       printf ("PASSED\n");
65 #endif
66       return 0;
67     }
68 
69 #ifdef DEBUG
70   printf ("SKIPPED\n");
71 #endif
72 
73   return 0;
74 }
75