Coverage Report

Created: 2025-06-16 07:00

/src/libdeflate/lib/x86/cpu_features.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * x86/cpu_features.h - feature detection for x86 CPUs
3
 *
4
 * Copyright 2016 Eric Biggers
5
 *
6
 * Permission is hereby granted, free of charge, to any person
7
 * obtaining a copy of this software and associated documentation
8
 * files (the "Software"), to deal in the Software without
9
 * restriction, including without limitation the rights to use,
10
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the
12
 * Software is furnished to do so, subject to the following
13
 * conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
 * OTHER DEALINGS IN THE SOFTWARE.
26
 */
27
28
#ifndef LIB_X86_CPU_FEATURES_H
29
#define LIB_X86_CPU_FEATURES_H
30
31
#include "../lib_common.h"
32
33
#if defined(ARCH_X86_32) || defined(ARCH_X86_64)
34
35
6
#define X86_CPU_FEATURE_SSE2    (1 << 0)
36
6
#define X86_CPU_FEATURE_PCLMULQDQ (1 << 1)
37
6
#define X86_CPU_FEATURE_AVX   (1 << 2)
38
18
#define X86_CPU_FEATURE_AVX2    (1 << 3)
39
12
#define X86_CPU_FEATURE_BMI2    (1 << 4)
40
/*
41
 * ZMM indicates whether 512-bit vectors (zmm registers) should be used.  On
42
 * some CPUs, to avoid downclocking issues we don't set ZMM even if the CPU and
43
 * operating system support AVX-512.  On these CPUs, we may still use AVX-512
44
 * instructions, but only with xmm and ymm registers.
45
 */
46
6
#define X86_CPU_FEATURE_ZMM   (1 << 5)
47
6
#define X86_CPU_FEATURE_AVX512BW  (1 << 6)
48
0
#define X86_CPU_FEATURE_AVX512VL  (1 << 7)
49
0
#define X86_CPU_FEATURE_VPCLMULQDQ  (1 << 8)
50
0
#define X86_CPU_FEATURE_AVX512VNNI  (1 << 9)
51
6
#define X86_CPU_FEATURE_AVXVNNI   (1 << 10)
52
53
#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
54
/* Runtime x86 CPU feature detection is supported. */
55
6
#  define X86_CPU_FEATURES_KNOWN  (1U << 31)
56
extern volatile u32 libdeflate_x86_cpu_features;
57
58
void libdeflate_init_x86_cpu_features(void);
59
60
static inline u32 get_x86_cpu_features(void)
61
12
{
62
12
  if (libdeflate_x86_cpu_features == 0)
63
6
    libdeflate_init_x86_cpu_features();
64
12
  return libdeflate_x86_cpu_features;
65
12
}
Unexecuted instantiation: deflate_compress.c:get_x86_cpu_features
deflate_decompress.c:get_x86_cpu_features
Line
Count
Source
61
6
{
62
6
  if (libdeflate_x86_cpu_features == 0)
63
6
    libdeflate_init_x86_cpu_features();
64
6
  return libdeflate_x86_cpu_features;
65
6
}
Unexecuted instantiation: cpu_features.c:get_x86_cpu_features
adler32.c:get_x86_cpu_features
Line
Count
Source
61
6
{
62
6
  if (libdeflate_x86_cpu_features == 0)
63
0
    libdeflate_init_x86_cpu_features();
64
6
  return libdeflate_x86_cpu_features;
65
6
}
66
/*
67
 * x86 intrinsics are also supported.  Include the headers needed to use them.
68
 * Normally just immintrin.h suffices.  With clang in MSVC compatibility mode,
69
 * immintrin.h incorrectly skips including sub-headers, so include those too.
70
 */
