Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/cpu.h
Line
Count
Source (jump to first uncovered line)
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 receives
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)
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(CRYPTOPP_GCC_VERSION)
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
// Thanks to v1ne at https://github.com/weidai11/cryptopp/pull/1133
64
#define PERCENT_PASTE(x) "%" #x
65
#define PERCENT_REG(x) PERCENT_PASTE(x)
66
67
#ifdef CRYPTOPP_GENERATE_X64_MASM
68
69
#define CRYPTOPP_X86_ASM_AVAILABLE
70
#define CRYPTOPP_BOOL_X64 1
71
#define CRYPTOPP_SSE2_ASM_AVAILABLE 1
72
#define NAMESPACE_END
73
74
#else
75
76
NAMESPACE_BEGIN(CryptoPP)
77
78
// ***************************** IA-32 ***************************** //
79
80
#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_DOXYGEN_PROCESSING
81
82
#define CRYPTOPP_CPUID_AVAILABLE 1
83
84
// Hide from Doxygen
85
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
86
// These should not be used directly
87
extern CRYPTOPP_DLL bool g_x86DetectionDone;
88
extern CRYPTOPP_DLL bool g_hasSSE2;
89
extern CRYPTOPP_DLL bool g_hasSSSE3;
90
extern CRYPTOPP_DLL bool g_hasSSE41;
91
extern CRYPTOPP_DLL bool g_hasSSE42;
92
extern CRYPTOPP_DLL bool g_hasMOVBE;
93
extern CRYPTOPP_DLL bool g_hasAESNI;
94
extern CRYPTOPP_DLL bool g_hasCLMUL;
95
extern CRYPTOPP_DLL bool g_hasAVX;
96
extern CRYPTOPP_DLL bool g_hasAVX2;
97
extern CRYPTOPP_DLL bool g_hasSHA;
98
extern CRYPTOPP_DLL bool g_hasADX;
99
extern CRYPTOPP_DLL bool g_isP4;
100
extern CRYPTOPP_DLL bool g_hasRDRAND;
101
extern CRYPTOPP_DLL bool g_hasRDSEED;
102
extern CRYPTOPP_DLL bool g_hasPadlockRNG;
103
extern CRYPTOPP_DLL bool g_hasPadlockACE;
104
extern CRYPTOPP_DLL bool g_hasPadlockACE2;
105
extern CRYPTOPP_DLL bool g_hasPadlockPHE;
106
extern CRYPTOPP_DLL bool g_hasPadlockPMM;
107
extern CRYPTOPP_DLL word32 g_cacheLineSize;
108
109
CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
110
CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 func, word32 subfunc, word32 output[4]);
111
#endif // CRYPTOPP_DOXYGEN_PROCESSING
112
113
/// \name IA-32 CPU FEATURES
114
//@{
115
116
/// \brief Determine SSE2 availability
117
/// \return true if SSE2 is determined to be available, false otherwise
118
/// \details MMX, SSE and SSE2 are core processor features for x86_64, and
119
///  the function return value is based on OSXSAVE. On i386 both
120
///  SSE2 and OSXSAVE are used for the return value.
121
/// \note This function is only available on Intel IA-32 platforms
122
inline bool HasSSE2()
123
98
{
124
98
#if (CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_SSE2_INTRIN_AVAILABLE)
125
98
  if (!g_x86DetectionDone)
126
0
    DetectX86Features();
127
98
  return g_hasSSE2;
128
#else
129
  return false;
130
#endif
131
98
}
132
133
/// \brief Determine SSSE3 availability
134
/// \return true if SSSE3 is determined to be available, false otherwise
135
/// \details HasSSSE3() is a runtime check performed using CPUID
136
/// \note This function is only available on Intel IA-32 platforms
137
inline bool HasSSSE3()
138
28
{
139
28
#if CRYPTOPP_SSSE3_AVAILABLE
140
28
  if (!g_x86DetectionDone)
141
0
    DetectX86Features();
142
28
  return g_hasSSSE3;
143
#else
144
  return false;
145
#endif
146
28
}
147
148
/// \brief Determine SSE4.1 availability
149
/// \return true if SSE4.1 is determined to be available, false otherwise
150
/// \details HasSSE41() is a runtime check performed using CPUID
151
/// \note This function is only available on Intel IA-32 platforms
152
inline bool HasSSE41()
153
684k
{
154
684k
#if CRYPTOPP_SSE41_AVAILABLE
155
684k
  if (!g_x86DetectionDone)
156
0
    DetectX86Features();
157
684k
  return g_hasSSE41;
158
#else
159
  return false;
160
#endif
161
684k
}
162
163
/// \brief Determine SSE4.2 availability
164
/// \return true if SSE4.2 is determined to be available, false otherwise
165
/// \details HasSSE42() is a runtime check performed using CPUID
166
/// \note This function is only available on Intel IA-32 platforms
167
inline bool HasSSE42()
168
0
{
169
0
#if CRYPTOPP_SSE42_AVAILABLE
170
0
  if (!g_x86DetectionDone)
171
0
    DetectX86Features();
172
0
  return g_hasSSE42;
173
0
#else
174
0
  return false;
175
0
#endif
176
0
}
177
178
/// \brief Determine MOVBE availability
179
/// \return true if MOVBE is determined to be available, false otherwise
180
/// \details HasMOVBE() is a runtime check performed using CPUID
181
/// \since Crypto++ 8.3
182
/// \note This function is only available on Intel IA-32 platforms
183
inline bool HasMOVBE()
184
0
{
185
0
#if CRYPTOPP_SSE42_AVAILABLE
186
0
  if (!g_x86DetectionDone)
187
0
    DetectX86Features();
188
0
  return g_hasMOVBE;
189
0
#else
190
0
  return false;
191
0
#endif
192
0
}
193
194
/// \brief Determine AES-NI availability
195
/// \return true if AES-NI is determined to be available, false otherwise
196
/// \details HasAESNI() is a runtime check performed using CPUID
197
/// \since Crypto++ 5.6.1
198
/// \note This function is only available on Intel IA-32 platforms
199
inline bool HasAESNI()
200
1.09k
{
201
1.09k
#if CRYPTOPP_AESNI_AVAILABLE
202
1.09k
  if (!g_x86DetectionDone)
203
0
    DetectX86Features();
204
1.09k
  return g_hasAESNI;
205
#else
206
  return false;
207
#endif
208
1.09k
}
209
210
/// \brief Determine Carryless Multiply availability
211
/// \return true if pclmulqdq is determined to be available, false otherwise
212
/// \details HasCLMUL() is a runtime check performed using CPUID
213
/// \since Crypto++ 5.6.1
214
/// \note This function is only available on Intel IA-32 platforms
215
inline bool HasCLMUL()
216
750
{
217
750
#if CRYPTOPP_CLMUL_AVAILABLE
218
750
  if (!g_x86DetectionDone)
219
0
    DetectX86Features();
220
750
  return g_hasCLMUL;
221
#else
222
  return false;
223
#endif
224
750
}
225
226
/// \brief Determine SHA availability
227
/// \return true if SHA is determined to be available, false otherwise
228
/// \details HasSHA() is a runtime check performed using CPUID
229
/// \since Crypto++ 6.0
230
/// \note This function is only available on Intel IA-32 platforms
231
inline bool HasSHA()
232
251k
{
233
251k
#if CRYPTOPP_SHANI_AVAILABLE
234
251k
  if (!g_x86DetectionDone)
235
0
    DetectX86Features();
236
251k
  return g_hasSHA;
237
#else
238
  return false;
239
#endif
240
251k
}
241
242
/// \brief Determine ADX availability
243
/// \return true if ADX is determined to be available, false otherwise
244
/// \details HasADX() is a runtime check performed using CPUID
245
/// \since Crypto++ 7.0
246
/// \note This function is only available on Intel IA-32 platforms
247
inline bool HasADX()
248
0
{
249
0
#if CRYPTOPP_ADX_AVAILABLE
250
0
  if (!g_x86DetectionDone)
251
0
    DetectX86Features();
252
0
  return g_hasADX;
253
0
#else
254
0
  return false;
255
0
#endif
256
0
}
257
258
/// \brief Determine AVX availability
259
/// \return true if AVX is determined to be available, false otherwise
260
/// \details HasAVX() is a runtime check performed using CPUID
261
/// \since Crypto++ 8.0
262
/// \note This function is only available on Intel IA-32 platforms
263
inline bool HasAVX()
264
0
{
265
0
#if CRYPTOPP_AVX_AVAILABLE
266
0
  if (!g_x86DetectionDone)
267
0
    DetectX86Features();
268
0
  return g_hasAVX;
269
0
#else
270
0
  return false;
271
0
#endif
272
0
}
273
274
/// \brief Determine AVX2 availability
275
/// \return true if AVX2 is determined to be available, false otherwise
276
/// \details HasAVX2() is a runtime check performed using CPUID
277
/// \since Crypto++ 8.0
278
/// \note This function is only available on Intel IA-32 platforms
279
inline bool HasAVX2()
280
226k
{
281
226k
#if CRYPTOPP_AVX2_AVAILABLE
282
226k
  if (!g_x86DetectionDone)
283
0
    DetectX86Features();
284
226k
  return g_hasAVX2;
285
#else
286
  return false;
287
#endif
288
226k
}
289
290
/// \brief Determine RDRAND availability
291
/// \return true if RDRAND is determined to be available, false otherwise
292
/// \details HasRDRAND() is a runtime check performed using CPUID
293
/// \note This function is only available on Intel IA-32 platforms
294
inline bool HasRDRAND()
295
0
{
296
0
#if CRYPTOPP_RDRAND_AVAILABLE
297
0
  if (!g_x86DetectionDone)
298
0
    DetectX86Features();
299
0
  return g_hasRDRAND;
300
0
#else
301
0
  return false;
302
0
#endif
303
0
}
304
305
/// \brief Determine RDSEED availability
306
/// \return true if RDSEED is determined to be available, false otherwise
307
/// \details HasRDSEED() is a runtime check performed using CPUID
308
/// \note This function is only available on Intel IA-32 platforms
309
inline bool HasRDSEED()
310
0
{
311
0
#if CRYPTOPP_RDSEED_AVAILABLE
312
0
  if (!g_x86DetectionDone)
313
0
    DetectX86Features();
314
0
  return g_hasRDSEED;
315
0
#else
316
0
  return false;
317
0
#endif
318
0
}
319
320
/// \brief Determine Padlock RNG availability
321
/// \return true if VIA Padlock RNG is determined to be available, false otherwise
322
/// \details HasPadlockRNG() is a runtime check performed using CPUID
323
/// \note This function is only available on Intel IA-32 platforms
324
inline bool HasPadlockRNG()
325
0
{
326
0
#if CRYPTOPP_PADLOCK_RNG_AVAILABLE
327
0
  if (!g_x86DetectionDone)
328
0
    DetectX86Features();
329
0
  return g_hasPadlockRNG;
330
0
#else
331
0
  return false;
332
0
#endif
333
0
}
334
335
/// \brief Determine Padlock ACE availability
336
/// \return true if VIA Padlock ACE is determined to be available, false otherwise
337
/// \details HasPadlockACE() is a runtime check performed using CPUID
338
/// \note This function is only available on Intel IA-32 platforms
339
inline bool HasPadlockACE()
340
0
{
341
0
#if CRYPTOPP_PADLOCK_ACE_AVAILABLE
342
0
  if (!g_x86DetectionDone)
343
0
    DetectX86Features();
344
0
  return g_hasPadlockACE;
345
0
#else
346
0
  return false;
347
0
#endif
348
0
}
349
350
/// \brief Determine Padlock ACE2 availability
351
/// \return true if VIA Padlock ACE2 is determined to be available, false otherwise
352
/// \details HasPadlockACE2() is a runtime check performed using CPUID
353
/// \note This function is only available on Intel IA-32 platforms
354
inline bool HasPadlockACE2()
355
0
{
356
0
#if CRYPTOPP_PADLOCK_ACE2_AVAILABLE
357
0
  if (!g_x86DetectionDone)
358
0
    DetectX86Features();
359
0
  return g_hasPadlockACE2;
360
0
#else
361
0
  return false;
362
0
#endif
363
0
}
364
365
/// \brief Determine Padlock PHE availability
366
/// \return true if VIA Padlock PHE is determined to be available, false otherwise
367
/// \details HasPadlockPHE() is a runtime check performed using CPUID
368
/// \note This function is only available on Intel IA-32 platforms
369
inline bool HasPadlockPHE()
370
0
{
371
0
#if CRYPTOPP_PADLOCK_PHE_AVAILABLE
372
0
  if (!g_x86DetectionDone)
373
0
    DetectX86Features();
374
0
  return g_hasPadlockPHE;
375
0
#else
376
0
  return false;
377
0
#endif
378
0
}
379
380
/// \brief Determine Padlock PMM availability
381
/// \return true if VIA Padlock PMM is determined to be available, false otherwise
382
/// \details HasPadlockPMM() is a runtime check performed using CPUID
383
/// \note This function is only available on Intel IA-32 platforms
384
inline bool HasPadlockPMM()
385
0
{
386
0
#if CRYPTOPP_PADLOCK_PMM_AVAILABLE
387
0
  if (!g_x86DetectionDone)
388
0
    DetectX86Features();
389
0
  return g_hasPadlockPMM;
390
0
#else
391
0
  return false;
392
0
#endif
393
0
}
394
395
/// \brief Determine if the CPU is an Intel P4
396
/// \return true if the CPU is a P4, false otherwise
397
/// \details IsP4() is a runtime check performed using CPUID
398
/// \note This function is only available on Intel IA-32 platforms
399
inline bool IsP4()
400
0
{
401
0
  if (!g_x86DetectionDone)
402
0
    DetectX86Features();
403
0
  return g_isP4;
404
0
}
405
406
/// \brief Provides the cache line size
407
/// \return lower bound on the size of a cache line in bytes, if available
408
/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
409
///  is available. If the value is not available at runtime, then 32 is returned for a 32-bit
410
///  processor and 64 is returned for a 64-bit processor.
411
/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
412
///  and AIX also makes the value available to user space and it is also usually accurate. The
413
///  ARM processor equivalent is a privileged instruction, so a compile time value is returned.
414
inline int GetCacheLineSize()
415
2.11k
{
416
2.11k
  if (!g_x86DetectionDone)
417
0
    DetectX86Features();
418
2.11k
  return g_cacheLineSize;
419
2.11k
}
420
//@}
421
422
#endif  // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
423
424
// ***************************** ARM-32, Aarch32 and Aarch64 ***************************** //
425
426
#if CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8 || CRYPTOPP_DOXYGEN_PROCESSING
427
428
// Hide from Doxygen
429
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
430
extern bool g_ArmDetectionDone;
431
extern bool g_hasARMv7;
432
extern bool g_hasNEON;
433
extern bool g_hasPMULL;
434
extern bool g_hasCRC32;
435
extern bool g_hasAES;
436
extern bool g_hasSHA1;
437
extern bool g_hasSHA2;
438
extern bool g_hasSHA512;
439
extern bool g_hasSHA3;
440
extern bool g_hasSM3;
441
extern bool g_hasSM4;
442
void CRYPTOPP_API DetectArmFeatures();
443
#endif  // CRYPTOPP_DOXYGEN_PROCESSING
444
445
/// \name ARM A-32, Aarch32 and AArch64 CPU FEATURES
446
//@{
447
448
/// \brief Determine if an ARM processor is ARMv7 or above
449
/// \return true if the hardware is ARMv7 or above, false otherwise.
450
/// \details Some AES code requires ARMv7 or above
451
/// \since Crypto++ 8.0
452
/// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
453
inline bool HasARMv7()
454
{
455
  // ASIMD is a core feature on Aarch32 and Aarch64 like SSE2 is a core feature on x86_64
456
#if defined(__aarch32__) || defined(__aarch64__)
457
  return true;
458
#else
459
  if (!g_ArmDetectionDone)
460
    DetectArmFeatures();
461
  return g_hasARMv7;
462
#endif
463
}
464
465
/// \brief Determine if an ARM processor has Advanced SIMD available
466
/// \return true if the hardware is capable of Advanced SIMD at runtime, false otherwise.
467
/// \details Advanced SIMD instructions are available under most ARMv7, Aarch32 and Aarch64.
468
/// \details Runtime support requires compile time support. When compiling with GCC, you may
469
///  need to compile with <tt>-mfpu=neon</tt> (32-bit) or <tt>-march=armv8-a</tt>
470
///  (64-bit). Also see ARM's <tt>__ARM_NEON</tt> preprocessor macro.
471
/// \since Crypto++ 5.6.4
472
/// \note This function is only available on ARM-32, Aarch32 and Aarch64 platforms
473
inline bool HasNEON()
474
{
475
  // ASIMD is a core feature on Aarch32 and Aarch64 like SSE2 is a core feature on x86_64
476
#if defined(CRYPTOPP_ARM_ASIMD_AVAILABLE)
477
  return true;
478
#elif defined(CRYPTOPP_ARM_NEON_AVAILABLE)
479
  if (!g_ArmDetectionDone)
480
    DetectArmFeatures();
481
  return g_hasNEON;
482
#else
483
  return false;
484
#endif
485
}
486
487
/// \brief Determine if an ARM processor has CRC32 available
488
/// \return true if the hardware is capable of CRC32 at runtime, false otherwise.
489
/// \details CRC32 instructions provide access to the processor's CRC-32 and CRC-32C
490
///  instructions. They are provided by ARM C Language Extensions 2.0 (ACLE 2.0) and
491
///  available under Aarch32 and Aarch64.
492
/// \details Runtime support requires compile time support. When compiling with GCC,
493
///  you may need to compile with <tt>-march=armv8-a+crc</tt>; while Apple requires
494
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRC32</tt> preprocessor macro.
495
/// \since Crypto++ 5.6.4
496
/// \note This function is only available on Aarch32 and Aarch64 platforms
497
inline bool HasCRC32()
498
{
499
#if defined(CRYPTOPP_ARM_CRC32_AVAILABLE)
500
  if (!g_ArmDetectionDone)
501
    DetectArmFeatures();
502
  return g_hasCRC32;
503
#else
504
  return false;
505
#endif
506
}
507
508
/// \brief Determine if an ARM processor has AES available
509
/// \return true if the hardware is capable of AES at runtime, false otherwise.
510
/// \details AES is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
511
///  accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
512
/// \details Runtime support requires compile time support. When compiling with GCC, you may
513
///  need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
514
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
515
/// \since Crypto++ 5.6.4
516
/// \note This function is only available on Aarch32 and Aarch64 platforms
517
inline bool HasAES()
518
{
519
#if defined(CRYPTOPP_ARM_AES_AVAILABLE)
520
  if (!g_ArmDetectionDone)
521
    DetectArmFeatures();
522
  return g_hasAES;
523
#else
524
  return false;
525
#endif
526
}
527
528
/// \brief Determine if an ARM processor provides Polynomial Multiplication
529
/// \return true if the hardware is capable of polynomial multiplications at runtime,
530
///  false otherwise.
531
/// \details The multiplication instructions are available under Aarch32 and Aarch64.
532
/// \details Runtime support requires compile time support. When compiling with GCC,
533
///  you may need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
534
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
535
/// \since Crypto++ 5.6.4
536
/// \note This function is only available on Aarch32 and Aarch64 platforms
537
inline bool HasPMULL()
538
{
539
#if defined(CRYPTOPP_ARM_PMULL_AVAILABLE)
540
  if (!g_ArmDetectionDone)
541
    DetectArmFeatures();
542
  return g_hasPMULL;
543
#else
544
  return false;
545
#endif
546
}
547
548
/// \brief Determine if an ARM processor has SHA1 available
549
/// \return true if the hardware is capable of SHA1 at runtime, false otherwise.
550
/// \details SHA1 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
551
///  accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
552
/// \details Runtime support requires compile time support. When compiling with GCC, you may
553
///  need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
554
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
555
/// \since Crypto++ 5.6.4
556
/// \note This function is only available on Aarch32 and Aarch64 platforms
557
inline bool HasSHA1()
558
{
559
#if defined(CRYPTOPP_ARM_SHA1_AVAILABLE)
560
  if (!g_ArmDetectionDone)
561
    DetectArmFeatures();
562
  return g_hasSHA1;
563
#else
564
  return false;
565
#endif
566
}
567
568
/// \brief Determine if an ARM processor has SHA256 available
569
/// \return true if the hardware is capable of SHA256 at runtime, false otherwise.
570
/// \details SHA256 is part of the optional Crypto extensions on Aarch32 and Aarch64. They are
571
///  accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
572
/// \details Runtime support requires compile time support. When compiling with GCC, you may
573
///  need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
574
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
575
/// \since Crypto++ 5.6.4
576
/// \note This function is only available on Aarch32 and Aarch64 platforms
577
inline bool HasSHA2()
578
{
579
#if defined(CRYPTOPP_ARM_SHA2_AVAILABLE)
580
  if (!g_ArmDetectionDone)
581
    DetectArmFeatures();
582
  return g_hasSHA2;
583
#else
584
  return false;
585
#endif
586
}
587
588
/// \brief Determine if an ARM processor has SHA3 available
589
/// \return true if the hardware is capable of SHA3 at runtime, false otherwise.
590
/// \details SHA3 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They
591
///  are accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
592
/// \details Runtime support requires compile time support. When compiling with GCC, you
593
///  may need to compile with <tt>-march=armv8.2-a+crypto</tt>; while Apple requires
594
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
595
/// \since Crypto++ 8.0
596
/// \note This function is only available on Aarch32 and Aarch64 platforms
597
inline bool HasSHA3()
598
{
599
#if defined(CRYPTOPP_ARM_SHA3_AVAILABLE)
600
  if (!g_ArmDetectionDone)
601
    DetectArmFeatures();
602
  return g_hasSHA3;
603
#else
604
  return false;
605
#endif
606
}
607
608
/// \brief Determine if an ARM processor has SHA512 available
609
/// \return true if the hardware is capable of SHA512 at runtime, false otherwise.
610
/// \details SHA512 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They
611
///  are accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
612
/// \details Runtime support requires compile time support. When compiling with GCC, you
613
///  may need to compile with <tt>-march=armv8.2-a+crypto</tt>; while Apple requires
614
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
615
/// \since Crypto++ 8.0
616
/// \note This function is only available on Aarch32 and Aarch64 platforms
617
inline bool HasSHA512()
618
{
619
#if defined(CRYPTOPP_ARM_SHA512_AVAILABLE)
620
  if (!g_ArmDetectionDone)
621
    DetectArmFeatures();
622
  return g_hasSHA512;
623
#else
624
  return false;
625
#endif
626
}
627
628
/// \brief Determine if an ARM processor has SM3 available
629
/// \return true if the hardware is capable of SM3 at runtime, false otherwise.
630
/// \details SM3 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They
631
///  are accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
632
/// \details Runtime support requires compile time support. When compiling with GCC, you
633
///  may need to compile with <tt>-march=armv8.2-a+crypto</tt>; while Apple requires
634
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
635
/// \since Crypto++ 8.0
636
/// \note This function is only available on Aarch32 and Aarch64 platforms
637
inline bool HasSM3()
638
{
639
#if defined(CRYPTOPP_ARM_SM3_AVAILABLE)
640
  if (!g_ArmDetectionDone)
641
    DetectArmFeatures();
642
  return g_hasSM3;
643
#else
644
  return false;
645
#endif
646
}
647
648
/// \brief Determine if an ARM processor has SM4 available
649
/// \return true if the hardware is capable of SM4 at runtime, false otherwise.
650
/// \details SM4 is part of the ARMv8.2 Crypto extensions on Aarch32 and Aarch64. They
651
///  are accessed using ARM C Language Extensions 2.0 (ACLE 2.0).
652
/// \details Runtime support requires compile time support. When compiling with GCC, you
653
///  may need to compile with <tt>-march=armv8.2-a+crypto</tt>; while Apple requires
654
///  <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
655
/// \since Crypto++ 8.0
656
/// \note This function is only available on Aarch32 and Aarch64 platforms
657
inline bool HasSM4()
658
{
659
#if defined(CRYPTOPP_ARM_SM4_AVAILABLE)
660
  if (!g_ArmDetectionDone)
661
    DetectArmFeatures();
662
  return g_hasSM4;
663
#else
664
  return false;
665
#endif
666
}
667
668
//@}
669
670
#endif  // CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8
671
672
// ***************************** PowerPC ***************************** //
673
674
#if CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64 || CRYPTOPP_DOXYGEN_PROCESSING
675
676
// Hide from Doxygen
677
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
678
extern bool g_PowerPcDetectionDone;
679
extern bool g_hasAltivec;
680
extern bool g_hasPower7;
681
extern bool g_hasPower8;
682
extern bool g_hasPower9;
683
extern bool g_hasAES;
684
extern bool g_hasPMULL;
685
extern bool g_hasSHA256;
686
extern bool g_hasSHA512;
687
extern bool g_hasDARN;
688
extern word32 g_cacheLineSize;
689
void CRYPTOPP_API DetectPowerPcFeatures();
690
#endif  // CRYPTOPP_DOXYGEN_PROCESSING
691
692
/// \name POWERPC CPU FEATURES
693
//@{
694
695
/// \brief Determine if a PowerPC processor has Altivec available
696
/// \return true if the hardware is capable of Altivec at runtime, false otherwise.
697
/// \details Altivec instructions are available on modern PowerPCs.
698
/// \details Runtime support requires compile time support. When compiling with GCC, you may
699
///  need to compile with <tt>-mcpu=power4</tt>; while IBM XL C/C++ compilers require
700
///  <tt>-qarch=pwr6 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
701
/// \note This function is only available on PowerPC and PowerPC-64 platforms
702
inline bool HasAltivec()
703
{
704
#if CRYPTOPP_ALTIVEC_AVAILABLE
705
  if (!g_PowerPcDetectionDone)
706
    DetectPowerPcFeatures();
707
  return g_hasAltivec;
708
#else
709
  return false;
710
#endif
711
}
712
713
/// \brief Determine if a PowerPC processor has Power7 available
714
/// \return true if the hardware is capable of Power7 at runtime, false otherwise.
715
/// \details Runtime support requires compile time support. When compiling with GCC, you may
716
///  need to compile with <tt>-mcpu=power7</tt>; while IBM XL C/C++ compilers require
717
///  <tt>-qarch=pwr7 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
718
/// \note This function is only available on PowerPC and PowerPC-64 platforms
719
inline bool HasPower7()
720
{
721
#if CRYPTOPP_POWER7_AVAILABLE
722
  if (!g_PowerPcDetectionDone)
723
    DetectPowerPcFeatures();
724
  return g_hasPower7;
725
#else
726
  return false;
727
#endif
728
}
729
730
/// \brief Determine if a PowerPC processor has Power8 available
731
/// \return true if the hardware is capable of Power8 at runtime, false otherwise.
732
/// \details Runtime support requires compile time support. When compiling with GCC, you may
733
///  need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
734
///  <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
735
/// \note This function is only available on PowerPC and PowerPC-64 platforms
736
inline bool HasPower8()
737
{
738
#if CRYPTOPP_POWER8_AVAILABLE
739
  if (!g_PowerPcDetectionDone)
740
    DetectPowerPcFeatures();
741
  return g_hasPower8;
742
#else
743
  return false;
744
#endif
745
}
746
747
/// \brief Determine if a PowerPC processor has Power9 available
748
/// \return true if the hardware is capable of Power9 at runtime, false otherwise.
749
/// \details Runtime support requires compile time support. When compiling with GCC, you may
750
///  need to compile with <tt>-mcpu=power9</tt>; while IBM XL C/C++ compilers require
751
///  <tt>-qarch=pwr9 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
752
/// \note This function is only available on PowerPC and PowerPC-64 platforms
753
inline bool HasPower9()
754
{
755
#if CRYPTOPP_POWER9_AVAILABLE
756
  if (!g_PowerPcDetectionDone)
757
    DetectPowerPcFeatures();
758
  return g_hasPower9;
759
#else
760
  return false;
761
#endif
762
}
763
764
/// \brief Determine if a PowerPC processor has AES available
765
/// \return true if the hardware is capable of AES at runtime, false otherwise.
766
/// \details AES is part of the in-crypto extensions on Power8 and Power9.
767
/// \details Runtime support requires compile time support. When compiling with GCC, you may
768
///  need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
769
///  <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
770
/// \note This function is only available on PowerPC and PowerPC-64 platforms
771
inline bool HasAES()
772
{
773
#if CRYPTOPP_POWER8_AES_AVAILABLE
774
  if (!g_PowerPcDetectionDone)
775
    DetectPowerPcFeatures();
776
  return g_hasAES;
777
#else
778
  return false;
779
#endif
780
}
781
782
/// \brief Determine if a PowerPC processor has Polynomial Multiply available
783
/// \return true if the hardware is capable of PMULL at runtime, false otherwise.
784
/// \details PMULL is part of the in-crypto extensions on Power8 and Power9.
785
/// \details Runtime support requires compile time support. When compiling with GCC, you may
786
///  need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
787
///  <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
788
/// \note This function is only available on PowerPC and PowerPC-64 platforms
789
inline bool HasPMULL()
790
{
791
#if CRYPTOPP_POWER8_VMULL_AVAILABLE
792
  if (!g_PowerPcDetectionDone)
793
    DetectPowerPcFeatures();
794
  return g_hasPMULL;
795
#else
796
  return false;
797
#endif
798
}
799
800
/// \brief Determine if a PowerPC processor has SHA256 available
801
/// \return true if the hardware is capable of SHA256 at runtime, false otherwise.
802
/// \details SHA is part of the in-crypto extensions on Power8 and Power9.
803
/// \details Runtime support requires compile time support. When compiling with GCC, you may
804
///  need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
805
///  <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
806
/// \note This function is only available on PowerPC and PowerPC-64 platforms
807
inline bool HasSHA256()
808
{
809
#if CRYPTOPP_POWER8_SHA_AVAILABLE
810
  if (!g_PowerPcDetectionDone)
811
    DetectPowerPcFeatures();
812
  return g_hasSHA256;
813
#else
814
  return false;
815
#endif
816
}
817
818
/// \brief Determine if a PowerPC processor has SHA512 available
819
/// \return true if the hardware is capable of SHA512 at runtime, false otherwise.
820
/// \details SHA is part of the in-crypto extensions on Power8 and Power9.
821
/// \details Runtime support requires compile time support. When compiling with GCC, you may
822
///  need to compile with <tt>-mcpu=power8</tt>; while IBM XL C/C++ compilers require
823
///  <tt>-qarch=pwr8 -qaltivec</tt>. Also see PowerPC's <tt>__CRYPTO</tt> preprocessor macro.
824
/// \note This function is only available on PowerPC and PowerPC-64 platforms
825
inline bool HasSHA512()
826
{
827
#if CRYPTOPP_POWER8_SHA_AVAILABLE
828
  if (!g_PowerPcDetectionDone)
829
    DetectPowerPcFeatures();
830
  return g_hasSHA512;
831
#else
832
  return false;
833
#endif
834
}
835
836
/// \brief Determine if a PowerPC processor has DARN available
837
/// \return true if the hardware is capable of DARN at runtime, false otherwise.
838
/// \details Runtime support requires compile time support. When compiling with GCC, you may
839
///  need to compile with <tt>-mcpu=power9</tt>; while IBM XL C/C++ compilers require
840
///  <tt>-qarch=pwr9 -qaltivec</tt>. Also see PowerPC's <tt>_ALTIVEC_</tt> preprocessor macro.
841
/// \note This function is only available on PowerPC and PowerPC-64 platforms
842
inline bool HasDARN()
843
{
844
#if CRYPTOPP_POWER9_AVAILABLE
845
  if (!g_PowerPcDetectionDone)
846
    DetectPowerPcFeatures();
847
  // see comments in cpu.cpp
848
#  if defined(__ibmxl__) && defined(__linux__)
849
  return false;
850
#  else
851
  return g_hasDARN;
852
#  endif
853
#else
854
  return false;
855
#endif
856
}
857
858
/// \brief Provides the cache line size
859
/// \return lower bound on the size of a cache line in bytes, if available
860
/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
861
///  is available. If the value is not available at runtime, then 32 is returned for a 32-bit
862
///  processor and 64 is returned for a 64-bit processor.
863
/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
864
///  and AIX also makes the value available to user space and it is also usually accurate. The
865
///  ARM processor equivalent is a privileged instruction, so a compile time value is returned.
866
inline int GetCacheLineSize()
867
{
868
  if (!g_PowerPcDetectionDone)
869
    DetectPowerPcFeatures();
870
  return g_cacheLineSize;
871
}
872
873
//@}
874
875
#endif  // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
876
877
// ***************************** L1 cache line ***************************** //
878
879
// Non-Intel systems
880
#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
881
/// \brief Provides the cache line size
882
/// \return lower bound on the size of a cache line in bytes, if available
883
/// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it
884
///  is available. If the value is not available at runtime, then 32 is returned for a 32-bit
885
///  processor and 64 is returned for a 64-bit processor.
886
/// \details x86/x32/x64 uses CPUID to determine the value and it is usually accurate. PowerPC
887
///  and AIX also makes the value available to user space and it is also usually accurate. The
888
///  ARM processor equivalent is a privileged instruction, so a compile time value is returned.
889
inline int GetCacheLineSize()
890
{
891
  return CRYPTOPP_L1_CACHE_LINE_SIZE;
892
}
893
#endif  // Non-Intel systems
894
895
#endif  // CRYPTOPP_GENERATE_X64_MASM
896
897
// ***************************** Inline ASM Helper ***************************** //
898
899
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
900
901
#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
902
903
#ifdef CRYPTOPP_GENERATE_X64_MASM
904
  #define AS1(x) x*newline*
