Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/sse_simd.cpp
Line
Count
Source (jump to first uncovered line)
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
33
extern const char SSE_SIMD_FNAME[] = __FILE__;
34
35
NAMESPACE_BEGIN(CryptoPP)
36
37
#ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
38
extern "C" {
39
    typedef void (*SigHandler)(int);
40
}
41
42
extern "C"
43
{
44
    static jmp_buf s_jmpNoSSE2;
45
    static void SigIllHandler(int)
46
0
    {
47
0
        longjmp(s_jmpNoSSE2, 1);
48
0
    }
49
}
50
#endif  // CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
51
52
bool CPU_ProbeSSE2()
53
0
{
54
    // Apple switched to Intel desktops in 2005/2006 using
55
    //   Core2 Duo's, which provides SSE2 and above.
56
0
#if CRYPTOPP_BOOL_X64 || defined(__APPLE__)
57
0
    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, SigIllHandler);
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
    {
89
        signal(SIGILL, oldHandler);
90
        return false;
91
    }
92
# endif
93
94
    if (setjmp(s_jmpNoSSE2))
95
        result = false;
96
    else
97
    {
98
# if CRYPTOPP_SSE2_ASM_AVAILABLE
99
        __asm __volatile ("por %xmm0, %xmm0");
100
# elif CRYPTOPP_SSE2_INTRIN_AVAILABLE
101
        __m128i x = _mm_setzero_si128();
102
        result = _mm_cvtsi128_si32(x) == 0;
103
# endif
104
    }
105
106
# ifndef __MINGW32__
107
    sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
108
# endif
109
110
    signal(SIGILL, oldHandler);
111
    return result;
112
#endif
113
0
}
114
115
NAMESPACE_END