1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker *
3*61046927SAndroid Build Coastguard Worker * Copyright 2008 Dennis Smit
4*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * on the rights to use, copy, modify, merge, publish, distribute, sub
10*61046927SAndroid Build Coastguard Worker * license, and/or sell copies of the Software, and to permit persons to whom
11*61046927SAndroid Build Coastguard Worker * the Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
14*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
15*61046927SAndroid Build Coastguard Worker * Software.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21*61046927SAndroid Build Coastguard Worker * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22*61046927SAndroid Build Coastguard Worker * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23*61046927SAndroid Build Coastguard Worker * USE OR OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker *
25*61046927SAndroid Build Coastguard Worker ***************************************************************************/
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker /**
28*61046927SAndroid Build Coastguard Worker * @file
29*61046927SAndroid Build Coastguard Worker * CPU feature detection.
30*61046927SAndroid Build Coastguard Worker *
31*61046927SAndroid Build Coastguard Worker * @author Dennis Smit
32*61046927SAndroid Build Coastguard Worker * @author Based on the work of Eric Anholt <[email protected]>
33*61046927SAndroid Build Coastguard Worker */
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker #ifndef _UTIL_CPU_DETECT_H
36*61046927SAndroid Build Coastguard Worker #define _UTIL_CPU_DETECT_H
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
41*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
42*61046927SAndroid Build Coastguard Worker #include "util/u_thread.h"
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker /* Maximal cpu count for update affinity */
46*61046927SAndroid Build Coastguard Worker #define UTIL_MAX_CPUS 1024 /* this should be enough */
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
49*61046927SAndroid Build Coastguard Worker extern "C" {
50*61046927SAndroid Build Coastguard Worker #endif
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker enum cpu_family {
53*61046927SAndroid Build Coastguard Worker CPU_UNKNOWN,
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker CPU_AMD_ZEN1_ZEN2,
56*61046927SAndroid Build Coastguard Worker CPU_AMD_ZEN_HYGON,
57*61046927SAndroid Build Coastguard Worker CPU_AMD_ZEN3,
58*61046927SAndroid Build Coastguard Worker CPU_AMD_ZEN_NEXT,
59*61046927SAndroid Build Coastguard Worker CPU_AMD_LAST,
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker CPU_S390X,
62*61046927SAndroid Build Coastguard Worker };
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker typedef uint32_t util_affinity_mask[UTIL_MAX_CPUS / 32];
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker struct util_cpu_caps_t {
67*61046927SAndroid Build Coastguard Worker /**
68*61046927SAndroid Build Coastguard Worker * Number of CPUs available to the process.
69*61046927SAndroid Build Coastguard Worker *
70*61046927SAndroid Build Coastguard Worker * This will be less than or equal to \c max_cpus. This is the number of
71*61046927SAndroid Build Coastguard Worker * CPUs that are online and available to the process.
72*61046927SAndroid Build Coastguard Worker */
73*61046927SAndroid Build Coastguard Worker int16_t nr_cpus;
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker /**
76*61046927SAndroid Build Coastguard Worker * Maximum number of CPUs that can be online in the system.
77*61046927SAndroid Build Coastguard Worker *
78*61046927SAndroid Build Coastguard Worker * This will be greater than or equal to \c nr_cpus. This is the number of
79*61046927SAndroid Build Coastguard Worker * CPUs installed in the system. \c nr_cpus will be less if some CPUs are
80*61046927SAndroid Build Coastguard Worker * offline.
81*61046927SAndroid Build Coastguard Worker */
82*61046927SAndroid Build Coastguard Worker int16_t max_cpus;
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker enum cpu_family family;
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker /* Feature flags */
87*61046927SAndroid Build Coastguard Worker int x86_cpu_type;
88*61046927SAndroid Build Coastguard Worker unsigned cacheline;
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker unsigned has_intel:1;
91*61046927SAndroid Build Coastguard Worker unsigned has_mmx:1;
92*61046927SAndroid Build Coastguard Worker unsigned has_mmx2:1;
93*61046927SAndroid Build Coastguard Worker unsigned has_sse:1;
94*61046927SAndroid Build Coastguard Worker unsigned has_sse2:1;
95*61046927SAndroid Build Coastguard Worker unsigned has_sse3:1;
96*61046927SAndroid Build Coastguard Worker unsigned has_ssse3:1;
97*61046927SAndroid Build Coastguard Worker unsigned has_sse4_1:1;
98*61046927SAndroid Build Coastguard Worker unsigned has_sse4_2:1;
99*61046927SAndroid Build Coastguard Worker unsigned has_popcnt:1;
100*61046927SAndroid Build Coastguard Worker unsigned has_avx:1;
101*61046927SAndroid Build Coastguard Worker unsigned has_avx2:1;
102*61046927SAndroid Build Coastguard Worker unsigned has_f16c:1;
103*61046927SAndroid Build Coastguard Worker unsigned has_fma:1;
104*61046927SAndroid Build Coastguard Worker unsigned has_3dnow:1;
105*61046927SAndroid Build Coastguard Worker unsigned has_3dnow_ext:1;
106*61046927SAndroid Build Coastguard Worker unsigned has_xop:1;
107*61046927SAndroid Build Coastguard Worker unsigned has_altivec:1;
108*61046927SAndroid Build Coastguard Worker unsigned has_vsx:1;
109*61046927SAndroid Build Coastguard Worker unsigned has_daz:1;
110*61046927SAndroid Build Coastguard Worker unsigned has_neon:1;
111*61046927SAndroid Build Coastguard Worker unsigned has_msa:1;
112*61046927SAndroid Build Coastguard Worker unsigned has_lsx:1;
113*61046927SAndroid Build Coastguard Worker unsigned has_lasx:1;
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker unsigned has_avx512f:1;
116*61046927SAndroid Build Coastguard Worker unsigned has_avx512dq:1;
117*61046927SAndroid Build Coastguard Worker unsigned has_avx512ifma:1;
118*61046927SAndroid Build Coastguard Worker unsigned has_avx512pf:1;
119*61046927SAndroid Build Coastguard Worker unsigned has_avx512er:1;
120*61046927SAndroid Build Coastguard Worker unsigned has_avx512cd:1;
121*61046927SAndroid Build Coastguard Worker unsigned has_avx512bw:1;
122*61046927SAndroid Build Coastguard Worker unsigned has_avx512vl:1;
123*61046927SAndroid Build Coastguard Worker unsigned has_avx512vbmi:1;
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker unsigned has_clflushopt:1;
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker unsigned num_L3_caches;
128*61046927SAndroid Build Coastguard Worker unsigned num_cpu_mask_bits;
129*61046927SAndroid Build Coastguard Worker unsigned max_vector_bits;
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker uint16_t cpu_to_L3[UTIL_MAX_CPUS];
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker /* Affinity masks for each L3 cache. */
134*61046927SAndroid Build Coastguard Worker util_affinity_mask *L3_affinity_mask;
135*61046927SAndroid Build Coastguard Worker /**
136*61046927SAndroid Build Coastguard Worker * number of "big" CPUs in big.LITTLE configuration
137*61046927SAndroid Build Coastguard Worker *
138*61046927SAndroid Build Coastguard Worker * a "big" CPU is defined as anything with >= 50% the capacity of the largest CPU,
139*61046927SAndroid Build Coastguard Worker * useful for drivers determining how many and what kinds of threads to use
140*61046927SAndroid Build Coastguard Worker * example: 1x prime + 3x big + 4x little = 4x "big" cores
141*61046927SAndroid Build Coastguard Worker *
142*61046927SAndroid Build Coastguard Worker * A value of zero indicates that CPUs are homogeneous.
143*61046927SAndroid Build Coastguard Worker */
144*61046927SAndroid Build Coastguard Worker int16_t nr_big_cpus;
145*61046927SAndroid Build Coastguard Worker };
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker struct _util_cpu_caps_state_t {
148*61046927SAndroid Build Coastguard Worker once_flag once_flag;
149*61046927SAndroid Build Coastguard Worker /**
150*61046927SAndroid Build Coastguard Worker * Initialized to 0 and set to non-zero with an atomic after the entire
151*61046927SAndroid Build Coastguard Worker * struct has been initialized.
152*61046927SAndroid Build Coastguard Worker */
153*61046927SAndroid Build Coastguard Worker uint32_t detect_done;
154*61046927SAndroid Build Coastguard Worker struct util_cpu_caps_t caps;
155*61046927SAndroid Build Coastguard Worker };
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker #define U_CPU_INVALID_L3 0xffff
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker static inline ATTRIBUTE_CONST const struct util_cpu_caps_t *
util_get_cpu_caps(void)160*61046927SAndroid Build Coastguard Worker util_get_cpu_caps(void)
161*61046927SAndroid Build Coastguard Worker {
162*61046927SAndroid Build Coastguard Worker extern void _util_cpu_detect_once(void);
163*61046927SAndroid Build Coastguard Worker extern struct _util_cpu_caps_state_t _util_cpu_caps_state;
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker /* On most CPU architectures, an atomic read is simply a regular memory
166*61046927SAndroid Build Coastguard Worker * load instruction with some extra compiler magic to prevent code
167*61046927SAndroid Build Coastguard Worker * re-ordering around it. The perf impact of doing this check should be
168*61046927SAndroid Build Coastguard Worker * negligible in most cases.
169*61046927SAndroid Build Coastguard Worker *
170*61046927SAndroid Build Coastguard Worker * Also, even though it looks like a bit of a lie, we've declared this
171*61046927SAndroid Build Coastguard Worker * function with ATTRIBUTE_CONST. The GCC docs say:
172*61046927SAndroid Build Coastguard Worker *
173*61046927SAndroid Build Coastguard Worker * "Calls to functions whose return value is not affected by changes to
174*61046927SAndroid Build Coastguard Worker * the observable state of the program and that have no observable
175*61046927SAndroid Build Coastguard Worker * effects on such state other than to return a value may lend
176*61046927SAndroid Build Coastguard Worker * themselves to optimizations such as common subexpression elimination.
177*61046927SAndroid Build Coastguard Worker * Declaring such functions with the const attribute allows GCC to avoid
178*61046927SAndroid Build Coastguard Worker * emitting some calls in repeated invocations of the function with the
179*61046927SAndroid Build Coastguard Worker * same argument values."
180*61046927SAndroid Build Coastguard Worker *
181*61046927SAndroid Build Coastguard Worker * The word "observable" is important here. With the exception of a
182*61046927SAndroid Build Coastguard Worker * llvmpipe debug flag behind an environment variable and a few unit tests,
183*61046927SAndroid Build Coastguard Worker * all of which emulate worse CPUs, this function neither affects nor is
184*61046927SAndroid Build Coastguard Worker * affected by any "observable" state. It has its own internal state for
185*61046927SAndroid Build Coastguard Worker * sure, but that state is such that it appears to return exactly the same
186*61046927SAndroid Build Coastguard Worker * value with the same internal data every time.
187*61046927SAndroid Build Coastguard Worker */
188*61046927SAndroid Build Coastguard Worker if (unlikely(!p_atomic_read(&_util_cpu_caps_state.detect_done)))
189*61046927SAndroid Build Coastguard Worker call_once(&_util_cpu_caps_state.once_flag, _util_cpu_detect_once);
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker return &_util_cpu_caps_state.caps;
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker
194*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker #endif
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker #endif /* _UTIL_CPU_DETECT_H */
200