905
  #define AS2(x, y) x, y*newline*
906
  #define AS3(x, y, z) x, y, z*newline*
907
  #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline*
908
  #define ASL(x) label##x:*newline*
909
  #define ASJ(x, y, z) x label##y*newline*
910
  #define ASC(x, y) x label##y*newline*
911
  #define AS_HEX(y) 0##y##h
912
#elif defined(CRYPTOPP_MSC_VERSION) || defined(__BORLANDC__)
913
  #define AS1(x) __asm {x}
914
  #define AS2(x, y) __asm {x, y}
915
  #define AS3(x, y, z) __asm {x, y, z}
916
  #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)}
917
  #define ASL(x) __asm {label##x:}
918
  #define ASJ(x, y, z) __asm {x label##y}
919
  #define ASC(x, y) __asm {x label##y}
920
  #define CRYPTOPP_NAKED __declspec(naked)
921
  #define AS_HEX(y) 0x##y
922
#else
923
  // define these in two steps to allow arguments to be expanded
924
  #define GNU_AS1(x) #x ";" NEW_LINE
925
  #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE
926
  #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" NEW_LINE
927
  #define GNU_ASL(x) "\n" #x ":" NEW_LINE
928
// clang 5.0.0 and apple clang 9.0.0 don't support numerical backward jumps
929
#if (CRYPTOPP_LLVM_CLANG_VERSION >= 50000) || (CRYPTOPP_APPLE_CLANG_VERSION >= 90000)
930
  #define GNU_ASJ(x, y, z) ATT_PREFIX ";" NEW_LINE #x " " #y #z ";" NEW_LINE INTEL_PREFIX ";" NEW_LINE
