Crypto++ 8.7
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
27extern const char PPC_SIMD_FNAME[] = __FILE__;
28
29NAMESPACE_BEGIN(CryptoPP)
30
31#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
32extern "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)
44bool 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
96NAMESPACE_END
Library configuration file.
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:56
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.