diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2003-09-05 00:54:14 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2003-09-05 00:54:14 +0000 |
commit | 4e675fcfdd0c4949d11a5a15ff3f2bfe645a1f87 (patch) | |
tree | 001560cc0bbba8ce98ec3f76e551bcbba5d686fb /integer.cpp | |
parent | 95ded6656783b66a11c8229d42137c97cabbaa30 (diff) | |
download | cryptopp-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.cpp | 42 |
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() { |