931
#else
932
  #define GNU_ASJ(x, y, z) #x " " #y #z ";" NEW_LINE
933
#endif
934
  #define AS1(x) GNU_AS1(x)
935
  #define AS2(x, y) GNU_AS2(x, y)
936
  #define AS3(x, y, z) GNU_AS3(x, y, z)
937
  #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
938
  #define ASL(x) GNU_ASL(x)
939
  #define ASJ(x, y, z) GNU_ASJ(x, y, z)
940
  #define ASC(x, y) #x " " #y ";"
941
  #define CRYPTOPP_NAKED
942
  #define AS_HEX(y) 0x##y
943
#endif
944
945
#define IF0(y)
946
#define IF1(y) y
947
948
#ifdef CRYPTOPP_GENERATE_X64_MASM
949
#define ASM_MOD(x, y) ((x) MOD (y))
950
#define XMMWORD_PTR XMMWORD PTR
951
#else
952
// GNU assembler doesn't seem to have mod operator
953
#define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
954
// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM
955
#define XMMWORD_PTR
956
#endif
957
958
#if CRYPTOPP_BOOL_X86
959
  #define AS_REG_1 ecx
960
  #define AS_REG_2 edx
961
  #define AS_REG_3 esi
962
  #define AS_REG_4 edi
963
  #define AS_REG_5 eax
