Crypto++ 8.2
Free C&
sse_simd.cpp
1// sse_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 SSE for CPU
5// feature testing. A separate source file is needed because additional
6// CXXFLAGS are required to enable the appropriate instructions set in
7// some build configurations.
8
9#include "pch.h"
10#include "config.h"
11#include "cpu.h"
12
13// Needed by MIPS for definition of NULL
14#include "stdcpp.h"
15
16#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
17# include <signal.h>
18# include <setjmp.h>
19#endif
20
21#ifndef EXCEPTION_EXECUTE_HANDLER
22# define EXCEPTION_EXECUTE_HANDLER 1
23#endif
24
25// Needed by SunCC and MSVC
26#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
27# if !defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) && !CRYPTOPP_SSE2_ASM_AVAILABLE && CRYPTOPP_SSE2_INTRIN_AVAILABLE
28# include <emmintrin.h>
29# endif
30#endif
31
32// Squash MS LNK4221 and libtool warnings
33extern const char SSE_SIMD_FNAME[] = __FILE__;
34
35NAMESPACE_BEGIN(CryptoPP)
36
37#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
38extern "C" {
39 typedef void (*SigHandler)(int);
40}
41
42extern "C"
43{
44 static jmp_buf s_jmpNoSSE2;
45 static void SigIllHandlerSSE2(int)
46 {
47 longjmp(s_jmpNoSSE2, 1);
48 }
49}
50#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
51
52bool CPU_ProbeSSE2()
53{
54 // Apple switched to Intel desktops in 2005/2006 using
55 // Core2 Duo's, which provides SSE2 and above.
56#if CRYPTOPP_BOOL_X64 || defined(__APPLE__)
57 return true;
58#elif defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
59 return false;
60#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
61 __try
62 {
63# if CRYPTOPP_SSE2_ASM_AVAILABLE
64 AS2(por xmm0, xmm0) // executing SSE2 instruction
65# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE
66 __m128i x = _mm_setzero_si128();
67 return _mm_cvtsi128_si32(x) == 0;
68# endif
69 }
70 // GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION
71 __except (EXCEPTION_EXECUTE_HANDLER)
72 {
73 return false;
74 }
75 return true;
76#else
77 // longjmp and clobber warnings. Volatile is required.
78 // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
79 volatile bool result = true;
80
81 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
82 if (oldHandler == SIG_ERR)
83 return false;
84
85# ifndef __MINGW32__
86 volatile sigset_t oldMask;
87 if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask))
88 return false;
89# endif
90
91 if (setjmp(s_jmpNoSSE2))
92 result = false;
93 else
94 {
95# if CRYPTOPP_SSE2_ASM_AVAILABLE
96 __asm __volatile ("por %xmm0, %xmm0");
97# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE
98 __m128i x = _mm_setzero_si128();
99 result = _mm_cvtsi128_si32(x) == 0;
100# endif
101 }
102
103# ifndef __MINGW32__
104 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
105# endif
106
107 signal(SIGILL, oldHandler);
108 return result;
109#endif
110}
111
112NAMESPACE_END
Library configuration file.
Functions for CPU features and intrinsics.
Crypto++ library namespace.
Precompiled header file.
Common C++ header files.