1 /*
2 * x86 feature check
3 *
4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
5 * Author:
6 * Jim Kukunas
7 *
8 * For conditions of distribution and use, see copyright notice in zlib.h
9 */
10
11 #include "x86.h"
12 #include "zutil.h"
13
14 int ZLIB_INTERNAL x86_cpu_enable_ssse3 = 0;
15 int ZLIB_INTERNAL x86_cpu_enable_simd = 0;
16
17 #ifndef _MSC_VER
18 #include <pthread.h>
19
20 pthread_once_t cpu_check_inited_once = PTHREAD_ONCE_INIT;
21 static void _x86_check_features(void);
22
x86_check_features(void)23 void x86_check_features(void)
24 {
25 pthread_once(&cpu_check_inited_once, _x86_check_features);
26 }
27
_x86_check_features(void)28 static void _x86_check_features(void)
29 {
30 int x86_cpu_has_sse2;
31 int x86_cpu_has_ssse3;
32 int x86_cpu_has_sse42;
33 int x86_cpu_has_pclmulqdq;
34 unsigned eax, ebx, ecx, edx;
35
36 eax = 1;
37 #ifdef __i386__
38 __asm__ __volatile__ (
39 "xchg %%ebx, %1\n\t"
40 "cpuid\n\t"
41 "xchg %1, %%ebx\n\t"
42 : "+a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx)
43 );
44 #else
45 __asm__ __volatile__ (
46 "cpuid\n\t"
47 : "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
48 );
49 #endif /* (__i386__) */
50
51 x86_cpu_has_sse2 = edx & 0x4000000;
52 x86_cpu_has_ssse3 = ecx & 0x000200;
53 x86_cpu_has_sse42 = ecx & 0x100000;
54 x86_cpu_has_pclmulqdq = ecx & 0x2;
55
56 x86_cpu_enable_ssse3 = x86_cpu_has_ssse3;
57
58 x86_cpu_enable_simd = x86_cpu_has_sse2 &&
59 x86_cpu_has_sse42 &&
60 x86_cpu_has_pclmulqdq;
61 }
62 #else
63 #include <intrin.h>
64 #include <windows.h>
65
66 static BOOL CALLBACK _x86_check_features(PINIT_ONCE once,
67 PVOID param,
68 PVOID *context);
69 static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT;
70
x86_check_features(void)71 void x86_check_features(void)
72 {
73 InitOnceExecuteOnce(&cpu_check_inited_once, _x86_check_features,
74 NULL, NULL);
75 }
76
_x86_check_features(PINIT_ONCE once,PVOID param,PVOID * context)77 static BOOL CALLBACK _x86_check_features(PINIT_ONCE once,
78 PVOID param,
79 PVOID *context)
80 {
81 int x86_cpu_has_sse2;
82 int x86_cpu_has_ssse3;
83 int x86_cpu_has_sse42;
84 int x86_cpu_has_pclmulqdq;
85 int regs[4];
86
87 __cpuid(regs, 1);
88
89 x86_cpu_has_sse2 = regs[3] & 0x4000000;
90 x86_cpu_has_ssse3 = regs[2] & 0x000200;
91 x86_cpu_has_sse42 = regs[2] & 0x100000;
92 x86_cpu_has_pclmulqdq = regs[2] & 0x2;
93
94 x86_cpu_enable_ssse3 = x86_cpu_has_ssse3;
95
96 x86_cpu_enable_simd = x86_cpu_has_sse2 &&
97 x86_cpu_has_sse42 &&
98 x86_cpu_has_pclmulqdq;
99 return TRUE;
100 }
101 #endif /* _MSC_VER */
102