964
  #define AS_REG_6 ebx
965
  #define AS_REG_7 ebp
966
  #define AS_REG_1d ecx
967
  #define AS_REG_2d edx
968
  #define AS_REG_3d esi
969
  #define AS_REG_4d edi
970
  #define AS_REG_5d eax
971
  #define AS_REG_6d ebx
972
  #define AS_REG_7d ebp
973
  #define WORD_SZ 4
974
  #define WORD_REG(x) e##x
975
  #define WORD_PTR DWORD PTR
976
  #define AS_PUSH_IF86(x) AS1(push e##x)
977
  #define AS_POP_IF86(x) AS1(pop e##x)
978
  #define AS_JCXZ jecxz
979
#elif CRYPTOPP_BOOL_X32
980
  #define AS_REG_1 ecx
981
  #define AS_REG_2 edx
982
  #define AS_REG_3 r8d
983
  #define AS_REG_4 r9d
984
  #define AS_REG_5 eax
985
  #define AS_REG_6 r10d
986
  #define AS_REG_7 r11d
987
  #define AS_REG_1d ecx
988
  #define AS_REG_2d edx
989
  #define AS_REG_3d r8d
990
  #define AS_REG_4d r9d
991
  #define AS_REG_5d eax
992
  #define AS_REG_6d r10d
