5 #ifndef CRYPTOPP_IMPORTS
11 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
16 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
17 #include <emmintrin.h>
20 NAMESPACE_BEGIN(CryptoPP)
22 #ifdef CRYPTOPP_CPUID_AVAILABLE
24 #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64
26 bool CpuId(word32 input, word32 *output)
28 __cpuid((
int *)output, input);
34 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
36 typedef void (*SigHandler)(int);
38 static jmp_buf s_jmpNoCPUID;
39 static void SigIllHandlerCPUID(
int)
41 longjmp(s_jmpNoCPUID, 1);
44 static jmp_buf s_jmpNoSSE2;
45 static void SigIllHandlerSSE2(
int)
47 longjmp(s_jmpNoSSE2, 1);
52 bool CpuId(word32 input, word32 *output)
54 #ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
74 SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
75 if (oldHandler == SIG_ERR)
79 if (setjmp(s_jmpNoCPUID))
87 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
89 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
91 :
"=a" (output[0]),
"=D" (output[1]),
"=c" (output[2]),
"=d" (output[3])
96 signal(SIGILL, oldHandler);
103 static bool TrySSE2()
105 #if CRYPTOPP_BOOL_X64
107 #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
110 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
112 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
113 __m128i x = _mm_setzero_si128();
114 return _mm_cvtsi128_si32(x) == 0;
123 SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
124 if (oldHandler == SIG_ERR)
128 if (setjmp(s_jmpNoSSE2))
132 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
133 __asm __volatile (
"por %xmm0, %xmm0");
134 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
135 __m128i x = _mm_setzero_si128();
136 result = _mm_cvtsi128_si32(x) == 0;
140 signal(SIGILL, oldHandler);
145 bool g_x86DetectionDone =
false;
146 bool g_hasISSE =
false, g_hasSSE2 =
false, g_hasSSSE3 =
false, g_hasMMX =
false, g_hasAESNI =
false, g_hasCLMUL =
false, g_isP4 =
false;
147 word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
149 void DetectX86Features()
151 word32 cpuid[4], cpuid1[4];
152 if (!CpuId(0, cpuid))
154 if (!CpuId(1, cpuid1))
157 g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
158 if ((cpuid1[3] & (1 << 26)) != 0)
159 g_hasSSE2 = TrySSE2();
160 g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
161 g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25));
162 g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1));
164 if ((cpuid1[3] & (1 << 25)) != 0)
169 CpuId(0x080000000, cpuid2);
170 if (cpuid2[0] >= 0x080000001)
172 CpuId(0x080000001, cpuid2);
173 g_hasISSE = (cpuid2[3] & (1 << 22)) != 0;
177 std::swap(cpuid[2], cpuid[3]);
178 if (memcmp(cpuid+1,
"GenuineIntel", 12) == 0)
180 g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
181 g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
183 else if (memcmp(cpuid+1,
"AuthenticAMD", 12) == 0)
185 CpuId(0x80000005, cpuid);
186 g_cacheLineSize = GETBYTE(cpuid[2], 0);
189 if (!g_cacheLineSize)
190 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
192 g_x86DetectionDone =
true;