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 |