Crypto++  5.6.3
Free C++ class library of cryptographic schemes
cpu.h
Go to the documentation of this file.
1 // cpu.h - written and placed in the public domain by Wei Dai
2 
3 //! \file cpu.h
4 //! \brief Functions for CPU features and intrinsics
5 //! \details The functions are used in X86/X32/X64 and NEON code paths
6 
7 #ifndef CRYPTOPP_CPU_H
8 #define CRYPTOPP_CPU_H
9 
10 #include "config.h"
11 
12 #if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
13 # if defined(_MSC_VER) || defined(__BORLANDC__)
14 # define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
15 # else
16 # define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
17 # endif
18 # if CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE
19 # include <arm_neon.h>
20 # endif
21 # if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE)
22 # include <stdint.h>
23 # if (defined(__ARM_ACLE) || defined(__GNUC__)) && !defined(__APPLE__)
24 # include <arm_acle.h>
25 # endif
26 # endif
27 #endif // ARM-32 or ARM-64
28 
29 #ifdef CRYPTOPP_GENERATE_X64_MASM
30 
31 #define CRYPTOPP_X86_ASM_AVAILABLE
32 #define CRYPTOPP_BOOL_X64 1
33 #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1
34 #define NAMESPACE_END
35 
36 #else
37 
38 # if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
39 # include <emmintrin.h>
40 # endif
41 
42 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
43 
44 // GCC 5.3/i686 fails to declare __m128 in the headers we use when compiling with -std=c++11 or -std=c++14.
45 // Consequently, our _mm_shuffle_epi8, _mm_extract_epi32, etc fails to compile.
46 #if defined(__has_include)
47 # if __has_include(<xmmintrin.h>)
48 # include <xmmintrin.h>
49 # endif
50 #endif
51 
52 // PUSHFB needs Clang 3.3 and Apple Clang 5.0.
53 #if !defined(__GNUC__) || defined(__SSSE3__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000)
54 #include <tmmintrin.h>
55 #else
56 NAMESPACE_BEGIN(CryptoPP)
57 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
58 _mm_shuffle_epi8 (__m128i a, __m128i b)
59 {
60  asm ("pshufb %1, %0" : "+x"(a) : "xm"(b));
61  return a;
62 }
63 NAMESPACE_END
64 #endif // tmmintrin.h
65 
66 // PEXTRD needs Clang 3.3 and Apple Clang 5.0.
67 #if !defined(__GNUC__) || defined(__SSE4_1__)|| defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50000)
68 #include <smmintrin.h>
69 #else
70 NAMESPACE_BEGIN(CryptoPP)
71 __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
72 _mm_extract_epi32 (__m128i a, const int i)
73 {
74  int r;
75  asm ("pextrd %2, %1, %0" : "=rm"(r) : "x"(a), "i"(i));
76  return r;
77 }
78 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
79 _mm_insert_epi32 (__m128i a, int b, const int i)
80 {
81  asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i));
82  return a;
83 }
84 NAMESPACE_END
85 #endif // smmintrin.h
86 
87 // AES needs Clang 2.8 and Apple Clang 4.6. PCLMUL needs Clang 3.4 and Apple Clang 6.0
88 #if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 60000)
89 #include <wmmintrin.h>
90 #else
91 NAMESPACE_BEGIN(CryptoPP)
92 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
93 _mm_clmulepi64_si128 (__m128i a, __m128i b, const int i)
94 {
95  asm ("pclmulqdq %2, %1, %0" : "+x"(a) : "xm"(b), "i"(i));
96  return a;
97 }
98 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
99 _mm_aeskeygenassist_si128 (__m128i a, const int i)
100 {
101  __m128i r;
102  asm ("aeskeygenassist %2, %1, %0" : "=x"(r) : "xm"(a), "i"(i));
103  return r;
104 }
105 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
106 _mm_aesimc_si128 (__m128i a)
107 {
108  __m128i r;
109  asm ("aesimc %1, %0" : "=x"(r) : "xm"(a));
110  return r;
111 }
112 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
113 _mm_aesenc_si128 (__m128i a, __m128i b)
114 {
115  asm ("aesenc %1, %0" : "+x"(a) : "xm"(b));
116  return a;
117 }
118 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
119 _mm_aesenclast_si128 (__m128i a, __m128i b)
120 {
121  asm ("aesenclast %1, %0" : "+x"(a) : "xm"(b));
122  return a;
123 }
124 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
125 _mm_aesdec_si128 (__m128i a, __m128i b)
126 {
127  asm ("aesdec %1, %0" : "+x"(a) : "xm"(b));
128  return a;
129 }
130 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
131 _mm_aesdeclast_si128 (__m128i a, __m128i b)
132 {
133  asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b));
134  return a;
135 }
136 NAMESPACE_END
137 #endif // wmmintrin.h
138 #endif // CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
139 
140 NAMESPACE_BEGIN(CryptoPP)
141 
142 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING
143 
144 #define CRYPTOPP_CPUID_AVAILABLE
145 
146 // Hide from Doxygen
147 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
148 // These should not be used directly
149 extern CRYPTOPP_DLL bool g_x86DetectionDone;
150 extern CRYPTOPP_DLL bool g_hasMMX;
151 extern CRYPTOPP_DLL bool g_hasISSE;
152 extern CRYPTOPP_DLL bool g_hasSSE2;
153 extern CRYPTOPP_DLL bool g_hasSSSE3;
154 extern CRYPTOPP_DLL bool g_hasSSE4;
155 extern CRYPTOPP_DLL bool g_hasAESNI;
156 extern CRYPTOPP_DLL bool g_hasCLMUL;
157 extern CRYPTOPP_DLL bool g_isP4;
158 extern CRYPTOPP_DLL bool g_hasRDRAND;
159 extern CRYPTOPP_DLL bool g_hasRDSEED;
160 extern CRYPTOPP_DLL bool g_hasPadlockRNG;
161 extern CRYPTOPP_DLL bool g_hasPadlockACE;
162 extern CRYPTOPP_DLL bool g_hasPadlockACE2;
163 extern CRYPTOPP_DLL bool g_hasPadlockPHE;
164 extern CRYPTOPP_DLL bool g_hasPadlockPMM;
165 extern CRYPTOPP_DLL word32 g_cacheLineSize;
166 
167 CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
168 CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 output[4]);
169 #endif // CRYPTOPP_DOXYGEN_PROCESSING
170 
171 //! \brief Determines MMX availability
172 //! \returns true if MMX is determined to be available, false otherwise
173 //! \details MMX, SSE and SSE2 are core processor features for x86_64, and
174 //! the function always returns true for the platform.
175 inline bool HasMMX()
176 {
177 #if CRYPTOPP_BOOL_X64
178  return true;
179 #else
180  if (!g_x86DetectionDone)
181  DetectX86Features();
182  return g_hasMMX;
183 #endif
184 }
185 
186 //! \brief Determines SSE availability
187 //! \returns true if SSE is determined to be available, false otherwise
188 //! \details MMX, SSE and SSE2 are core processor features for x86_64, and
189 //! the function always returns true for the platform.
190 inline bool HasISSE()
191 {
192 #if CRYPTOPP_BOOL_X64
193  return true;
194 #else
195  if (!g_x86DetectionDone)
196  DetectX86Features();
197  return g_hasISSE;
198 #endif
199 }
200 
201 //! \brief Determines SSE2 availability
202 //! \returns true if SSE2 is determined to be available, false otherwise
203 //! \details MMX, SSE and SSE2 are core processor features for x86_64, and
204 //! the function always returns true for the platform.
205 inline bool HasSSE2()
206 {
207 #if CRYPTOPP_BOOL_X64
208  return true;
209 #else
210  if (!g_x86DetectionDone)
211  DetectX86Features();
212  return g_hasSSE2;
213 #endif
214 }
215 
216 //! \brief Determines SSSE3 availability
217 //! \returns true if SSSE3 is determined to be available, false otherwise
218 //! \details HasSSSE3() is a runtime check performed using CPUID
219 //! \note Some Clang compilers incorrectly omit SSSE3 even though its native to the processor.
220 inline bool HasSSSE3()
221 {
222  if (!g_x86DetectionDone)
223  DetectX86Features();
224  return g_hasSSSE3;
225 }
226 
227 //! \brief Determines SSE4 availability
228 //! \returns true if SSE4.1 and SSE4.2 are determined to be available, false otherwise
229 //! \details HasSSE4() is a runtime check performed using CPUID which requires both SSE4.1 and SSE4.2
230 inline bool HasSSE4()
231 {
232  if (!g_x86DetectionDone)
233  DetectX86Features();
234  return g_hasSSE4;
235 }
236 
237 //! \brief Determines AES-NI availability
238 //! \returns true if AES-NI is determined to be available, false otherwise
239 //! \details HasAESNI() is a runtime check performed using CPUID
240 inline bool HasAESNI()
241 {
242  if (!g_x86DetectionDone)
243  DetectX86Features();
244  return g_hasAESNI;
245 }
246 
247 //! \brief Determines Carryless Multiply availability
248 //! \returns true if pclmulqdq is determined to be available, false otherwise
249 //! \details HasCLMUL() is a runtime check performed using CPUID
250 inline bool HasCLMUL()
251 {
252  if (!g_x86DetectionDone)
253  DetectX86Features();
254  return g_hasCLMUL;
255 }
256 
257 //! \brief Determines if the CPU is an Intel P4
258 //! \returns true if the CPU is a P4, false otherwise
259 //! \details IsP4() is a runtime check performed using CPUID
260 inline bool IsP4()
261 {
262  if (!g_x86DetectionDone)
263  DetectX86Features();
264  return g_isP4;
265 }
266 
267 //! \brief Determines RDRAND availability
268 //! \returns true if RDRAND is determined to be available, false otherwise
269 //! \details HasRDRAND() is a runtime check performed using CPUID
270 inline bool HasRDRAND()
271 {
272  if (!g_x86DetectionDone)
273  DetectX86Features();
274  return g_hasRDRAND;
275 }
276 
277 //! \brief Determines RDSEED availability
278 //! \returns true if RDSEED is determined to be available, false otherwise
279 //! \details HasRDSEED() is a runtime check performed using CPUID
280 inline bool HasRDSEED()
281 {
282  if (!g_x86DetectionDone)
283  DetectX86Features();
284  return g_hasRDSEED;
285 }
286 
287 //! \brief Determines Padlock RNG availability
288 //! \returns true if VIA Padlock RNG is determined to be available, false otherwise
289 //! \details HasPadlockRNG() is a runtime check performed using CPUID
290 inline bool HasPadlockRNG()
291 {
292  if (!g_x86DetectionDone)
293  DetectX86Features();
294  return g_hasPadlockRNG;
295 }
296 
297 //! \brief Determines Padlock ACE availability
298 //! \returns true if VIA Padlock ACE is determined to be available, false otherwise
299 //! \details HasPadlockACE() is a runtime check performed using CPUID
300 inline bool HasPadlockACE()
301 {
302  if (!g_x86DetectionDone)
303  DetectX86Features();
304  return g_hasPadlockACE;
305 }
306 
307 //! \brief Determines Padlock ACE2 availability
308 //! \returns true if VIA Padlock ACE2 is determined to be available, false otherwise
309 //! \details HasPadlockACE2() is a runtime check performed using CPUID
310 inline bool HasPadlockACE2()
311 {
312  if (!g_x86DetectionDone)
313  DetectX86Features();
314  return g_hasPadlockACE2;
315 }
316 
317 //! \brief Determines Padlock PHE availability
318 //! \returns true if VIA Padlock PHE is determined to be available, false otherwise
319 //! \details HasPadlockPHE() is a runtime check performed using CPUID
320 inline bool HasPadlockPHE()
321 {
322  if (!g_x86DetectionDone)
323  DetectX86Features();
324  return g_hasPadlockPHE;
325 }
326 
327 //! \brief Determines Padlock PMM availability
328 //! \returns true if VIA Padlock PMM is determined to be available, false otherwise
329 //! \details HasPadlockPMM() is a runtime check performed using CPUID
330 inline bool HasPadlockPMM()
331 {
332  if (!g_x86DetectionDone)
333  DetectX86Features();
334  return g_hasPadlockPMM;
335 }
336 
337 //! \brief Provides the cache line size
338 //! \returns lower bound on the size of a cache line in bytes, if available
339 //! \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
340 //! is available. If the value is not available at runtime, then 32 is returned for a 32-bit
341 //! processor and 64 is returned for a 64-bit processor.
342 //! \details x86/x32/x64 uses CPUID to determine the value and its usually accurate. The ARM
343 //! processor equivalent is a privileged instruction, so a compile time value is returned.
344 inline int GetCacheLineSize()
345 {
346  if (!g_x86DetectionDone)
347  DetectX86Features();
348  return g_cacheLineSize;
349 }
350 
351 #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
352 
353 extern bool g_ArmDetectionDone;
354 extern bool g_hasNEON, g_hasCRC32, g_hasAES, g_hasSHA1, g_hasSHA2;
355 void CRYPTOPP_API DetectArmFeatures();
356 
357 //! \brief Determine if an ARM processor has Advanced SIMD available
358 //! \returns true if the hardware is capable of Advanced SIMD at runtime, false otherwise.
359 //! \details Advanced SIMD instructions are available under Aarch64 (ARM-64) and Aarch32 (ARM-32).
360 //! \details Runtime support requires compile time support. When compiling with GCC, you may
361 //! need to compile with <tt>-mfpu=neon</tt> (32-bit) or <tt>-march=armv8-a</tt>
362 //! (64-bit). Also see ARM's <tt>__ARM_NEON</tt> preprocessor macro.
363 inline bool HasNEON()
364 {
365  if (!g_ArmDetectionDone)
366  DetectArmFeatures();
367  return g_hasNEON;
368 }
369 
370 //! \brief Determine if an ARM processor has CRC32 available
371 //! \returns true if the hardware is capable of CRC32 at runtime, false otherwise.
372 //! \details CRC32 instructions provide access to the processor's CRC32 and CRC32-C intructions.
373 //! They are provided by ARM C Language Extensions 2.0 (ACLE 2.0) and available under Aarch64
374 //! (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an AArch32 execution environment).
375 //! \details Runtime support requires compile time support. When compiling with GCC, you may
376 //! need to compile with <tt>-march=armv8-a+crc</tt>; while Apple requires
377 //! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRC32</tt> preprocessor macro.
378 inline bool HasCRC32()
379 {
380  if (!g_ArmDetectionDone)
381  DetectArmFeatures();
382  return g_hasCRC32;
383 }
384 
385 //! \brief Determine if an ARM processor has AES available
386 //! \returns true if the hardware is capable of AES at runtime, false otherwise.
387 //! \details AES is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
388 //! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
389 //! AArch32 execution environment).
390 //! \details Runtime support requires compile time support. When compiling with GCC, you may
391 //! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
392 //! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
393 inline bool HasAES()
394 {
395  if (!g_ArmDetectionDone)
396  DetectArmFeatures();
397  return g_hasAES;
398 }
399 
400 //! \brief Determine if an ARM processor has SHA1 available
401 //! \returns true if the hardware is capable of SHA1 at runtime, false otherwise.
402 //! \details SHA1 is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
403 //! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
404 //! AArch32 execution environment).
405 //! \details Runtime support requires compile time support. When compiling with GCC, you may
406 //! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
407 //! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
408 inline bool HasSHA1()
409 {
410  if (!g_ArmDetectionDone)
411  DetectArmFeatures();
412  return g_hasSHA1;
413 }
414 
415 //! \brief Determine if an ARM processor has SHA2 available
416 //! \returns true if the hardware is capable of SHA2 at runtime, false otherwise.
417 //! \details SHA2 is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
418 //! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
419 //! AArch32 execution environment).
420 //! \details Runtime support requires compile time support. When compiling with GCC, you may
421 //! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
422 //! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
423 inline bool HasSHA2()
424 {
425  if (!g_ArmDetectionDone)
426  DetectArmFeatures();
427  return g_hasSHA2;
428 }
429 
430 //! \brief Provides the cache line size at runtime
431 //! \returns true if the hardware is capable of CRC32 at runtime, false otherwise.
432 //! \details GetCacheLineSize() provides is an estimate using CRYPTOPP_L1_CACHE_LINE_SIZE.
433 //! The runtime instructions to query the processor are privileged.
434 inline int GetCacheLineSize()
435 {
436  return CRYPTOPP_L1_CACHE_LINE_SIZE;
437 }
438 
439 #else
440 
441 inline int GetCacheLineSize()
442 {
443  return CRYPTOPP_L1_CACHE_LINE_SIZE;
444 }
445 
446 #endif // X86/X32/X64 and ARM
447 
448 #endif
449 
450 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
451 
452 #ifdef CRYPTOPP_GENERATE_X64_MASM
453  #define AS1(x) x*newline*
454  #define AS2(x, y) x, y*newline*
455  #define AS3(x, y, z) x, y, z*newline*
456  #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline*
457  #define ASL(x) label##x:*newline*
458  #define ASJ(x, y, z) x label##y*newline*
459  #define ASC(x, y) x label##y*newline*
460  #define AS_HEX(y) 0##y##h
461 #elif defined(_MSC_VER) || defined(__BORLANDC__)
462  #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
463  #define AS1(x) __asm {x}
464  #define AS2(x, y) __asm {x, y}
465  #define AS3(x, y, z) __asm {x, y, z}
466  #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)}
467  #define ASL(x) __asm {label##x:}
468  #define ASJ(x, y, z) __asm {x label##y}
469  #define ASC(x, y) __asm {x label##y}
470  #define CRYPTOPP_NAKED __declspec(naked)
471  #define AS_HEX(y) 0x##y
472 #else
473  #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
474 
475 #if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER)
476  #define NEW_LINE "\n"
477  #define INTEL_PREFIX ".intel_syntax;"
478  #define INTEL_NOPREFIX ".intel_syntax;"
479  #define ATT_PREFIX ".att_syntax;"
480  #define ATT_NOPREFIX ".att_syntax;"
481 #else
482  #define NEW_LINE
483  #define INTEL_PREFIX ".intel_syntax prefix;"
484  #define INTEL_NOPREFIX ".intel_syntax noprefix;"
485  #define ATT_PREFIX ".att_syntax prefix;"
486  #define ATT_NOPREFIX ".att_syntax noprefix;"
487 #endif
488 
489  // define these in two steps to allow arguments to be expanded
490  #define GNU_AS1(x) #x ";" NEW_LINE
491  #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE
492  #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE
493  #define GNU_ASL(x) "\n" #x ":" NEW_LINE
494  #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
495  #define AS1(x) GNU_AS1(x)
496  #define AS2(x, y) GNU_AS2(x, y)
497  #define AS3(x, y, z) GNU_AS3(x, y, z)
498  #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
499  #define ASL(x) GNU_ASL(x)
500  #define ASJ(x, y, z) GNU_ASJ(x, y, z)
501  #define ASC(x, y) #x " " #y ";"
502  #define CRYPTOPP_NAKED
503  #define AS_HEX(y) 0x##y
504 #endif
505 
506 #define IF0(y)
507 #define IF1(y) y
508 
509 // Should be confined to GCC, but its used to help manage Clang 3.4 compiler error.
510 // Also see LLVM Bug 24232, http://llvm.org/bugs/show_bug.cgi?id=24232 .
511 #ifndef INTEL_PREFIX
512  #define INTEL_PREFIX
513 #endif
514 #ifndef INTEL_NOPREFIX
515  #define INTEL_NOPREFIX
516 #endif
517 #ifndef ATT_PREFIX
518  #define ATT_PREFIX
519 #endif
520 #ifndef ATT_NOPREFIX
521  #define ATT_NOPREFIX
522 #endif
523 
524 #ifdef CRYPTOPP_GENERATE_X64_MASM
525 #define ASM_MOD(x, y) ((x) MOD (y))
526 #define XMMWORD_PTR XMMWORD PTR
527 #else
528 // GNU assembler doesn't seem to have mod operator
529 #define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
530 // GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM
531 #define XMMWORD_PTR
532 #endif
533 
534 #if CRYPTOPP_BOOL_X86
535  #define AS_REG_1 ecx
536  #define AS_REG_2 edx
537  #define AS_REG_3 esi
538  #define AS_REG_4 edi
539  #define AS_REG_5 eax
540  #define AS_REG_6 ebx
541  #define AS_REG_7 ebp
542  #define AS_REG_1d ecx
543  #define AS_REG_2d edx
544  #define AS_REG_3d esi
545  #define AS_REG_4d edi
546  #define AS_REG_5d eax
547  #define AS_REG_6d ebx
548  #define AS_REG_7d ebp
549  #define WORD_SZ 4
550  #define WORD_REG(x) e##x
551  #define WORD_PTR DWORD PTR
552  #define AS_PUSH_IF86(x) AS1(push e##x)
553  #define AS_POP_IF86(x) AS1(pop e##x)
554  #define AS_JCXZ jecxz
555 #elif CRYPTOPP_BOOL_X32
556  #define AS_REG_1 ecx
557  #define AS_REG_2 edx
558  #define AS_REG_3 r8d
559  #define AS_REG_4 r9d
560  #define AS_REG_5 eax
561  #define AS_REG_6 r10d
562  #define AS_REG_7 r11d
563  #define AS_REG_1d ecx
564  #define AS_REG_2d edx
565  #define AS_REG_3d r8d
566  #define AS_REG_4d r9d
567  #define AS_REG_5d eax
568  #define AS_REG_6d r10d
569  #define AS_REG_7d r11d
570  #define WORD_SZ 4
571  #define WORD_REG(x) e##x
572  #define WORD_PTR DWORD PTR
573  #define AS_PUSH_IF86(x) AS1(push r##x)
574  #define AS_POP_IF86(x) AS1(pop r##x)
575  #define AS_JCXZ jecxz
576 #elif CRYPTOPP_BOOL_X64
577  #ifdef CRYPTOPP_GENERATE_X64_MASM
578  #define AS_REG_1 rcx
579  #define AS_REG_2 rdx
580  #define AS_REG_3 r8
581  #define AS_REG_4 r9
582  #define AS_REG_5 rax
583  #define AS_REG_6 r10
584  #define AS_REG_7 r11
585  #define AS_REG_1d ecx
586  #define AS_REG_2d edx
587  #define AS_REG_3d r8d
588  #define AS_REG_4d r9d
589  #define AS_REG_5d eax
590  #define AS_REG_6d r10d
591  #define AS_REG_7d r11d
592  #else
593  #define AS_REG_1 rdi
594  #define AS_REG_2 rsi
595  #define AS_REG_3 rdx
596  #define AS_REG_4 rcx
597  #define AS_REG_5 r8
598  #define AS_REG_6 r9
599  #define AS_REG_7 r10
600  #define AS_REG_1d edi
601  #define AS_REG_2d esi
602  #define AS_REG_3d edx
603  #define AS_REG_4d ecx
604  #define AS_REG_5d r8d
605  #define AS_REG_6d r9d
606  #define AS_REG_7d r10d
607  #endif
608  #define WORD_SZ 8
609  #define WORD_REG(x) r##x
610  #define WORD_PTR QWORD PTR
611  #define AS_PUSH_IF86(x)
612  #define AS_POP_IF86(x)
613  #define AS_JCXZ jrcxz
614 #endif
615 
616 // helper macro for stream cipher output
617 #define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\
618  AS2( test inputPtr, inputPtr)\
619  ASC( jz, labelPrefix##3)\
620  AS2( test inputPtr, 15)\
621  ASC( jnz, labelPrefix##7)\
622  AS2( pxor xmm##x0, [inputPtr+p0*16])\
623  AS2( pxor xmm##x1, [inputPtr+p1*16])\
624  AS2( pxor xmm##x2, [inputPtr+p2*16])\
625  AS2( pxor xmm##x3, [inputPtr+p3*16])\
626  AS2( add inputPtr, increment*16)\
627  ASC( jmp, labelPrefix##3)\
628  ASL(labelPrefix##7)\
629  AS2( movdqu xmm##t, [inputPtr+p0*16])\
630  AS2( pxor xmm##x0, xmm##t)\
631  AS2( movdqu xmm##t, [inputPtr+p1*16])\
632  AS2( pxor xmm##x1, xmm##t)\
633  AS2( movdqu xmm##t, [inputPtr+p2*16])\
634  AS2( pxor xmm##x2, xmm##t)\
635  AS2( movdqu xmm##t, [inputPtr+p3*16])\
636  AS2( pxor xmm##x3, xmm##t)\
637  AS2( add inputPtr, increment*16)\
638  ASL(labelPrefix##3)\
639  AS2( test outputPtr, 15)\
640  ASC( jnz, labelPrefix##8)\
641  AS2( movdqa [outputPtr+p0*16], xmm##x0)\
642  AS2( movdqa [outputPtr+p1*16], xmm##x1)\
643  AS2( movdqa [outputPtr+p2*16], xmm##x2)\
644  AS2( movdqa [outputPtr+p3*16], xmm##x3)\
645  ASC( jmp, labelPrefix##9)\
646  ASL(labelPrefix##8)\
647  AS2( movdqu [outputPtr+p0*16], xmm##x0)\
648  AS2( movdqu [outputPtr+p1*16], xmm##x1)\
649  AS2( movdqu [outputPtr+p2*16], xmm##x2)\
650  AS2( movdqu [outputPtr+p3*16], xmm##x3)\
651  ASL(labelPrefix##9)\
652  AS2( add outputPtr, increment*16)
653 
654 #endif // X86/X32/X64
655 
656 NAMESPACE_END
657 
658 #endif // CRYPTOPP_CPU_H
bool HasISSE()
Determines SSE availability.
Definition: cpu.h:190
bool HasSSE4()
Determines SSE4 availability.
Definition: cpu.h:230
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:220
bool HasPadlockRNG()
Determines Padlock RNG availability.
Definition: cpu.h:290
bool IsP4()
Determines if the CPU is an Intel P4.
Definition: cpu.h:260
Library configuration file.
int GetCacheLineSize()
Provides the cache line size.
Definition: cpu.h:344
bool HasRDRAND()
Determines RDRAND availability.
Definition: cpu.h:270
bool HasRDSEED()
Determines RDSEED availability.
Definition: cpu.h:280
bool HasCLMUL()
Determines Carryless Multiply availability.
Definition: cpu.h:250
bool HasPadlockACE2()
Determines Padlock ACE2 availability.
Definition: cpu.h:310
bool HasPadlockPHE()
Determines Padlock PHE availability.
Definition: cpu.h:320
bool HasPadlockPMM()
Determines Padlock PMM availability.
Definition: cpu.h:330
bool HasAESNI()
Determines AES-NI availability.
Definition: cpu.h:240
bool HasSSE2()
Determines SSE2 availability.
Definition: cpu.h:205
bool HasMMX()
Determines MMX availability.
Definition: cpu.h:175
Crypto++ library namespace.
bool HasPadlockACE()
Determines Padlock ACE availability.
Definition: cpu.h:300