Crypto++  8.8
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
Library configuration file.
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
Crypto++ library namespace.
Precompiled header file.
Support functions for PowerPC and vector operations.
__vector unsigned char uint8x16_p
Vector of 8-bit elements.
Definition: ppc_simd.h:192
T1 VecXor(const T1 vec1, const T2 vec2)
XOR two vectors.
Definition: ppc_simd.h:1414
Common C++ header files.