Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 1 | // Copyright 2017 Google Inc. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Guillaume Chatelet | 8e58ef0 | 2018-02-01 10:38:48 +0100 | [diff] [blame] | 15 | #ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ |
| 16 | #define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 17 | |
| 18 | #include "cpu_features_macros.h" |
| 19 | |
Guillaume Chatelet | e419573 | 2018-02-12 16:15:15 +0100 | [diff] [blame] | 20 | CPU_FEATURES_START_CPP_NAMESPACE |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 21 | |
| 22 | // See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features. |
Guillaume Chatelet | d395dfa | 2019-01-22 13:19:42 +0100 | [diff] [blame] | 23 | // The field names are based on the short name provided in the wikipedia tables. |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 24 | typedef struct { |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 25 | int fpu : 1; |
| 26 | int tsc : 1; |
| 27 | int cx8 : 1; |
| 28 | int clfsh : 1; |
| 29 | int mmx : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 30 | int aes : 1; |
| 31 | int erms : 1; |
| 32 | int f16c : 1; |
| 33 | int fma3 : 1; |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 34 | int vaes : 1; |
Guillaume Chatelet | 11e3e20 | 2018-02-09 08:55:11 +0100 | [diff] [blame] | 35 | int vpclmulqdq : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 36 | int bmi1 : 1; |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 37 | int hle : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 38 | int bmi2 : 1; |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 39 | int rtm : 1; |
| 40 | int rdseed : 1; |
| 41 | int clflushopt : 1; |
| 42 | int clwb : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 43 | |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 44 | int sse : 1; |
| 45 | int sse2 : 1; |
| 46 | int sse3 : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 47 | int ssse3 : 1; |
| 48 | int sse4_1 : 1; |
| 49 | int sse4_2 : 1; |
| 50 | |
| 51 | int avx : 1; |
| 52 | int avx2 : 1; |
| 53 | |
| 54 | int avx512f : 1; |
| 55 | int avx512cd : 1; |
| 56 | int avx512er : 1; |
| 57 | int avx512pf : 1; |
| 58 | int avx512bw : 1; |
| 59 | int avx512dq : 1; |
| 60 | int avx512vl : 1; |
| 61 | int avx512ifma : 1; |
| 62 | int avx512vbmi : 1; |
| 63 | int avx512vbmi2 : 1; |
| 64 | int avx512vnni : 1; |
| 65 | int avx512bitalg : 1; |
| 66 | int avx512vpopcntdq : 1; |
| 67 | int avx512_4vnniw : 1; |
| 68 | int avx512_4vbmi2 : 1; |
| 69 | |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 70 | int pclmulqdq : 1; |
Patrik Fiedler | 3ee0d62 | 2018-02-13 11:14:32 +0100 | [diff] [blame] | 71 | int smx : 1; |
| 72 | int sgx : 1; |
Guillaume Chatelet | 9b872ce | 2018-03-13 10:58:42 +0100 | [diff] [blame] | 73 | int cx16 : 1; // aka. CMPXCHG16B |
Guillaume Chatelet | d395dfa | 2019-01-22 13:19:42 +0100 | [diff] [blame] | 74 | int sha : 1; |
| 75 | int popcnt : 1; |
| 76 | int movbe : 1; |
| 77 | int rdrnd : 1; |
Patrik Fiedler | 3ee0d62 | 2018-02-13 11:14:32 +0100 | [diff] [blame] | 78 | |
Artem Alekseev | 3ee4a9e | 2019-06-19 16:06:05 +0300 | [diff] [blame^] | 79 | int dca : 1; |
| 80 | int ss : 1; |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 81 | // Make sure to update X86FeaturesEnum below if you add a field here. |
| 82 | } X86Features; |
| 83 | |
| 84 | typedef struct { |
| 85 | X86Features features; |
| 86 | int family; |
| 87 | int model; |
| 88 | int stepping; |
| 89 | char vendor[13]; // 0 terminated string |
| 90 | } X86Info; |
| 91 | |
| 92 | // Calls cpuid and returns an initialized X86info. |
| 93 | // This function is guaranteed to be malloc, memset and memcpy free. |
| 94 | X86Info GetX86Info(void); |
| 95 | |
| 96 | typedef enum { |
| 97 | X86_UNKNOWN, |
| 98 | INTEL_CORE, // CORE |
| 99 | INTEL_PNR, // PENRYN |
| 100 | INTEL_NHM, // NEHALEM |
| 101 | INTEL_ATOM_BNL, // BONNELL |
| 102 | INTEL_WSM, // WESTMERE |
| 103 | INTEL_SNB, // SANDYBRIDGE |
| 104 | INTEL_IVB, // IVYBRIDGE |
| 105 | INTEL_ATOM_SMT, // SILVERMONT |
| 106 | INTEL_HSW, // HASWELL |
| 107 | INTEL_BDW, // BROADWELL |
| 108 | INTEL_SKL, // SKYLAKE |
| 109 | INTEL_ATOM_GMT, // GOLDMONT |
| 110 | INTEL_KBL, // KABY LAKE |
| 111 | INTEL_CFL, // COFFEE LAKE |
Brandon Surmanski | efcc49a | 2018-02-07 11:07:00 -0800 | [diff] [blame] | 112 | INTEL_CNL, // CANNON LAKE |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 113 | AMD_HAMMER, // K8 |
| 114 | AMD_K10, // K10 |
| 115 | AMD_BOBCAT, // K14 |
| 116 | AMD_BULLDOZER, // K15 |
| 117 | AMD_JAGUAR, // K16 |
| 118 | AMD_ZEN, // K17 |
| 119 | } X86Microarchitecture; |
| 120 | |
| 121 | // Returns the underlying microarchitecture by looking at X86Info's vendor, |
| 122 | // family and model. |
| 123 | X86Microarchitecture GetX86Microarchitecture(const X86Info* info); |
| 124 | |
| 125 | // Calls cpuid and fills the brand_string. |
| 126 | // - brand_string *must* be of size 49 (beware of array decaying). |
| 127 | // - brand_string will be zero terminated. |
| 128 | // - This function calls memcpy. |
| 129 | void FillX86BrandString(char brand_string[49]); |
| 130 | |
| 131 | //////////////////////////////////////////////////////////////////////////////// |
| 132 | // Introspection functions |
| 133 | |
| 134 | typedef enum { |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 135 | X86_FPU, |
| 136 | X86_TSC, |
| 137 | X86_CX8, |
| 138 | X86_CLFSH, |
| 139 | X86_MMX, |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 140 | X86_AES, |
| 141 | X86_ERMS, |
| 142 | X86_F16C, |
| 143 | X86_FMA3, |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 144 | X86_VAES, |
Guillaume Chatelet | 11e3e20 | 2018-02-09 08:55:11 +0100 | [diff] [blame] | 145 | X86_VPCLMULQDQ, |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 146 | X86_BMI1, |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 147 | X86_HLE, |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 148 | X86_BMI2, |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 149 | X86_RTM, |
| 150 | X86_RDSEED, |
| 151 | X86_CLFLUSHOPT, |
| 152 | X86_CLWB, |
| 153 | X86_SSE, |
| 154 | X86_SSE2, |
| 155 | X86_SSE3, |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 156 | X86_SSSE3, |
| 157 | X86_SSE4_1, |
| 158 | X86_SSE4_2, |
| 159 | X86_AVX, |
| 160 | X86_AVX2, |
| 161 | X86_AVX512F, |
| 162 | X86_AVX512CD, |
| 163 | X86_AVX512ER, |
| 164 | X86_AVX512PF, |
| 165 | X86_AVX512BW, |
| 166 | X86_AVX512DQ, |
| 167 | X86_AVX512VL, |
| 168 | X86_AVX512IFMA, |
| 169 | X86_AVX512VBMI, |
| 170 | X86_AVX512VBMI2, |
| 171 | X86_AVX512VNNI, |
| 172 | X86_AVX512BITALG, |
| 173 | X86_AVX512VPOPCNTDQ, |
| 174 | X86_AVX512_4VNNIW, |
| 175 | X86_AVX512_4VBMI2, |
Dr.-Ing. Patrick Siegl | 367bc42 | 2019-06-13 11:53:39 +0200 | [diff] [blame] | 176 | X86_PCLMULQDQ, |
Patrik Fiedler | 3ee0d62 | 2018-02-13 11:14:32 +0100 | [diff] [blame] | 177 | X86_SMX, |
| 178 | X86_SGX, |
Guillaume Chatelet | 9b872ce | 2018-03-13 10:58:42 +0100 | [diff] [blame] | 179 | X86_CX16, |
Guillaume Chatelet | d395dfa | 2019-01-22 13:19:42 +0100 | [diff] [blame] | 180 | X86_SHA, |
| 181 | X86_POPCNT, |
| 182 | X86_MOVBE, |
| 183 | X86_RDRND, |
Artem Alekseev | 3ee4a9e | 2019-06-19 16:06:05 +0300 | [diff] [blame^] | 184 | X86_DCA, |
| 185 | X86_SS, |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 186 | X86_LAST_, |
| 187 | } X86FeaturesEnum; |
| 188 | |
| 189 | int GetX86FeaturesEnumValue(const X86Features* features, X86FeaturesEnum value); |
| 190 | |
| 191 | const char* GetX86FeaturesEnumName(X86FeaturesEnum); |
| 192 | |
| 193 | const char* GetX86MicroarchitectureName(X86Microarchitecture); |
| 194 | |
Guillaume Chatelet | e419573 | 2018-02-12 16:15:15 +0100 | [diff] [blame] | 195 | CPU_FEATURES_END_CPP_NAMESPACE |
Guillaume Chatelet | 439d371 | 2018-02-01 10:03:09 +0100 | [diff] [blame] | 196 | |
Guillaume Chatelet | 4155ee7 | 2019-01-18 13:38:22 +0100 | [diff] [blame] | 197 | #if !defined(CPU_FEATURES_ARCH_X86) |
| 198 | #error "Including cpuinfo_x86.h from a non-x86 target." |
| 199 | #endif |
| 200 | |
Guillaume Chatelet | 8e58ef0 | 2018-02-01 10:38:48 +0100 | [diff] [blame] | 201 | #endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ |