Coverage Report

Created: 2025-06-13 06:43

/src/php-src/Zend/zend_cpuinfo.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine                                                          |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.00 of the Zend license,     |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.zend.com/license/2_00.txt.                                |
11
   | If you did not receive a copy of the Zend license and are unable to  |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@zend.com so we can mail you a copy immediately.              |
14
   +----------------------------------------------------------------------+
15
   | Authors: Xinchen Hui <laruence@php.net>                              |
16
   +----------------------------------------------------------------------+
17
*/
18
19
#ifndef ZEND_CPU_INFO_H
20
#define ZEND_CPU_INFO_H
21
22
#include "zend.h"
23
24
129k
#define ZEND_CPU_EBX_MASK     (1<<30)
25
86.5k
#define ZEND_CPU_EDX_MASK     (1U<<31)
26
27
typedef enum _zend_cpu_feature {
28
  /* ECX */
29
  ZEND_CPU_FEATURE_SSE3     = (1<<0),
30
  ZEND_CPU_FEATURE_PCLMULQDQ    = (1<<1),
31
  ZEND_CPU_FEATURE_DTES64     = (1<<2),
32
  ZEND_CPU_FEATURE_MONITOR    = (1<<3),
33
  ZEND_CPU_FEATURE_DSCPL      = (1<<4),
34
  ZEND_CPU_FEATURE_VMX      = (1<<5),
35
  ZEND_CPU_FEATURE_SMX      = (1<<6),
36
  ZEND_CPU_FEATURE_EST      = (1<<7),
37
  ZEND_CPU_FEATURE_TM2      = (1<<8),
38
  ZEND_CPU_FEATURE_SSSE3      = (1<<9),
39
  ZEND_CPU_FEATURE_CID      = (1<<10),
40
  ZEND_CPU_FEATURE_SDBG     = (1<<11),
41
  ZEND_CPU_FEATURE_FMA      = (1<<12),
42
  ZEND_CPU_FEATURE_CX16     = (1<<13),
43
  ZEND_CPU_FEATURE_XTPR     = (1<<14),
44
  ZEND_CPU_FEATURE_PDCM     = (1<<15),
45
  /* reserved           = (1<<16),*/
46
  ZEND_CPU_FEATURE_PCID     = (1<<17),
47
  ZEND_CPU_FEATURE_DCA      = (1<<18),
48
  ZEND_CPU_FEATURE_SSE41      = (1<<19),
49
  ZEND_CPU_FEATURE_SSE42      = (1<<20),
50
  ZEND_CPU_FEATURE_X2APIC     = (1<<21),
51
  ZEND_CPU_FEATURE_MOVBE      = (1<<22),
52
  ZEND_CPU_FEATURE_POPCNT     = (1<<23),
53
  ZEND_CPU_FEATURE_TSC_DEADLINE   = (1<<24),
54
  ZEND_CPU_FEATURE_AES      = (1<<25),
55
  ZEND_CPU_FEATURE_XSAVE      = (1<<26),
56
  ZEND_CPU_FEATURE_OSXSAVE    = (1<<27) ,
57
  ZEND_CPU_FEATURE_AVX      = (1<<28),
58
  ZEND_CPU_FEATURE_F16C     = (1<<29),
59
  /* intentionally don't support  = (1<<30) */
60
  /* intentionally don't support  = (1<<31) */
61
62
  /* EBX */
63
  ZEND_CPU_FEATURE_AVX2     = (1<<5 | ZEND_CPU_EBX_MASK),
64
  ZEND_CPU_FEATURE_AVX512F    = (1<<16 | ZEND_CPU_EBX_MASK),
65
  ZEND_CPU_FEATURE_AVX512DQ   = (1<<17 | ZEND_CPU_EBX_MASK),
66
  ZEND_CPU_FEATURE_AVX512CD   = (1<<28 | ZEND_CPU_EBX_MASK),
67
  ZEND_CPU_FEATURE_SHA      = (1<<29 | ZEND_CPU_EBX_MASK),
68
  /* intentionally don't support    = (1<<30 | ZEND_CPU_EBX_MASK) */
69
  /* intentionally don't support    = (1<<31 | ZEND_CPU_EBX_MASK) */
70
71
  /* EDX */
72
  ZEND_CPU_FEATURE_FPU      = (1<<0 | ZEND_CPU_EDX_MASK),
73
  ZEND_CPU_FEATURE_VME      = (1<<1 | ZEND_CPU_EDX_MASK),
74
  ZEND_CPU_FEATURE_DE       = (1<<2 | ZEND_CPU_EDX_MASK),
75
  ZEND_CPU_FEATURE_PSE      = (1<<3 | ZEND_CPU_EDX_MASK),
76
  ZEND_CPU_FEATURE_TSC      = (1<<4 | ZEND_CPU_EDX_MASK),
77
  ZEND_CPU_FEATURE_MSR      = (1<<5 | ZEND_CPU_EDX_MASK),
78
  ZEND_CPU_FEATURE_PAE      = (1<<6 | ZEND_CPU_EDX_MASK),
79
  ZEND_CPU_FEATURE_MCE      = (1<<7 | ZEND_CPU_EDX_MASK),
80
  ZEND_CPU_FEATURE_CX8      = (1<<8 | ZEND_CPU_EDX_MASK),
81
  ZEND_CPU_FEATURE_APIC     = (1<<9 | ZEND_CPU_EDX_MASK),
82
  /* reserved           = (1<<10 | ZEND_CPU_EDX_MASK),*/
83
  ZEND_CPU_FEATURE_SEP      = (1<<11 | ZEND_CPU_EDX_MASK),
84
  ZEND_CPU_FEATURE_MTRR     = (1<<12 | ZEND_CPU_EDX_MASK),
85
  ZEND_CPU_FEATURE_PGE      = (1<<13 | ZEND_CPU_EDX_MASK),
86
  ZEND_CPU_FEATURE_MCA      = (1<<14 | ZEND_CPU_EDX_MASK),
87
  ZEND_CPU_FEATURE_CMOV     = (1<<15 | ZEND_CPU_EDX_MASK),
88
  ZEND_CPU_FEATURE_PAT      = (1<<16 | ZEND_CPU_EDX_MASK),
89
  ZEND_CPU_FEATURE_PSE36      = (1<<17 | ZEND_CPU_EDX_MASK),
90
  ZEND_CPU_FEATURE_PN       = (1<<18 | ZEND_CPU_EDX_MASK),
91
  ZEND_CPU_FEATURE_CLFLUSH    = (1<<19 | ZEND_CPU_EDX_MASK),
92
  /* reserved           = (1<<20 | ZEND_CPU_EDX_MASK),*/
93
  ZEND_CPU_FEATURE_DS       = (1<<21 | ZEND_CPU_EDX_MASK),
94
  ZEND_CPU_FEATURE_ACPI     = (1<<22 | ZEND_CPU_EDX_MASK),
95
  ZEND_CPU_FEATURE_MMX      = (1<<23 | ZEND_CPU_EDX_MASK),
96
  ZEND_CPU_FEATURE_FXSR     = (1<<24 | ZEND_CPU_EDX_MASK),
97
  ZEND_CPU_FEATURE_SSE      = (1<<25 | ZEND_CPU_EDX_MASK),
98
  ZEND_CPU_FEATURE_SSE2     = (1<<26 | ZEND_CPU_EDX_MASK),
99
  ZEND_CPU_FEATURE_SS       = (1<<27 | ZEND_CPU_EDX_MASK),
100
  ZEND_CPU_FEATURE_HT       = (1<<28 | ZEND_CPU_EDX_MASK),
101
  ZEND_CPU_FEATURE_TM       = (1<<29 | ZEND_CPU_EDX_MASK)
102
  /*intentionally don't support   = (1<<30 | ZEND_CPU_EDX_MASK)*/
103
  /*intentionally don't support   = (1<<31 | ZEND_CPU_EDX_MASK)*/
104
} zend_cpu_feature;
105
106
void zend_cpu_startup(void);
107
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
108
109
#ifndef __has_attribute
110
# define __has_attribute(x) 0
111
#endif
112
113
/* Address sanitizer is incompatible with ifunc resolvers, so exclude the
114
 * CPU support helpers from asan.
115
 * See also https://github.com/google/sanitizers/issues/342. */
