summaryrefslogtreecommitdiff
path: root/sse_simd.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2018-11-10 08:00:14 -0500
committerJeffrey Walton <noloader@gmail.com>2018-11-10 08:00:14 -0500
commit896225069db7f34e752dd7b7bb401052c6b7cb17 (patch)
tree8d4eabb2bd304b6fe9168aac8fdc28618f3212f8 /sse_simd.cpp
parent776a2195bd78c80130b1809b22a5e4d3aecb5b95 (diff)
downloadcryptopp-git-896225069db7f34e752dd7b7bb401052c6b7cb17.tar.gz
Rename files with dashes to underscores (GH #736)
Also see https://groups.google.com/forum/#!topic/cryptopp-users/HBz-6gZZFOA on the mailing list
Diffstat (limited to 'sse_simd.cpp')
-rw-r--r--sse_simd.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/sse_simd.cpp b/sse_simd.cpp
new file mode 100644
index 00000000..09484fa0
--- /dev/null
+++ b/sse_simd.cpp
@@ -0,0 +1,110 @@
+// sse_simd.cpp - written and placed in the public domain by
+// Jeffrey Walton, Uri Blumenthal and Marcel Raad.
+//
+// This source file uses intrinsics to gain access to SSE for CPU
+// feature testing. A separate source file is needed because additional
+// CXXFLAGS are required to enable the appropriate instructions set in
+// some build configurations.
+
+#include "pch.h"
+#include "config.h"
+#include "cpu.h"
+
+// Needed by MIPS for definition of NULL
+#include "stdcpp.h"
+
+#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
+# include <signal.h>
+# include <setjmp.h>
+#endif
+
+#ifndef EXCEPTION_EXECUTE_HANDLER
+# define EXCEPTION_EXECUTE_HANDLER 1
+#endif
+
+// Needed by SunCC and MSVC
+#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
+# include <emmintrin.h>
+#endif
+
+// Squash MS LNK4221 and libtool warnings
+extern const char SSE_SIMD_FNAME[] = __FILE__;
+
+NAMESPACE_BEGIN(CryptoPP)
+
+#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
+extern "C" {
+ typedef void (*SigHandler)(int);
+}
+
+extern "C"
+{
+ static jmp_buf s_jmpNoSSE2;
+ static void SigIllHandlerSSE2(int)
+ {
+ longjmp(s_jmpNoSSE2, 1);
+ }
+}
+#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
+
+bool CPU_ProbeSSE2()
+{
+ // Apple switched to Intel desktops in 2005/2006 using
+ // Core2 Duo's, which provides SSE2 and above.
+#if CRYPTOPP_BOOL_X64 || defined(__APPLE__)
+ return true;
+#elif defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
+ return false;
+#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
+ __try
+ {
+# if CRYPTOPP_SSE2_ASM_AVAILABLE
+ AS2(por xmm0, xmm0) // executing SSE2 instruction
+# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE
+ __m128i x = _mm_setzero_si128();
+ return _mm_cvtsi128_si32(x) == 0;
+# endif
+ }
+ // GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ return false;
+ }
+ return true;
+#else
+ // longjmp and clobber warnings. Volatile is required.
+ // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
+ volatile bool result = true;
+
+ volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
+ if (oldHandler == SIG_ERR)
+ return false;
+
+# ifndef __MINGW32__
+ volatile sigset_t oldMask;
+ if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask))
+ return false;
+# endif
+
+ if (setjmp(s_jmpNoSSE2))
+ result = false;
+ else
+ {
+# if CRYPTOPP_SSE2_ASM_AVAILABLE
+ __asm __volatile ("por %xmm0, %xmm0");
+# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE
+ __m128i x = _mm_setzero_si128();
+ result = _mm_cvtsi128_si32(x) == 0;
+# endif
+ }
+
+# ifndef __MINGW32__
+ sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
+# endif
+
+ signal(SIGILL, oldHandler);
+ return result;
+#endif
+}
+
+NAMESPACE_END