993
  #define AS_REG_7d r11d
994
  #define WORD_SZ 4
995
  #define WORD_REG(x) e##x
996
  #define WORD_PTR DWORD PTR
997
  #define AS_PUSH_IF86(x) AS1(push r##x)
998
  #define AS_POP_IF86(x) AS1(pop r##x)
999
  #define AS_JCXZ jecxz
1000
#elif CRYPTOPP_BOOL_X64
1001
  #ifdef CRYPTOPP_GENERATE_X64_MASM
1002
    #define AS_REG_1 rcx
1003
    #define AS_REG_2 rdx
1004
    #define AS_REG_3 r8
1005
    #define AS_REG_4 r9
1006
    #define AS_REG_5 rax
1007
    #define AS_REG_6 r10
1008
    #define AS_REG_7 r11
1009
    #define AS_REG_1d ecx
1010
    #define AS_REG_2d edx
1011
    #define AS_REG_3d r8d
1012
    #define AS_REG_4d r9d
1013
    #define AS_REG_5d eax
1014
    #define AS_REG_6d r10d
1015
    #define AS_REG_7d r11d
1016
  #else
1017
    #define AS_REG_1 rdi
1018
    #define AS_REG_2 rsi
1019
    #define AS_REG_3 rdx
1020
    #define AS_REG_4 rcx
