summaryrefslogtreecommitdiff
path: root/power7_ppc.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2022-03-29 22:02:19 -0400
committerJeffrey Walton <noloader@gmail.com>2022-03-29 22:02:19 -0400
commit48377cac698b82b85f3beb1c6dbbd135cdfd49f6 (patch)
tree1f560657f6a88291bc85023a2f8e8503dcfc25d0 /power7_ppc.cpp
parentab7f885c9fd75178a229fc8e04f99b35bae2fe79 (diff)
downloadcryptopp-git-48377cac698b82b85f3beb1c6dbbd135cdfd49f6.tar.gz
Rename PowerPC specific files
This will allow us to filter-out some files more easily
Diffstat (limited to 'power7_ppc.cpp')
-rw-r--r--power7_ppc.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/power7_ppc.cpp b/power7_ppc.cpp
new file mode 100644
index 00000000..84a7275a
--- /dev/null
+++ b/power7_ppc.cpp
@@ -0,0 +1,93 @@
+// ppc_power7.cpp - written and placed in the public domain by
+// Jeffrey Walton, Uri Blumenthal and Marcel Raad.
+//
+// This source file uses intrinsics and built-ins to gain access to
+// Power7 instructions. A separate source file is needed because
+// additional CXXFLAGS are required to enable the appropriate
+// instructions sets in some build configurations.
+
+#include "pch.h"
+#include "config.h"
+
+#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
+# include <signal.h>
+# include <setjmp.h>
+#endif
+
+#if defined(__ALTIVEC__) || defined(_ARCH_PWR7)
+# include "ppc_simd.h"
+#endif
+
+// Squash MS LNK4221 and libtool warnings
+extern const char PPC_POWER7_FNAME[] = __FILE__;
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// ************************* Feature Probes ************************* //
+
+#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
+extern "C" {
+ typedef void (*SigHandler)(int);
+
+ static jmp_buf s_jmpSIGILL;
+ static void SigIllHandler(int)
+ {
+ longjmp(s_jmpSIGILL, 1);
+ }
+}
+#endif // CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
+
+#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
+bool CPU_ProbePower7()
+{
+#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
+ return false;
+#elif defined(CRYPTOPP_POWER7_AVAILABLE)
+# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
+
+ // longjmp and clobber warnings. Volatile is required.
+ // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
+ volatile int result = false;
+
+ volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler);
+ if (oldHandler == SIG_ERR)
+ return false;
+
+ volatile sigset_t oldMask;
+ if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask))
+ {
+ signal(SIGILL, oldHandler);
+ return false;
+ }
+
+ if (setjmp(s_jmpSIGILL))
+ result = false;
+ else
+ {
+ // POWER7 added unaligned loads and store operations
+ byte b1[19] = {255, 255, 255, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, b2[17];
+
+ // See comments in ppc_simd.h for some of these defines.
+ #if defined(_AIX) && defined(_ARCH_PWR7) && ((__xlC__ & 0xff00) == 0x0c00)
+ vec_xstw4(vec_xlw4(0, (unsigned int*)(b1+3)), 0, (unsigned int*)(b2+1));
+ result = (0 == std::memcmp(b1+3, b2+1, 16));
+ #elif defined(_ARCH_PWR7) && defined(__VSX__)
+ vec_xst(vec_xl(0, (unsigned int*)(b1+3)), 0, (unsigned int*)(b2+1));
+ result = (0 == std::memcmp(b1+3, b2+1, 16));
+ #else
+ result = false;
+ #endif
+ }
+
+ sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
+ signal(SIGILL, oldHandler);
+ return result;
+# endif
+#else
+ return false;
+#endif // _ARCH_PWR7
+}
+
+#endif // PPC32 or PPC64
+
+NAMESPACE_END