6 #ifndef EXCEPTION_EXECUTE_HANDLER 7 # define EXCEPTION_EXECUTE_HANDLER 1 10 #ifndef CRYPTOPP_IMPORTS 16 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 21 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 22 #include <emmintrin.h> 27 #ifdef CRYPTOPP_CPUID_AVAILABLE 29 #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 31 bool CpuId(word32 input, word32 output[4])
33 __cpuid((
int *)output, input);
39 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 41 typedef void (*SigHandler)(int);
43 static jmp_buf s_jmpNoCPUID;
44 static void SigIllHandlerCPUID(
int)
46 longjmp(s_jmpNoCPUID, 1);
49 static jmp_buf s_jmpNoSSE2;
50 static void SigIllHandlerSSE2(
int)
52 longjmp(s_jmpNoSSE2, 1);
57 bool CpuId(word32 input, word32 output[4])
59 #if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 75 __except (EXCEPTION_EXECUTE_HANDLER)
89 volatile bool result =
true;
91 SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
92 if (oldHandler == SIG_ERR)
95 if (setjmp(s_jmpNoCPUID))
103 # if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 104 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 106 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" 108 :
"=a" (output[0]),
"=D" (output[1]),
"=c" (output[2]),
"=d" (output[3])
109 :
"a" (input),
"c" (0)
113 signal(SIGILL, oldHandler);
120 static bool TrySSE2()
122 #if CRYPTOPP_BOOL_X64 124 #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 127 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 129 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 130 __m128i x = _mm_setzero_si128();
131 return _mm_cvtsi128_si32(x) == 0;
135 __except (EXCEPTION_EXECUTE_HANDLER)
144 volatile bool result =
true;
146 SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
147 if (oldHandler == SIG_ERR)
150 if (setjmp(s_jmpNoSSE2))
154 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 155 __asm __volatile (
"por %xmm0, %xmm0");
156 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 157 __m128i x = _mm_setzero_si128();
158 result = _mm_cvtsi128_si32(x) == 0;
162 signal(SIGILL, oldHandler);
167 bool g_x86DetectionDone =
false;
168 bool g_hasMMX =
false, g_hasISSE =
false, g_hasSSE2 =
false, g_hasSSSE3 =
false, g_hasAESNI =
false, g_hasCLMUL =
false, g_isP4 =
false, g_hasRDRAND =
false, g_hasRDSEED =
false;
169 word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
172 #define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) 173 #define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) 175 static inline bool IsIntel(
const word32 output[4])
178 return (output[1] == 0x756e6547) &&
179 (output[2] == 0x6c65746e) &&
180 (output[3] == 0x49656e69);
183 static inline bool IsAMD(
const word32 output[4])
186 return (output[1] == 0x68747541) &&
187 (output[2] == 0x69746E65) &&
188 (output[3] == 0x444D4163);
191 #if HAVE_GCC_CONSTRUCTOR1 192 void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features()
193 #elif HAVE_GCC_CONSTRUCTOR0 194 void __attribute__ ((constructor)) DetectX86Features()
196 void DetectX86Features()
199 word32 cpuid[4], cpuid1[4];
200 if (!CpuId(0, cpuid))
202 if (!CpuId(1, cpuid1))
205 g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
206 if ((cpuid1[3] & (1 << 26)) != 0)
207 g_hasSSE2 = TrySSE2();
208 g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
209 g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25));
210 g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1));
212 if ((cpuid1[3] & (1 << 25)) != 0)
217 CpuId(0x080000000, cpuid2);
218 if (cpuid2[0] >= 0x080000001)
220 CpuId(0x080000001, cpuid2);
221 g_hasISSE = (cpuid2[3] & (1 << 22)) != 0;
225 static const unsigned int RDRAND_FLAG = (1 << 30);
226 static const unsigned int RDSEED_FLAG = (1 << 18);
229 g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
230 g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
231 g_hasRDRAND = !!(cpuid1[2] & RDRAND_FLAG);
236 if (CpuId(7, cpuid3))
237 g_hasRDSEED = !!(cpuid3[1] & RDSEED_FLAG);
240 else if (IsAMD(cpuid))
242 CpuId(0x80000005, cpuid);
243 g_cacheLineSize = GETBYTE(cpuid[2], 0);
244 g_hasRDRAND = !!(cpuid[2] & RDRAND_FLAG);
247 if (!g_cacheLineSize)
248 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
250 *((
volatile bool*)&g_x86DetectionDone) =
true;
Utility functions for the Crypto++ library.
Library configuration file.
Classes, functions, intrinsics and features for X86, X32 nd X64 assembly.
Crypto++ library namespace.