1021
    #define AS_REG_5 r8
1022
    #define AS_REG_6 r9
1023
    #define AS_REG_7 r10
1024
    #define AS_REG_1d edi
1025
    #define AS_REG_2d esi
1026
    #define AS_REG_3d edx
1027
    #define AS_REG_4d ecx
1028
    #define AS_REG_5d r8d
1029
    #define AS_REG_6d r9d
1030
    #define AS_REG_7d r10d
1031
  #endif
1032
  #define WORD_SZ 8
1033
  #define WORD_REG(x) r##x
1034
  #define WORD_PTR QWORD PTR
1035
  #define AS_PUSH_IF86(x)
1036
  #define AS_POP_IF86(x)
1037
  #define AS_JCXZ jrcxz
1038
#endif
1039
1040
// helper macro for stream cipher output
1041
#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\
1042
  AS2(  test  inputPtr, inputPtr)\
1043
  ASC(  jz,   labelPrefix##3)\
1044
  AS2(  test  inputPtr, 15)\
1045
  ASC(  jnz,  labelPrefix##7)\
1046
  AS2(  pxor  xmm##x0, [inputPtr+p0*16])\
1047
  AS2(  pxor  xmm##x1, [inputPtr+p1*16])\
1048
  AS2(  pxor  xmm##x2, [inputPtr+p2*16])\
1049
  AS2(  pxor  xmm##x3, [inputPtr+p3*16])\
1050
  AS2(  add   inputPtr, increment*16)\
1051
  ASC(  jmp,  labelPrefix##3)\
1052
  ASL(labelPrefix##7)\
1053
  AS2(  movdqu  xmm##t, [inputPtr+p0*16])\
1054
  AS2(  pxor  xmm##x0, xmm##t)\
1055
  AS2(  movdqu  xmm##t, [inputPtr+p1*16])\
1056
  AS2(  pxor  xmm##x1, xmm##t)\
1057
  AS2(  movdqu  xmm##t, [inputPtr+p2*16])\
1058
  AS2(  pxor  xmm##x2, xmm##t)\
1059
  AS2(  movdqu  xmm##t, [inputPtr+p3*16])\
1060
  AS2(  pxor  xmm##x3, xmm##t)\
1061
  AS2(  add   inputPtr, increment*16)\
1062
  ASL(labelPrefix##3)\
1063
  AS2(  test  outputPtr, 15)\
1064
  ASC(  jnz,  labelPrefix##8)\
1065
  AS2(  movdqa  [outputPtr+p0*16], xmm##x0)\
1066
  AS2(  movdqa  [outputPtr+p1*16], xmm##x1)\
1067
  AS2(  movdqa  [outputPtr+p2*16], xmm##x2)\
1068
  AS2(  movdqa  [outputPtr+p3*16], xmm##x3)\
1069
  ASC(  jmp,  labelPrefix##9)\
1070
  ASL(labelPrefix##8)\
1071
  AS2(  movdqu  [outputPtr+p0*16], xmm##x0)\
1072
  AS2(  movdqu  [outputPtr+p1*16], xmm##x1)\
1073
  AS2(  movdqu  [outputPtr+p2*16], xmm##x2)\
1074
  AS2(  movdqu  [outputPtr+p3*16], xmm##x3)\
1075
  ASL(labelPrefix##9)\
1076
  AS2(  add   outputPtr, increment*16)
1077
1078
#endif  // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
1079
1080
#endif  // Not CRYPTOPP_DOXYGEN_PROCESSING
1081
1082
NAMESPACE_END
1083
1084
// Issue 340
1085
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
1086
# pragma GCC diagnostic pop
1087
#endif
1088
1089
#endif  // CRYPTOPP_CPU_H