Crypto++  6.0
Free C++ class library of cryptographic schemes
cpu.h
Go to the documentation of this file.
1 // cpu.h - originally written and placed in the public domain by Wei Dai
2 // updated for ARM and PowerPC by Jeffrey Walton.
3 // updated to split CPU_Query() and CPU_Probe() by Jeffrey Walton.
4 
5 /// \file cpu.h
6 /// \brief Functions for CPU features and intrinsics
7 /// \details The CPU functions are used in IA-32, ARM and PowerPC code paths. The
8 /// functions provide cpu specific feature testing on IA-32, ARM and PowerPC machines.
9 /// \details Feature detection uses CPUID on IA-32, like Intel and AMD. On other platforms
10 /// a two-part strategy is used. First, the library attempts to *Query* the OS for a feature,
11 /// like using Linux getauxval() or android_getCpuFeatures(). If that fails, then *Probe*
12 /// the cpu executing an instruction and an observe a SIGILL if unsupported. The general
13 /// pattern used by the library is:
14 /// <pre>
15 /// g_hasCRC32 = CPU_QueryCRC32() || CPU_ProbeCRC32();
16 /// g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
17 /// g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
18 /// </pre>
19 /// \details Generally speaking, CPU_Query() is in the source file <tt>cpu.cpp</tt> because it
20 /// does not require special architectural flags. CPU_Probe() is in a source file that recieves
21 /// architectural flags, like <tt>sse-simd.cpp</tt>, <tt>neon-simd.cpp</tt> and
22 /// <tt>ppc-simd.cpp</tt>. For example, compiling <tt>neon-simd.cpp</tt> on an ARM64 machine will
23 /// have <tt>-march=armv8-a</tt> applied during a compile to make the instruction set architecture
24 /// (ISA) available.
25 /// \details The cpu probes are expensive when compared to a standard OS feature query. The library
26 /// also avoids probes on Apple platforms because Apple's signal handling for SIGILLs appears to
27 /// corrupt memory. CPU_Probe() will unconditionally return false for Apple platforms. OpenSSL
28 /// experienced the same problem and moved away from SIGILL probes on Apple.
29 
30 #ifndef CRYPTOPP_CPU_H
31 #define CRYPTOPP_CPU_H
32 
33 #include "config.h"
34 
35 // Issue 340
36 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
37 # pragma GCC diagnostic push
38 # pragma GCC diagnostic ignored "-Wconversion"
39 # pragma GCC diagnostic ignored "-Wsign-conversion"
40 #endif
41 
42 // Applies to both X86/X32/X64 and ARM32/ARM64
43 #if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER)
44  #define NEW_LINE "\n"
45  #define INTEL_PREFIX ".intel_syntax;"
46  #define INTEL_NOPREFIX ".intel_syntax;"
47  #define ATT_PREFIX ".att_syntax;"
48  #define ATT_NOPREFIX ".att_syntax;"
49 #elif defined(__GNUC__)
50  #define NEW_LINE
51  #define INTEL_PREFIX ".intel_syntax prefix;"
52  #define INTEL_NOPREFIX ".intel_syntax noprefix;"
53  #define ATT_PREFIX ".att_syntax prefix;"
54  #define ATT_NOPREFIX ".att_syntax noprefix;"
55 #else
56  #define NEW_LINE
57  #define INTEL_PREFIX
58  #define INTEL_NOPREFIX
59  #define ATT_PREFIX
60  #define ATT_NOPREFIX
61 #endif
62 
63 #ifdef CRYPTOPP_GENERATE_X64_MASM
64 
65 #define CRYPTOPP_X86_ASM_AVAILABLE
66 #define CRYPTOPP_BOOL_X64 1
67 #define CRYPTOPP_SSE2_ASM_AVAILABLE 1
68 #define NAMESPACE_END
69 
70 #else
71 
72 NAMESPACE_BEGIN(CryptoPP)
73 
74 // ***************************** IA-32 ***************************** //
75 
76 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING
77 
78 #define CRYPTOPP_CPUID_AVAILABLE 1
79 
80 // Hide from Doxygen
81 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
82 // These should not be used directly
83 extern CRYPTOPP_DLL bool g_x86DetectionDone;
84 extern CRYPTOPP_DLL bool g_hasSSE2;
85 extern CRYPTOPP_DLL bool g_hasSSSE3;
86 extern CRYPTOPP_DLL bool g_hasSSE41;
87 extern CRYPTOPP_DLL bool g_hasSSE42;
88 extern CRYPTOPP_DLL bool g_hasAESNI;
89 extern CRYPTOPP_DLL bool g_hasCLMUL;
90 extern CRYPTOPP_DLL bool g_hasSHA;
91 extern CRYPTOPP_DLL bool g_hasADX;
92 extern CRYPTOPP_DLL bool g_isP4;
93 extern CRYPTOPP_DLL bool g_hasRDRAND;
94 extern CRYPTOPP_DLL bool g_hasRDSEED;
95 extern CRYPTOPP_DLL bool g_hasPadlockRNG;
96 extern CRYPTOPP_DLL bool g_hasPadlockACE;
97 extern CRYPTOPP_DLL bool g_hasPadlockACE2;
98 extern CRYPTOPP_DLL bool g_hasPadlockPHE;
99 extern CRYPTOPP_DLL bool g_hasPadlockPMM;
100 extern CRYPTOPP_DLL word32 g_cacheLineSize;
101 
102 CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
103 CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 func, word32 subfunc, word32 output[4]);
104 #endif // CRYPTOPP_DOXYGEN_PROCESSING
105 
106 /// \name IA-32 CPU FEATURES
107 //@{
108 
109 /// \brief Determines SSE2 availability
110 /// \returns true if SSE2 is determined to be available, false otherwise
111 /// \details MMX, SSE and SSE2 are core processor features for x86_64, and
112 /// the function always returns true for the platform.
113 /// \note This function is only available on Intel IA-32 platforms
114 inline bool HasSSE2()
115 {
116 #if CRYPTOPP_BOOL_X64
117  return true;
118 #else
119  if (!g_x86DetectionDone)
120  DetectX86Features();
121  return g_hasSSE2;
122 #endif
123 }
124 
125 /// \brief Determines SSSE3 availability
126 /// \returns true if SSSE3 is determined to be available, false otherwise
127 /// \details HasSSSE3() is a runtime check performed using CPUID
128 /// \note This function is only available on Intel IA-32 platforms
129 inline bool HasSSSE3()
130 {
131  if (!g_x86DetectionDone)
132  DetectX86Features();
133  return g_hasSSSE3;
134 }
135 
136 /// \brief Determines SSE4.1 availability
137 /// \returns true if SSE4.1 is determined to be available, false otherwise
138 /// \details HasSSE41() is a runtime check performed using CPUID
139 /// \note This function is only available on Intel IA-32 platforms
140 inline bool HasSSE41()
141 {
142  if (!g_x86DetectionDone)
143  DetectX86Features();
144  return g_hasSSE41;
145 }
146 
147 /// \brief Determines SSE4.2 availability
148 /// \returns true if SSE4.2 is determined to be available, false otherwise
149 /// \details HasSSE42() is a runtime check performed using CPUID
150 /// \note This function is only available on Intel IA-32 platforms
151 inline bool HasSSE42()
152 {
153  if (!g_x86DetectionDone)
154  DetectX86Features();
155  return g_hasSSE42;
156 }
157 
158 /// \brief Determines AES-NI availability
159 /// \returns true if AES-NI is determined to be available, false otherwise
160 /// \details HasAESNI() is a runtime check performed using CPUID
161 /// \note This function is only available on Intel IA-32 platforms
162 inline bool HasAESNI()
163 {
164  if (!g_x86DetectionDone)
165  DetectX86Features();
166  return g_hasAESNI;
167 }
168 
169 /// \brief Determines Carryless Multiply availability
170 /// \returns true if pclmulqdq is determined to be available, false otherwise
171 /// \details HasCLMUL() is a runtime check performed using CPUID
172 /// \note This function is only available on Intel IA-32 platforms
173 inline bool HasCLMUL()
174 {
175  if (!g_x86DetectionDone)
176  DetectX86Features();
177  return g_hasCLMUL;
178 }
179 
180 /// \brief Determines SHA availability
181 /// \returns true if SHA is determined to be available, false otherwise
182 /// \details HasSHA() is a runtime check performed using CPUID
183 /// \note This function is only available on Intel IA-32 platforms
184 inline bool HasSHA()
185 {
186  if (!g_x86DetectionDone)
187  DetectX86Features();
188  return g_hasSHA;
189 }
190 
191 /// \brief Determines ADX availability
192 /// \returns true if ADX is determined to be available, false otherwise
193 /// \details HasADX() is a runtime check performed using CPUID
194 /// \note This function is only available on Intel IA-32 platforms
195 inline bool HasADX()
196 {
197  if (!g_x86DetectionDone)
198  DetectX86Features();
199  return g_hasADX;
200 }
201 
202 /// \brief Determines if the CPU is an Intel P4
203 /// \returns true if the CPU is a P4, false otherwise
204 /// \details IsP4() is a runtime check performed using CPUID
205 /// \note This function is only available on Intel IA-32 platforms
206 inline bool IsP4()
207 {
208  if (!g_x86DetectionDone)
209  DetectX86Features();
210  return g_isP4;
211 }
212 
213 /// \brief Determines RDRAND availability
214 /// \returns true if RDRAND is determined to be available, false otherwise
215 /// \details HasRDRAND() is a runtime check performed using CPUID
216 /// \note This function is only available on Intel IA-32 platforms
217 inline bool HasRDRAND()
218 {
219  if (!g_x86DetectionDone)
220  DetectX86Features();
221  return g_hasRDRAND;
222 }
223 
224 /// \brief Determines RDSEED availability
225 /// \returns true if RDSEED is determined to be available, false otherwise
226 /// \details HasRDSEED() is a runtime check performed using CPUID
227 /// \note This function is only available on Intel IA-32 platforms
228 inline bool HasRDSEED()
229 {
230  if (!g_x86DetectionDone)
231  DetectX86Features();
232  return g_hasRDSEED;
233 }
234 
235 /// \brief Determines Padlock RNG availability
236 /// \returns true if VIA Padlock RNG is determined to be available, false otherwise
237 /// \details HasPadlockRNG() is a runtime check performed using CPUID
238 /// \note This function is only available on Intel IA-32 platforms
239 inline bool HasPadlockRNG()
240 {
241  if (!g_x86DetectionDone)
242  DetectX86Features();
243  return g_hasPadlockRNG;
244 }
245 
246 /// \brief Determines Padlock ACE availability
247 /// \returns true if VIA Padlock ACE is determined to be available, false otherwise
248 /// \details HasPadlockACE() is a runtime check performed using CPUID
249 /// \note This function is only available on Intel IA-32 platforms
250 inline bool HasPadlockACE()
251 {
252  if (!g_x86DetectionDone)
253  DetectX86Features();
254  return g_hasPadlockACE;
255 }
256 
257 /// \brief Determines Padlock ACE2 availability
258 /// \returns true if VIA Padlock ACE2 is determined to be available, false otherwise
259 /// \details HasPadlockACE2() is a runtime check performed using CPUID
260 /// \note This function is only available on Intel IA-32 platforms
261 inline bool HasPadlockACE2()
262 {
263  if (!g_x86DetectionDone)
264  DetectX86Features();
265  return g_hasPadlockACE2;
266 }
267 
268 /// \brief Determines Padlock PHE availability
269 /// \returns true if VIA Padlock PHE is determined to be available, false otherwise
270 /// \details HasPadlockPHE() is a runtime check performed using CPUID
271 /// \note This function is only available on Intel IA-32 platforms
272 inline bool HasPadlockPHE()
273 {
274  if (!g_x86DetectionDone)
275  DetectX86Features();
276  return g_hasPadlockPHE;
277 }
278 
279 /// \brief Determines Padlock PMM availability
280 /// \returns true if VIA Padlock PMM is determined to be available, false otherwise
281 /// \details HasPadlockPMM() is a runtime check performed using CPUID
282 /// \note This function is only available on Intel IA-32 platforms
283 inline bool HasPadlockPMM()
284 {
285  if (!g_x86DetectionDone)
286  DetectX86Features();
287  return g_hasPadlockPMM;
288 }
289 
290 /// \brief Provides the cache line size
291 /// \returns lower bound on the size of a cache line in bytes, if available
292 /// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
293 /// is available. If the value is not available at runtime, then 32 is returned for a 32-bit
294 /// processor and 64 is returned for a 64-bit processor.
295 /// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
296 /// and AIX also makes the value available to user space and it is also usually accurate. The
297 /// ARM processor equivalent is a privileged instruction, so a compile time value is returned.
298 inline int GetCacheLineSize()
299 {
300  if (!g_x86DetectionDone)
301  DetectX86Features();
302  return g_cacheLineSize;
303 }
304 //@}
305 
306 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
307 
308 // ***************************** ARM-32, Aarch32 and Aarch64 ***************************** //
309 
310 #if CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64 || CRYPTOPP_DOXYGEN_PROCESSING
311 
312 // Hide from Doxygen
313 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
314 extern bool g_ArmDetectionDone;
315 extern bool g_hasNEON, g_hasPMULL, g_hasCRC32, g_hasAES, g_hasSHA1, g_hasSHA2;
316 void CRYPTOPP_API DetectArmFeatures();
317 #endif // CRYPTOPP_DOXYGEN_PROCESSING
318 
319 /// \name ARM A-32, Aarch32 and AArch64 CPU FEATURES
320 //@{
321 
322 /// \brief Determine if an ARM processor has Advanced SIMD available
323 /// \returns true if the hardware is capable of Advanced SIMD at runtime, false otherwise.
324 /// \details Advanced SIMD instructions are available under most ARMv7, Aarch32 and Aarch64.
325 /// \details Runtime support requires compile time support. When compiling with GCC, you may
326 /// need to compile with <tt>-mfpu=neon</tt> (32-bit) or <tt>-march=armv8-a</tt>
327 /// (64-bit). Also see ARM's <tt>__ARM_NEON</tt> preprocessor macro.
328 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
329 inline bool HasNEON()
330 {
331  // ASIMD is a core feature on Aarch32 and Aarch64 like SSE2 is a core feature on x86_64
332 #if defined(__aarch32__) || defined(__aarch64__)
333  return true;
334 #else
335  if (!g_ArmDetectionDone)
336  DetectArmFeatures();
337  return g_hasNEON;
338 #endif
339 }
340 
341 /// \brief Determine if an ARM processor provides Polynomial Multiplication
342 /// \returns true if the hardware is capable of polynomial multiplications at runtime, false otherwise.
343 /// \details The multiplication instructions are available under Aarch32 and Aarch64.
344 /// \details Runtime support requires compile time support. When compiling with GCC, you may
345 /// need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
346 /// <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
347 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
348 inline bool HasPMULL()
349 {
350 #if defined(__aarch32__) || defined(__aarch64__)
351  if (!g_ArmDetectionDone)
352  DetectArmFeatures();
353  return g_hasPMULL;
354 #else
355  return false;
356 #endif
357 }
358 
359 /// \brief Determine if an ARM processor has CRC32 available
360 /// \returns true if the hardware is capable of CRC32 at runtime, false otherwise.
361 /// \details CRC32 instructions provide access to the processor's CRC-32 and CRC-32C instructions.
362 /// They are provided by ARM C Language Extensions 2.0 (ACLE 2.0) and available under Aarch32 and Aarch64.
363 /// \details Runtime support requires compile time support. When compiling with GCC, you may
364 /// need to compile with <tt>-march=armv8-a+crc</tt>; while Apple requires
365 /// <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRC32</tt> preprocessor macro.
366 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
367 inline bool HasCRC32()
368 {
369 #if defined(__aarch32__) || defined(__aarch64__)
370  if (!g_ArmDetectionDone)
371  DetectArmFeatures();
372  return g_hasCRC32;
373 #else
374  return false;
375 #endif
376 }
377 
378 /// \brief Determine if an ARM processor has AES available
379 /// \returns true if the hardware is capable of AES at runtime, false otherwise.
380 /// \details AES is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
381 /// accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
382 /// \details Runtime support requires compile time support. When compiling with GCC, you may
383 /// need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
384 /// <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
385 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
386 inline bool HasAES()
387 {
388 #if defined(__aarch32__) || defined(__aarch64__)
389  if (!g_ArmDetectionDone)
390  DetectArmFeatures();
391  return g_hasAES;
392 #else
393  return false;
394 #endif
395 }
396 
397 /// \brief Determine if an ARM processor has SHA1 available
398 /// \returns true if the hardware is capable of SHA1 at runtime, false otherwise.
399 /// \details SHA1 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
400 /// accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
401 /// \details Runtime support requires compile time support. When compiling with GCC, you may
402 /// need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
403 /// <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
404 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
405 inline bool HasSHA1()
406 {
407 #if defined(__aarch32__) || defined(__aarch64__)
408  if (!g_ArmDetectionDone)
409  DetectArmFeatures();
410  return g_hasSHA1;
411 #else
412  return false;
413 #endif
414 }
415 
416 /// \brief Determine if an ARM processor has SHA2 available
417 /// \returns true if the hardware is capable of SHA2 at runtime, false otherwise.
418 /// \details SHA2 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
419 /// accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
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 /// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
424 inline bool HasSHA2()
425 {
426 #if defined(__aarch32__) || defined(__aarch64__)
427  if (!g_ArmDetectionDone)
428  DetectArmFeatures();
429  return g_hasSHA2;
430 #else
431  return false;
432 #endif
433 }
434 
435 //@}
436 
437 #endif // CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64
438 
439 // ***************************** PowerPC ***************************** //
440 
441 #if CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 || CRYPTOPP_DOXYGEN_PROCESSING
442 
443 // Hide from Doxygen
444 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
445 extern bool g_PowerpcDetectionDone;
446 extern bool g_hasAltivec, g_hasPower7, g_hasPower8, g_hasAES, g_hasSHA256, g_hasSHA512;
447 extern word32 g_cacheLineSize;
448 void CRYPTOPP_API DetectPowerpcFeatures();
449 #endif // CRYPTOPP_DOXYGEN_PROCESSING
450 
451 /// \name POWERPC CPU FEATURES
452 //@{
453 
454 /// \brief Determine if a PowerPC processor has Altivec available
455 /// \returns true if the hardware is capable of Altivec at runtime, false otherwise.
456 /// \details Altivec instructions are available under most modern PowerPCs.
457 /// \details Runtime support requires compile time support. When compiling with GCC, you may
458 /// need to compile with <tt>-mcpu=power7</tt>; while IBM XL C/C++ compilers require
459 /// <tt>-qarch=pwr7 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
460 /// \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned
461 /// loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the
462 /// GNUmakefile sets <tt>-DCRYPTOPP_DISABLE_ALTIVEC</tt>.
463 /// \note This function is only available on PowerPC and PowerPC-64 platforms
464 inline bool HasAltivec()
465 {
466  if (!g_PowerpcDetectionDone)
467  DetectPowerpcFeatures();
468  return g_hasAltivec;
469 }
470 
471 /// \brief Determine if a PowerPC processor has Power8 available
472 /// \returns true if the hardware is capable of Power8 at runtime, false otherwise.
473 /// \details Altivec instructions are available under most modern PowerPCs.
474 /// \details Runtime support requires compile time support. When compiling with GCC, you may
475 /// need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
476 /// <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
477 /// \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned
478 /// loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the
479 /// GNUmakefile sets <tt>-DCRYPTOPP_DISABLE_ALTIVEC</tt>.
480 /// \note This function is only available on PowerPC and PowerPC-64 platforms
481 inline bool HasPower7()
482 {
483  if (!g_PowerpcDetectionDone)
484  DetectPowerpcFeatures();
485  return g_hasPower7;
486 }
487 
488 /// \brief Determine if a PowerPC processor has Power8 available
489 /// \returns true if the hardware is capable of Power8 at runtime, false otherwise.
490 /// \details Altivec instructions are available under most modern PowerPCs.
491 /// \details Runtime support requires compile time support. When compiling with GCC, you may
492 /// need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
493 /// <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
494 /// \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned
495 /// loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the
496 /// GNUmakefile sets <tt>-DCRYPTOPP_DISABLE_ALTIVEC</tt>.
497 /// \note This function is only available on PowerPC and PowerPC-64 platforms
498 inline bool HasPower8()
499 {
500  if (!g_PowerpcDetectionDone)
501  DetectPowerpcFeatures();
502  return g_hasPower8;
503 }
504 
505 /// \brief Determine if a PowerPC processor has AES available
506 /// \returns true if the hardware is capable of AES at runtime, false otherwise.
507 /// \details AES is part of the in-crypto extensions on Power8 and Power9.
508 /// \details Runtime support requires compile time support. When compiling with GCC, you may
509 /// need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
510 /// <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
511 /// \note This function is only available on PowerPC and PowerPC-64 platforms
512 inline bool HasAES()
513 {
514  if (!g_PowerpcDetectionDone)
515  DetectPowerpcFeatures();
516  return g_hasAES;
517 }
518 
519 /// \brief Determine if a PowerPC processor has SHA256 available
520 /// \returns true if the hardware is capable of SHA256 at runtime, false otherwise.
521 /// \details SHA is part of the in-crypto extensions on Power8 and Power9.
522 /// \details Runtime support requires compile time support. When compiling with GCC, you may
523 /// need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
524 /// <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
525 /// \note This function is only available on PowerPC and PowerPC-64 platforms
526 inline bool HasSHA256()
527 {
528  if (!g_PowerpcDetectionDone)
529  DetectPowerpcFeatures();
530  return g_hasSHA256;
531 }
532 
533 /// \brief Determine if a PowerPC processor has SHA512 available
534 /// \returns true if the hardware is capable of SHA512 at runtime, false otherwise.
535 /// \details SHA is part of the in-crypto extensions on Power8 and Power9.
536 /// \details Runtime support requires compile time support. When compiling with GCC, you may
537 /// need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
538 /// <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
539 /// \note This function is only available on PowerPC and PowerPC-64 platforms
540 inline bool HasSHA512()
541 {
542  if (!g_PowerpcDetectionDone)
543  DetectPowerpcFeatures();
544  return g_hasSHA512;
545 }
546 
547 /// \brief Provides the cache line size
548 /// \returns lower bound on the size of a cache line in bytes, if available
549 /// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
550 /// is available. If the value is not available at runtime, then 32 is returned for a 32-bit
551 /// processor and 64 is returned for a 64-bit processor.
552 /// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
553 /// and AIX also makes the value available to user space and it is also usually accurate. The
554 /// ARM processor equivalent is a privileged instruction, so a compile time value is returned.
555 inline int GetCacheLineSize()
556 {
557  if (!g_PowerpcDetectionDone)
558  DetectPowerpcFeatures();
559  return g_cacheLineSize;
560 }
561 
562 //@}
563 
564 #endif // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
565 
566 // ***************************** L1 cache line ***************************** //
567 
568 // Non-Intel systems
569 #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
570 /// \brief Provides the cache line size
571 /// \returns lower bound on the size of a cache line in bytes, if available
572 /// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
573 /// is available. If the value is not available at runtime, then 32 is returned for a 32-bit
574 /// processor and 64 is returned for a 64-bit processor.
575 /// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
576 /// and AIX also makes the value available to user space and it is also usually accurate. The
577 /// ARM processor equivalent is a privileged instruction, so a compile time value is returned.
578 inline int GetCacheLineSize()
579 {
580  return CRYPTOPP_L1_CACHE_LINE_SIZE;
581 }
582 #endif // Non-Intel systems
583 
584 #endif // CRYPTOPP_GENERATE_X64_MASM
585 
586 // ***************************** Inline ASM Helper ***************************** //
587 
588 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
589 
590 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
591 
592 #ifdef CRYPTOPP_GENERATE_X64_MASM
593  #define AS1(x) x*newline*
594  #define AS2(x, y) x, y*newline*
595  #define AS3(x, y, z) x, y, z*newline*
596  #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline*
597  #define ASL(x) label##x:*newline*
598  #define ASJ(x, y, z) x label##y*newline*
599  #define ASC(x, y) x label##y*newline*
600  #define AS_HEX(y) 0##y##h
601 #elif defined(_MSC_VER) || defined(__BORLANDC__)
602  #define AS1(x) __asm {x}
603  #define AS2(x, y) __asm {x, y}
604  #define AS3(x, y, z) __asm {x, y, z}
605  #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)}
606  #define ASL(x) __asm {label##x:}
607  #define ASJ(x, y, z) __asm {x label##y}
608  #define ASC(x, y) __asm {x label##y}
609  #define CRYPTOPP_NAKED __declspec(naked)
610  #define AS_HEX(y) 0x##y
611 #else
612  // define these in two steps to allow arguments to be expanded
613  #define GNU_AS1(x) #x ";" NEW_LINE
614  #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE
615  #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE
616  #define GNU_ASL(x) "\n" #x ":" NEW_LINE
617  #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
618  #define AS1(x) GNU_AS1(x)
619  #define AS2(x, y) GNU_AS2(x, y)
620  #define AS3(x, y, z) GNU_AS3(x, y, z)
621  #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
622  #define ASL(x) GNU_ASL(x)
623  #define ASJ(x, y, z) GNU_ASJ(x, y, z)
624  #define ASC(x, y) #x " " #y ";"
625  #define CRYPTOPP_NAKED
626  #define AS_HEX(y) 0x##y
627 #endif
628 
629 #define IF0(y)
630 #define IF1(y) y
631 
632 #ifdef CRYPTOPP_GENERATE_X64_MASM
633 #define ASM_MOD(x, y) ((x) MOD (y))
634 #define XMMWORD_PTR XMMWORD PTR
635 #else
636 // GNU assembler doesn't seem to have mod operator
637 #define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
638 // GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM
639 #define XMMWORD_PTR
640 #endif
641 
642 #if CRYPTOPP_BOOL_X86
643  #define AS_REG_1 ecx
644  #define AS_REG_2 edx
645  #define AS_REG_3 esi
646  #define AS_REG_4 edi
647  #define AS_REG_5 eax
648  #define AS_REG_6 ebx
649  #define AS_REG_7 ebp
650  #define AS_REG_1d ecx
651  #define AS_REG_2d edx
652  #define AS_REG_3d esi
653  #define AS_REG_4d edi
654  #define AS_REG_5d eax
655  #define AS_REG_6d ebx
656  #define AS_REG_7d ebp
657  #define WORD_SZ 4
658  #define WORD_REG(x) e##x
659  #define WORD_PTR DWORD PTR
660  #define AS_PUSH_IF86(x) AS1(push e##x)
661  #define AS_POP_IF86(x) AS1(pop e##x)
662  #define AS_JCXZ jecxz
663 #elif CRYPTOPP_BOOL_X32
664  #define AS_REG_1 ecx
665  #define AS_REG_2 edx
666  #define AS_REG_3 r8d
667  #define AS_REG_4 r9d
668  #define AS_REG_5 eax
669  #define AS_REG_6 r10d
670  #define AS_REG_7 r11d
671  #define AS_REG_1d ecx
672  #define AS_REG_2d edx
673  #define AS_REG_3d r8d
674  #define AS_REG_4d r9d
675  #define AS_REG_5d eax
676  #define AS_REG_6d r10d
677  #define AS_REG_7d r11d
678  #define WORD_SZ 4
679  #define WORD_REG(x) e##x
680  #define WORD_PTR DWORD PTR
681  #define AS_PUSH_IF86(x) AS1(push r##x)
682  #define AS_POP_IF86(x) AS1(pop r##x)
683  #define AS_JCXZ jecxz
684 #elif CRYPTOPP_BOOL_X64
685  #ifdef CRYPTOPP_GENERATE_X64_MASM
686  #define AS_REG_1 rcx
687  #define AS_REG_2 rdx
688  #define AS_REG_3 r8
689  #define AS_REG_4 r9
690  #define AS_REG_5 rax
691  #define AS_REG_6 r10
692  #define AS_REG_7 r11
693  #define AS_REG_1d ecx
694  #define AS_REG_2d edx
695  #define AS_REG_3d r8d
696  #define AS_REG_4d r9d
697  #define AS_REG_5d eax
698  #define AS_REG_6d r10d
699  #define AS_REG_7d r11d
700  #else
701  #define AS_REG_1 rdi
702  #define AS_REG_2 rsi
703  #define AS_REG_3 rdx
704  #define AS_REG_4 rcx
705  #define AS_REG_5 r8
706  #define AS_REG_6 r9
707  #define AS_REG_7 r10
708  #define AS_REG_1d edi
709  #define AS_REG_2d esi
710  #define AS_REG_3d edx
711  #define AS_REG_4d ecx
712  #define AS_REG_5d r8d
713  #define AS_REG_6d r9d
714  #define AS_REG_7d r10d
715  #endif
716  #define WORD_SZ 8
717  #define WORD_REG(x) r##x
718  #define WORD_PTR QWORD PTR
719  #define AS_PUSH_IF86(x)
720  #define AS_POP_IF86(x)
721  #define AS_JCXZ jrcxz
722 #endif
723 
724 // helper macro for stream cipher output
725 #define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\
726  AS2( test inputPtr, inputPtr)\
727  ASC( jz, labelPrefix##3)\
728  AS2( test inputPtr, 15)\
729  ASC( jnz, labelPrefix##7)\
730  AS2( pxor xmm##x0, [inputPtr+p0*16])\
731  AS2( pxor xmm##x1, [inputPtr+p1*16])\
732  AS2( pxor xmm##x2, [inputPtr+p2*16])\
733  AS2( pxor xmm##x3, [inputPtr+p3*16])\
734  AS2( add inputPtr, increment*16)\
735  ASC( jmp, labelPrefix##3)\
736  ASL(labelPrefix##7)\
737  AS2( movdqu xmm##t, [inputPtr+p0*16])\
738  AS2( pxor xmm##x0, xmm##t)\
739  AS2( movdqu xmm##t, [inputPtr+p1*16])\
740  AS2( pxor xmm##x1, xmm##t)\
741  AS2( movdqu xmm##t, [inputPtr+p2*16])\
742  AS2( pxor xmm##x2, xmm##t)\
743  AS2( movdqu xmm##t, [inputPtr+p3*16])\
744  AS2( pxor xmm##x3, xmm##t)\
745  AS2( add inputPtr, increment*16)\
746  ASL(labelPrefix##3)\
747  AS2( test outputPtr, 15)\
748  ASC( jnz, labelPrefix##8)\
749  AS2( movdqa [outputPtr+p0*16], xmm##x0)\
750  AS2( movdqa [outputPtr+p1*16], xmm##x1)\
751  AS2( movdqa [outputPtr+p2*16], xmm##x2)\
752  AS2( movdqa [outputPtr+p3*16], xmm##x3)\
753  ASC( jmp, labelPrefix##9)\
754  ASL(labelPrefix##8)\
755  AS2( movdqu [outputPtr+p0*16], xmm##x0)\
756  AS2( movdqu [outputPtr+p1*16], xmm##x1)\
757  AS2( movdqu [outputPtr+p2*16], xmm##x2)\
758  AS2( movdqu [outputPtr+p3*16], xmm##x3)\
759  ASL(labelPrefix##9)\
760  AS2( add outputPtr, increment*16)
761 
762 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
763 
764 #endif // Not CRYPTOPP_DOXYGEN_PROCESSING
765 
766 NAMESPACE_END
767 
768 // Issue 340
769 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
770 # pragma GCC diagnostic pop
771 #endif
772 
773 #endif // CRYPTOPP_CPU_H
bool HasSHA()
Determines SHA availability.
Definition: cpu.h:184
bool HasAltivec()
Determine if a PowerPC processor has Altivec available.
Definition: cpu.h:464
bool HasCRC32()
Determine if an ARM processor has CRC32 available.
Definition: cpu.h:367
bool HasSSSE3()
Determines SSSE3 availability.
Definition: cpu.h:129
bool HasADX()
Determines ADX availability.
Definition: cpu.h:195
bool HasPadlockRNG()
Determines Padlock RNG availability.
Definition: cpu.h:239
bool HasAES()
Determine if an ARM processor has AES available.
Definition: cpu.h:386
bool IsP4()
Determines if the CPU is an Intel P4.
Definition: cpu.h:206
Library configuration file.
int GetCacheLineSize()
Provides the cache line size.
Definition: cpu.h:298
bool HasRDRAND()
Determines RDRAND availability.
Definition: cpu.h:217
bool HasPower7()
Determine if a PowerPC processor has Power8 available.
Definition: cpu.h:481
bool HasSHA256()
Determine if a PowerPC processor has SHA256 available.
Definition: cpu.h:526
bool HasPower8()
Determine if a PowerPC processor has Power8 available.
Definition: cpu.h:498
bool HasRDSEED()
Determines RDSEED availability.
Definition: cpu.h:228
bool HasCLMUL()
Determines Carryless Multiply availability.
Definition: cpu.h:173
bool HasSHA1()
Determine if an ARM processor has SHA1 available.
Definition: cpu.h:405
bool HasSHA512()
Determine if a PowerPC processor has SHA512 available.
Definition: cpu.h:540
bool HasPadlockACE2()
Determines Padlock ACE2 availability.
Definition: cpu.h:261
bool HasPadlockPHE()
Determines Padlock PHE availability.
Definition: cpu.h:272
bool HasPadlockPMM()
Determines Padlock PMM availability.
Definition: cpu.h:283
bool HasAESNI()
Determines AES-NI availability.
Definition: cpu.h:162
bool HasSSE2()
Determines SSE2 availability.
Definition: cpu.h:114
bool HasSHA2()
Determine if an ARM processor has SHA2 available.
Definition: cpu.h:424
bool HasSSE41()
Determines SSE4.1 availability.
Definition: cpu.h:140
Crypto++ library namespace.
bool HasPadlockACE()
Determines Padlock ACE availability.
Definition: cpu.h:250
bool HasSSE42()
Determines SSE4.2 availability.
Definition: cpu.h:151
bool HasPMULL()
Determine if an ARM processor provides Polynomial Multiplication.
Definition: cpu.h:348
bool HasNEON()
Determine if an ARM processor has Advanced SIMD available.
Definition: cpu.h:329