1/************************************************************************** 2 * 3 * Copyright 2008 Dennis Smit 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * on the rights to use, copy, modify, merge, publish, distribute, sub 10 * license, and/or sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 23 * USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 ***************************************************************************/ 26 27/** 28 * @file 29 * CPU feature detection. 30 * 31 * @author Dennis Smit 32 * @author Based on the work of Eric Anholt <anholt@FreeBSD.org> 33 */ 34 35#ifndef _UTIL_CPU_DETECT_H 36#define _UTIL_CPU_DETECT_H 37 38 39#include "pipe/p_config.h" 40#include "util/u_thread.h" 41 42 43#ifdef __cplusplus 44extern "C" { 45#endif 46 47enum cpu_family { 48 CPU_UNKNOWN, 49 50 CPU_AMD_ZEN1_ZEN2, 51 CPU_AMD_ZEN_HYGON, 52 CPU_AMD_ZEN3, 53 CPU_AMD_ZEN_NEXT, 54 CPU_AMD_LAST, 55}; 56 57typedef uint32_t util_affinity_mask[UTIL_MAX_CPUS / 32]; 58 59struct util_cpu_caps_t { 60 /** 61 * Number of CPUs available to the process. 62 * 63 * This will be less than or equal to \c max_cpus. This is the number of 64 * CPUs that are online and available to the process. 65 */ 66 int16_t nr_cpus; 67 68 /** 69 * Maximum number of CPUs that can be online in the system. 70 * 71 * This will be greater than or equal to \c nr_cpus. This is the number of 72 * CPUs installed in the system. \c nr_cpus will be less if some CPUs are 73 * offline. 74 */ 75 int16_t max_cpus; 76 77 enum cpu_family family; 78 79 /* Feature flags */ 80 int x86_cpu_type; 81 unsigned cacheline; 82 83 unsigned has_intel:1; 84 unsigned has_tsc:1; 85 unsigned has_mmx:1; 86 unsigned has_mmx2:1; 87 unsigned has_sse:1; 88 unsigned has_sse2:1; 89 unsigned has_sse3:1; 90 unsigned has_ssse3:1; 91 unsigned has_sse4_1:1; 92 unsigned has_sse4_2:1; 93 unsigned has_popcnt:1; 94 unsigned has_avx:1; 95 unsigned has_avx2:1; 96 unsigned has_f16c:1; 97 unsigned has_fma:1; 98 unsigned has_3dnow:1; 99 unsigned has_3dnow_ext:1; 100 unsigned has_xop:1; 101 unsigned has_altivec:1; 102 unsigned has_vsx:1; 103 unsigned has_daz:1; 104 unsigned has_neon:1; 105 unsigned has_msa:1; 106 107 unsigned has_avx512f:1; 108 unsigned has_avx512dq:1; 109 unsigned has_avx512ifma:1; 110 unsigned has_avx512pf:1; 111 unsigned has_avx512er:1; 112 unsigned has_avx512cd:1; 113 unsigned has_avx512bw:1; 114 unsigned has_avx512vl:1; 115 unsigned has_avx512vbmi:1; 116 117 unsigned num_L3_caches; 118 unsigned num_cpu_mask_bits; 119 120 uint16_t cpu_to_L3[UTIL_MAX_CPUS]; 121 /* Affinity masks for each L3 cache. */ 122 util_affinity_mask *L3_affinity_mask; 123}; 124 125#define U_CPU_INVALID_L3 0xffff 126 127static inline const struct util_cpu_caps_t * 128util_get_cpu_caps(void) 129{ 130 extern struct util_cpu_caps_t util_cpu_caps; 131 132 /* If you hit this assert, it means that something is using the 133 * cpu-caps without having first called util_cpu_detect() 134 */ 135 assert(util_cpu_caps.nr_cpus >= 1); 136 137 return &util_cpu_caps; 138} 139 140void util_cpu_detect(void); 141 142 143#ifdef __cplusplus 144} 145#endif 146 147 148#endif /* _UTIL_CPU_DETECT_H */ 149