4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
8 * For conditions of distribution and use, see copyright notice in zlib.h
13 int x86_cpu_enable_simd
= 0;
18 pthread_once_t cpu_check_inited_once
= PTHREAD_ONCE_INIT
;
19 static void _x86_check_features(void);
21 void x86_check_features(void)
23 pthread_once(&cpu_check_inited_once
, _x86_check_features
);
26 static void _x86_check_features(void)
29 int x86_cpu_has_sse42
;
30 int x86_cpu_has_pclmulqdq
;
31 unsigned eax
, ebx
, ecx
, edx
;
35 __asm__
__volatile__ (
39 : "+a" (eax
), "=S" (ebx
), "=c" (ecx
), "=d" (edx
)
42 __asm__
__volatile__ (
44 : "+a" (eax
), "=b" (ebx
), "=c" (ecx
), "=d" (edx
)
46 #endif /* (__i386__) */
48 x86_cpu_has_sse2
= edx
& 0x4000000;
49 x86_cpu_has_sse42
= ecx
& 0x100000;
50 x86_cpu_has_pclmulqdq
= ecx
& 0x2;
52 x86_cpu_enable_simd
= x86_cpu_has_sse2
&&
54 x86_cpu_has_pclmulqdq
;
61 static volatile int32_t once_control
= 0;
62 static void _x86_check_features(void);
63 static int fake_pthread_once(volatile int32_t *once_control
,
64 void (*init_routine
)(void));
66 void x86_check_features(void)
68 fake_pthread_once(&once_control
, _x86_check_features
);
71 /* Copied from "perftools_pthread_once" in tcmalloc */
72 static int fake_pthread_once(volatile int32_t *once_control
,
73 void (*init_routine
)(void)) {
74 // Try for a fast path first. Note: this should be an acquire semantics read
75 // It is on x86 and x64, where Windows runs.
76 if (*once_control
!= 1) {
78 switch (InterlockedCompareExchange(once_control
, 2, 0)) {
81 InterlockedExchange(once_control
, 1);
84 // The initializer has already been executed
87 // The initializer is being processed by another thread
95 static void _x86_check_features(void)
98 int x86_cpu_has_sse42
;
99 int x86_cpu_has_pclmulqdq
;
104 x86_cpu_has_sse2
= regs
[3] & 0x4000000;
105 x86_cpu_has_sse42
= regs
[2] & 0x100000;
106 x86_cpu_has_pclmulqdq
= regs
[2] & 0x2;
108 x86_cpu_enable_simd
= x86_cpu_has_sse2
&&
110 x86_cpu_has_pclmulqdq
;
112 #endif /* _MSC_VER */