Crypto++ 8.6 Free C++ class library of cryptographic schemes

ppc_simd.cpp
1 // ppc_simd.cpp - written and placed in the public domain by
2 // Jeffrey Walton, Uri Blumenthal and Marcel Raad.
3 //
4 // This source file uses intrinsics to gain access to AltiVec,
5 // Power8 and in-core crypto instructions. A separate source file
6 // is needed because additional CXXFLAGS are required to enable the
7 // appropriate instructions sets in some build configurations.
8
9 #include "pch.h"
10 #include "config.h"
11 #include "stdcpp.h"
12
13 #if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
14 # include "ppc_simd.h"
15 #endif
16
17 #ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
18 # include <signal.h>
19 # include <setjmp.h>
20 #endif
21
22 #ifndef EXCEPTION_EXECUTE_HANDLER
23 # define EXCEPTION_EXECUTE_HANDLER 1
24 #endif
25
26 // Squash MS LNK4221 and libtool warnings
27 extern const char PPC_SIMD_FNAME[] = __FILE__;
28
29 NAMESPACE_BEGIN(CryptoPP)
30
31 #ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
32 extern "C" {
33 typedef void (*SigHandler)(int);
34
35 static jmp_buf s_jmpSIGILL;
36 static void SigIllHandler(int)
37 {
38 longjmp(s_jmpSIGILL, 1);
39 }
40 }
41 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
42
43 #if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
44 bool CPU_ProbeAltivec()
45 {
46 #if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
47 return false;
48 #elif (_ARCH_PWR3) && (CRYPTOPP_ALTIVEC_AVAILABLE)
49 # if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
50
51 // longjmp and clobber warnings. Volatile is required.
52 // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
53 volatile int result = true;
54
55 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler);
56 if (oldHandler == SIG_ERR)
57 return false;
58
59 volatile sigset_t oldMask;
60 if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask))
61 {
62 signal(SIGILL, oldHandler);
63 return false;
64 }
65
66 if (setjmp(s_jmpSIGILL))
67 result = false;
68 else
69 {
70 CRYPTOPP_ALIGN_DATA(16)
71 const byte b1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
72 CRYPTOPP_ALIGN_DATA(16)
73 const byte b2[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
74 CRYPTOPP_ALIGN_DATA(16) byte b3[16];
75
76 // Specifically call the Altivec loads and stores
77 const uint8x16_p v1 = (uint8x16_p)vec_ld(0, (byte*)b1);
78 const uint8x16_p v2 = (uint8x16_p)vec_ld(0, (byte*)b2);
79 const uint8x16_p v3 = (uint8x16_p)VecXor(v1, v2);
80 vec_st(v3, 0, b3);
81
82 result = (0 == std::memcmp(b2, b3, 16));
83 }
84
85 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
86 signal(SIGILL, oldHandler);
87 return result;
88 # endif
89 #else
90 return false;
91 #endif // CRYPTOPP_ALTIVEC_AVAILABLE
92 }
93
94 # endif // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
95
96 NAMESPACE_END
config.h
Library configuration file.
byte
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
CryptoPP
Crypto++ library namespace.
pch.h
Precompiled header file.
ppc_simd.h
Support functions for PowerPC and vector operations.
uint8x16_p
__vector unsigned char uint8x16_p
Vector of 8-bit elements.
Definition: ppc_simd.h:192
VecXor
T1 VecXor(const T1 vec1, const T2 vec2)
XOR two vectors.
Definition: ppc_simd.h:1414
stdcpp.h
Common C++ header files.