116
#if __has_attribute(no_sanitize_address)
117
# define ZEND_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
118
#else
119
# define ZEND_NO_SANITIZE_ADDRESS
120
#endif
121
122
#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS
123
/* NOTE: you should use following inline function in
124
 * resolver functions (ifunc), as it could be called
125
 * before all PLT symbols are resolved. in other words,
126
 * resolver functions should not depend on any external
127
 * functions */
128
ZEND_NO_SANITIZE_ADDRESS
129
0
static inline int zend_cpu_supports_sse2(void) {
130
0
#ifdef __aarch64__
131
0
  return 0;
132
0
#else
133
0
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
134
0
  __builtin_cpu_init();
135
0
#endif
136
0
  return __builtin_cpu_supports("sse2");
137
0
#endif
138
0
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_sse2
Unexecuted instantiation: base64.c:zend_cpu_supports_sse2
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_sse2
Unexecuted instantiation: string.c:zend_cpu_supports_sse2
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_sse2
Unexecuted instantiation: zend.c:zend_cpu_supports_sse2
139
140
ZEND_NO_SANITIZE_ADDRESS
141
0
static inline int zend_cpu_supports_sse3(void) {
142
0
#ifdef __aarch64__
143
0
  return 0;
144
0
#else
145
0
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
146
0
  __builtin_cpu_init();
147
0
#endif
148
0
  return __builtin_cpu_supports("sse3");
149
0
#endif
150
0
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_sse3
Unexecuted instantiation: base64.c:zend_cpu_supports_sse3
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_sse3
Unexecuted instantiation: string.c:zend_cpu_supports_sse3
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_sse3
Unexecuted instantiation: zend.c:zend_cpu_supports_sse3
151
152
ZEND_NO_SANITIZE_ADDRESS
153
0
static inline int zend_cpu_supports_ssse3(void) {
154
#ifdef __aarch64__
155
  return 0;
156
#else
157
0
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
158
0
  __builtin_cpu_init();
159
0
#endif
160
0
  return __builtin_cpu_supports("ssse3");
161
0
#endif
162
0
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_ssse3
Unexecuted instantiation: base64.c:zend_cpu_supports_ssse3
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_ssse3
Unexecuted instantiation: string.c:zend_cpu_supports_ssse3
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_ssse3
Unexecuted instantiation: zend.c:zend_cpu_supports_ssse3
163
164
ZEND_NO_SANITIZE_ADDRESS
165
0
static inline int zend_cpu_supports_sse41(void) {
166
0
#ifdef __aarch64__
167
0
  return 0;
168
0
#else
169
0
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
170
0
  __builtin_cpu_init();
171
0
#endif
172
0
  return __builtin_cpu_supports("sse4.1");
173
0
#endif
174
0
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_sse41
Unexecuted instantiation: base64.c:zend_cpu_supports_sse41
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_sse41
Unexecuted instantiation: string.c:zend_cpu_supports_sse41
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_sse41
Unexecuted instantiation: zend.c:zend_cpu_supports_sse41
175
176
ZEND_NO_SANITIZE_ADDRESS
177
32
static inline int zend_cpu_supports_sse42(void) {
178
#ifdef __aarch64__
179
  return 0;
180
#else
181
32
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
182
32
  __builtin_cpu_init();
183
32
#endif
184
32
  return __builtin_cpu_supports("sse4.2");
185
32
#endif
186
32
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_sse42
Unexecuted instantiation: base64.c:zend_cpu_supports_sse42
crc32_x86.c:zend_cpu_supports_sse42
Line
Count
Source
177
16
static inline int zend_cpu_supports_sse42(void) {
178
#ifdef __aarch64__
179
  return 0;
180
#else
181
16
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
182
16
  __builtin_cpu_init();
183
16
#endif
184
16
  return __builtin_cpu_supports("sse4.2");
185
16
#endif
186
16
}
string.c:zend_cpu_supports_sse42
Line
Count
Source
177
16
static inline int zend_cpu_supports_sse42(void) {
178
#ifdef __aarch64__
179
  return 0;
180
#else
181
16
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
182
16
  __builtin_cpu_init();
183
16
#endif
184
16
  return __builtin_cpu_supports("sse4.2");
185
16
#endif
186
16
}
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_sse42
Unexecuted instantiation: zend.c:zend_cpu_supports_sse42
187
188
ZEND_NO_SANITIZE_ADDRESS
189
0
static inline int zend_cpu_supports_avx(void) {
190
0
#ifdef __aarch64__
191
0
  return 0;
192
0
#else
193
0
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
194
0
  __builtin_cpu_init();
195
0
#endif
196
0
  return __builtin_cpu_supports("avx");
197
0
#endif
198
0
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_avx
Unexecuted instantiation: base64.c:zend_cpu_supports_avx
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_avx
Unexecuted instantiation: string.c:zend_cpu_supports_avx
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_avx
Unexecuted instantiation: zend.c:zend_cpu_supports_avx
199
200
ZEND_NO_SANITIZE_ADDRESS
201
32
static inline int zend_cpu_supports_avx2(void) {
202
#ifdef __aarch64__
203
  return 0;
204
#else
205
32
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
206
32
  __builtin_cpu_init();
207
32
#endif
208
32
  return __builtin_cpu_supports("avx2");
209
32
#endif
210
32
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_avx2
base64.c:zend_cpu_supports_avx2
Line
Count
Source
201
32
static inline int zend_cpu_supports_avx2(void) {
202
#ifdef __aarch64__
203
  return 0;
204
#else
205
32
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
206
32
  __builtin_cpu_init();
207
32
#endif
208
32
  return __builtin_cpu_supports("avx2");
209
32
#endif
210
32
}
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_avx2
Unexecuted instantiation: string.c:zend_cpu_supports_avx2
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_avx2
Unexecuted instantiation: zend.c:zend_cpu_supports_avx2
211
212
#ifdef PHP_HAVE_AVX512_SUPPORTS
213
ZEND_NO_SANITIZE_ADDRESS
214
64
static inline int zend_cpu_supports_avx512(void) {
215
64
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
216
64
  __builtin_cpu_init();
217
64
#endif
218
64
  return __builtin_cpu_supports("avx512f") && __builtin_cpu_supports("avx512dq")
219
64
    && __builtin_cpu_supports("avx512cd") && __builtin_cpu_supports("avx512bw")
220
64
    && __builtin_cpu_supports("avx512vl");
221
64
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_avx512
base64.c:zend_cpu_supports_avx512
Line
Count
Source
214
64
static inline int zend_cpu_supports_avx512(void) {
215
64
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
216
64
  __builtin_cpu_init();
217
64
#endif
218
64
  return __builtin_cpu_supports("avx512f") && __builtin_cpu_supports("avx512dq")
219
64
    && __builtin_cpu_supports("avx512cd") && __builtin_cpu_supports("avx512bw")
220
64
    && __builtin_cpu_supports("avx512vl");
221
64
}
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_avx512
Unexecuted instantiation: string.c:zend_cpu_supports_avx512
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_avx512
Unexecuted instantiation: zend.c:zend_cpu_supports_avx512
222
#endif
223
224
#ifdef PHP_HAVE_AVX512_VBMI_SUPPORTS
225
ZEND_NO_SANITIZE_ADDRESS
226
32
static inline int zend_cpu_supports_avx512_vbmi(void) {
227
32
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
228
32
  __builtin_cpu_init();
229
32
#endif
230
32
  return zend_cpu_supports_avx512() && __builtin_cpu_supports("avx512vbmi");
231
32
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_avx512_vbmi
base64.c:zend_cpu_supports_avx512_vbmi
Line
Count
Source
226
32
static inline int zend_cpu_supports_avx512_vbmi(void) {
227
32
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
228
32
  __builtin_cpu_init();
229
32
#endif
230
32
  return zend_cpu_supports_avx512() && __builtin_cpu_supports("avx512vbmi");
231
32
}
Unexecuted instantiation: crc32_x86.c:zend_cpu_supports_avx512_vbmi
Unexecuted instantiation: string.c:zend_cpu_supports_avx512_vbmi
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_avx512_vbmi
Unexecuted instantiation: zend.c:zend_cpu_supports_avx512_vbmi
232
#endif
233
234
#else
235
236
static inline int zend_cpu_supports_sse2(void) {
237
  return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2);
238
}
239
240
static inline int zend_cpu_supports_sse3(void) {
241
  return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3);
242
}
243
244
static inline int zend_cpu_supports_ssse3(void) {
245
  return zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3);
246
}
247
248
static inline int zend_cpu_supports_sse41(void) {
249
  return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41);
250
}
251
252
static inline int zend_cpu_supports_sse42(void) {
253
  return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42);
254
}
255
256
static inline int zend_cpu_supports_avx(void) {
257
  return zend_cpu_supports(ZEND_CPU_FEATURE_AVX);
258
}
259
260
static inline int zend_cpu_supports_avx2(void) {
261
  return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
262
}
263
264
static inline int zend_cpu_supports_avx512(void) {
265
  /* TODO: avx512_bw/avx512_vl use bit 30/31 which are reserved for mask */
266
  return 0;
267
}
268
269
static zend_always_inline int zend_cpu_supports_avx512_vbmi(void) {
270
  /* TODO: avx512_vbmi use ECX of cpuid 7 */
271
  return 0;
272
}
273
#endif
274
275
/* __builtin_cpu_supports has pclmul from gcc9 */
276
#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
277
ZEND_NO_SANITIZE_ADDRESS
278
static inline int zend_cpu_supports_pclmul(void) {
279
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
280
  __builtin_cpu_init();
281
#endif
282
  return __builtin_cpu_supports("pclmul");
283
}
284
#else
285
16
static inline int zend_cpu_supports_pclmul(void) {
286
16
  return zend_cpu_supports(ZEND_CPU_FEATURE_PCLMULQDQ);
287
16
}
Unexecuted instantiation: hash_sha.c:zend_cpu_supports_pclmul
Unexecuted instantiation: base64.c:zend_cpu_supports_pclmul
crc32_x86.c:zend_cpu_supports_pclmul
Line
Count
Source
285
16
static inline int zend_cpu_supports_pclmul(void) {
286
16
  return zend_cpu_supports(ZEND_CPU_FEATURE_PCLMULQDQ);
287
16
}
Unexecuted instantiation: string.c:zend_cpu_supports_pclmul
Unexecuted instantiation: zend_cpuinfo.c:zend_cpu_supports_pclmul
Unexecuted instantiation: zend.c:zend_cpu_supports_pclmul
288
#endif
289
290
/* __builtin_cpu_supports has cldemote from gcc11 */
291
#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000)
292
ZEND_NO_SANITIZE_ADDRESS
293
static inline int zend_cpu_supports_cldemote(void) {
294
#ifdef PHP_HAVE_BUILTIN_CPU_INIT
295
  __builtin_cpu_init();
296
#endif
297
  return __builtin_cpu_supports("cldemote");
298
}
299
#endif
300
301
#endif