Crypto++ 8.2
Free C&
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 return false;
62
63 if (setjmp(s_jmpSIGILL))
64 result = false;
65 else
66 {
67 CRYPTOPP_ALIGN_DATA(16)
68 const byte b1[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
69 CRYPTOPP_ALIGN_DATA(16)
70 const byte b2[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
71 CRYPTOPP_ALIGN_DATA(16) byte b3[16];
72
73 // Specifically call the Altivec loads and stores
74 const uint8x16_p v1 = (uint8x16_p)vec_ld(0, (byte*)b1);
75 const uint8x16_p v2 = (uint8x16_p)vec_ld(0, (byte*)b2);
76 const uint8x16_p v3 = (uint8x16_p)VecXor(v1, v2);
77 vec_st(v3, 0, b3);
78
79 result = (0 == std::memcmp(b2, b3, 16));
80 }
81
82 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
83 signal(SIGILL, oldHandler);
84 return result;
85# endif
86#else
87 return false;
88#endif // CRYPTOPP_ALTIVEC_AVAILABLE
89}
90
91# endif // CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
92
93NAMESPACE_END
Library configuration file.
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:119
T1 VecXor(const T1 vec1, const T2 vec2)
XOR two vectors.
Definition: ppc_simd.h:916
Common C++ header files.