71
#  include <immintrin.h>
72
#  if defined(_MSC_VER) && defined(__clang__)
73
#    include <tmmintrin.h>
74
#    include <smmintrin.h>
75
#    include <wmmintrin.h>
76
#    include <avxintrin.h>
77
#    include <avx2intrin.h>
78
#    include <avx512fintrin.h>
79
#    include <avx512bwintrin.h>
80
#    include <avx512vlintrin.h>
81
#    if __has_include(<avx512vlbwintrin.h>)
82
#      include <avx512vlbwintrin.h>
83
#    endif
84
#    if __has_include(<vpclmulqdqintrin.h>)
85
#      include <vpclmulqdqintrin.h>
86
#    endif
87
#    if __has_include(<avx512vnniintrin.h>)
88
#      include <avx512vnniintrin.h>
89
#    endif
90
#    if __has_include(<avx512vlvnniintrin.h>)
91
#      include <avx512vlvnniintrin.h>
92
#    endif
93
#    if __has_include(<avxvnniintrin.h>)
94
#      include <avxvnniintrin.h>
95
#    endif
96
#  endif
97
#else
98
static inline u32 get_x86_cpu_features(void) { return 0; }
99
#endif
100
101
#if defined(__SSE2__) || \
102
  (defined(_MSC_VER) && \
103
   (defined(ARCH_X86_64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)))
104
0
#  define HAVE_SSE2(features)   1
105
#  define HAVE_SSE2_NATIVE    1
106
#else
107
#  define HAVE_SSE2(features)   ((features) & X86_CPU_FEATURE_SSE2)
108
#  define HAVE_SSE2_NATIVE    0
109
#endif
110
111
#if (defined(__PCLMUL__) && defined(__SSE4_1__)) || \
112
  (defined(_MSC_VER) && defined(__AVX2__))
113
#  define HAVE_PCLMULQDQ(features)  1
114
#else
115
#  define HAVE_PCLMULQDQ(features)  ((features) & X86_CPU_FEATURE_PCLMULQDQ)
116
#endif
117
118
#ifdef __AVX__
119
#  define HAVE_AVX(features)    1
120
#else
121
#  define HAVE_AVX(features)    ((features) & X86_CPU_FEATURE_AVX)
122
#endif
123
124
#ifdef __AVX2__
125
#  define HAVE_AVX2(features)   1
126
#else
127
18
#  define HAVE_AVX2(features)   ((features) & X86_CPU_FEATURE_AVX2)
128
#endif
129
130
#if defined(__BMI2__) || (defined(_MSC_VER) && defined(__AVX2__))
131
#  define HAVE_BMI2(features)   1
132
#  define HAVE_BMI2_NATIVE    1
133
#else
134
6
#  define HAVE_BMI2(features)   ((features) & X86_CPU_FEATURE_BMI2)
135
#  define HAVE_BMI2_NATIVE    0
136
#endif
137
138
#ifdef __AVX512BW__
139
#  define HAVE_AVX512BW(features) 1
140
#else
141
18
#  define HAVE_AVX512BW(features) ((features) & X86_CPU_FEATURE_AVX512BW)
142
#endif
143
144
#ifdef __AVX512VL__
145
#  define HAVE_AVX512VL(features) 1
146
#else
147
6
#  define HAVE_AVX512VL(features) ((features) & X86_CPU_FEATURE_AVX512VL)
148
#endif
149
150
#ifdef __VPCLMULQDQ__
151
#  define HAVE_VPCLMULQDQ(features) 1
152
#else
153
#  define HAVE_VPCLMULQDQ(features) ((features) & X86_CPU_FEATURE_VPCLMULQDQ)
154
#endif
155
156
#ifdef __AVX512VNNI__
157
#  define HAVE_AVX512VNNI(features) 1
158
#else
159
0
#  define HAVE_AVX512VNNI(features) ((features) & X86_CPU_FEATURE_AVX512VNNI)
160
#endif
161
162
#ifdef __AVXVNNI__
163
#  define HAVE_AVXVNNI(features)  1
164
#else
165
6
#  define HAVE_AVXVNNI(features)  ((features) & X86_CPU_FEATURE_AVXVNNI)
166
#endif
167
168
#endif /* ARCH_X86_32 || ARCH_X86_64 */
169
170
#endif /* LIB_X86_CPU_FEATURES_H */