summaryrefslogtreecommitdiff
path: root/integer.cpp
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2003-09-05 00:54:14 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2003-09-05 00:54:14 +0000
commit4e675fcfdd0c4949d11a5a15ff3f2bfe645a1f87 (patch)
tree001560cc0bbba8ce98ec3f76e551bcbba5d686fb /integer.cpp
parent95ded6656783b66a11c8229d42137c97cabbaa30 (diff)
downloadcryptopp-4e675fcfdd0c4949d11a5a15ff3f2bfe645a1f87.tar.gz
add detection for OS support of SSE2
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@130 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'integer.cpp')
-rw-r--r--integer.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/integer.cpp b/integer.cpp
index 5cb3a8d..1fee33b 100644
--- a/integer.cpp
+++ b/integer.cpp
@@ -21,6 +21,8 @@
#ifdef __GNUC__
#include <xmmintrin.h>
#include <malloc.h>
+ #include <signal.h>
+ #include <setjmp.h>
#else
#include <emmintrin.h>
#endif
@@ -893,6 +895,15 @@ static void CpuId(word32 input, word32 *output)
#endif
}
+#ifdef SSE2_INTRINSICS_AVAILABLE
+#ifndef _MSC_VER
+static jmp_buf s_env;
+static void SigIllHandler(int)
+{
+ longjmp(s_env, 1);
+}
+#endif
+
static bool HasSSE2()
{
if (!s_sse2Enabled)
@@ -900,8 +911,37 @@ static bool HasSSE2()
word32 cpuid[4];
CpuId(1, cpuid);
- return (cpuid[3] & (1 << 26)) != 0;
+ if ((cpuid[3] & (1 << 26)) == 0)
+ return false;
+
+#ifdef _MSC_VER
+ __try
+ {
+ __asm xorpd xmm0, xmm0 // executing SSE2 instruction
+ }
+ __except (1)
+ {
+ return false;
+ }
+ return true;
+#else
+ typedef void (*SigHandler)(int);
+
+ SigHandler oldHandler = signal(SIGILL, SigIllHandler);
+ if (oldHandler == SIG_ERR)
+ return false;
+
+ bool result = true;
+ if (setjmp(s_env))
+ result = false;
+ else
+ __asm __volatile ("xorps %xmm0, %xmm0");
+
+ signal(SIGILL, oldHandler);
+ return result;
+#endif
}
+#endif
static bool IsP4()
{