1/* This test checks if the __builtin_cpu_is and __builtin_cpu_supports calls 2 are recognized. It also independently uses CPUID to get cpu type and 3 features supported and checks if the builtins correctly identify the 4 platform. The code to do the identification is adapted from 5 libgcc/config/i386/cpuinfo.c. */ 6 7/* { dg-do run } */ 8 9#include <assert.h> 10#include "cpuid.h" 11 12/* Check if the Intel CPU model and sub-model are identified. */ 13static void 14check_intel_cpu_model (unsigned int family, unsigned int model, 15 unsigned int brand_id) 16{ 17 /* Parse family and model only if brand ID is 0. */ 18 if (brand_id == 0) 19 { 20 switch (family) 21 { 22 case 0x5: 23 /* Pentium. */ 24 break; 25 case 0x6: 26 switch (model) 27 { 28 case 0x1c: 29 case 0x26: 30 /* Atom. */ 31 assert (__builtin_cpu_is ("atom")); 32 break; 33 case 0x37: 34 case 0x4a: 35 case 0x4d: 36 case 0x5a: 37 case 0x5d: 38 /* Silvermont. */ 39 assert (__builtin_cpu_is ("silvermont")); 40 break; 41 case 0x1a: 42 case 0x1e: 43 case 0x1f: 44 case 0x2e: 45 /* Nehalem. */ 46 assert (__builtin_cpu_is ("corei7")); 47 assert (__builtin_cpu_is ("nehalem")); 48 break; 49 case 0x25: 50 case 0x2c: 51 case 0x2f: 52 /* Westmere. */ 53 assert (__builtin_cpu_is ("corei7")); 54 assert (__builtin_cpu_is ("westmere")); 55 break; 56 case 0x2a: 57 case 0x2d: 58 /* Sandy Bridge. */ 59 assert (__builtin_cpu_is ("corei7")); 60 assert (__builtin_cpu_is ("sandybridge")); 61 break; 62 case 0x3a: 63 case 0x3e: 64 /* Ivy Bridge. */ 65 assert (__builtin_cpu_is ("corei7")); 66 assert (__builtin_cpu_is ("ivybridge")); 67 break; 68 case 0x3c: 69 case 0x3f: 70 case 0x45: 71 case 0x46: 72 /* Haswell. */ 73 assert (__builtin_cpu_is ("corei7")); 74 assert (__builtin_cpu_is ("haswell")); 75 break; 76 case 0x3d: 77 case 0x4f: 78 case 0x56: 79 /* Broadwell. */ 80 assert (__builtin_cpu_is ("corei7")); 81 assert (__builtin_cpu_is ("broadwell")); 82 break; 83 case 0x17: 84 case 0x1d: 85 /* Penryn. */ 86 case 0x0f: 87 /* Merom. */ 88 assert (__builtin_cpu_is ("core2")); 89 break; 90 default: 91 break; 92 } 93 break; 94 default: 95 /* We have no idea. */ 96 break; 97 } 98 } 99} 100 101/* Check if the AMD CPU model and sub-model are identified. */ 102static void 103check_amd_cpu_model (unsigned int family, unsigned int model) 104{ 105 switch (family) 106 { 107 /* AMD Family 10h. */ 108 case 0x10: 109 switch (model) 110 { 111 case 0x2: 112 /* Barcelona. */ 113 assert (__builtin_cpu_is ("amdfam10h")); 114 assert (__builtin_cpu_is ("barcelona")); 115 break; 116 case 0x4: 117 /* Shanghai. */ 118 assert (__builtin_cpu_is ("amdfam10h")); 119 assert (__builtin_cpu_is ("shanghai")); 120 break; 121 case 0x8: 122 /* Istanbul. */ 123 assert (__builtin_cpu_is ("amdfam10h")); 124 assert (__builtin_cpu_is ("istanbul")); 125 break; 126 default: 127 break; 128 } 129 break; 130 /* AMD Family 15h. */ 131 case 0x15: 132 assert (__builtin_cpu_is ("amdfam15h")); 133 /* Bulldozer version 1. */ 134 if ( model <= 0xf) 135 assert (__builtin_cpu_is ("bdver1")); 136 /* Bulldozer version 2. */ 137 if (model >= 0x10 && model <= 0x1f) 138 assert (__builtin_cpu_is ("bdver2")); 139 break; 140 default: 141 break; 142 } 143} 144 145/* Check if the ISA features are identified. */ 146static void 147check_features (unsigned int ecx, unsigned int edx, 148 int max_cpuid_level) 149{ 150 if (edx & bit_CMOV) 151 assert (__builtin_cpu_supports ("cmov")); 152 if (edx & bit_MMX) 153 assert (__builtin_cpu_supports ("mmx")); 154 if (edx & bit_SSE) 155 assert (__builtin_cpu_supports ("sse")); 156 if (edx & bit_SSE2) 157 assert (__builtin_cpu_supports ("sse2")); 158 if (ecx & bit_POPCNT) 159 assert (__builtin_cpu_supports ("popcnt")); 160 if (ecx & bit_SSE3) 161 assert (__builtin_cpu_supports ("sse3")); 162 if (ecx & bit_SSSE3) 163 assert (__builtin_cpu_supports ("ssse3")); 164 if (ecx & bit_SSE4_1) 165 assert (__builtin_cpu_supports ("sse4.1")); 166 if (ecx & bit_SSE4_2) 167 assert (__builtin_cpu_supports ("sse4.2")); 168 if (ecx & bit_AVX) 169 assert (__builtin_cpu_supports ("avx")); 170 171 /* Get advanced features at level 7 (eax = 7, ecx = 0). */ 172 if (max_cpuid_level >= 7) 173 { 174 unsigned int eax, ebx, ecx, edx; 175 __cpuid_count (7, 0, eax, ebx, ecx, edx); 176 if (ebx & bit_AVX2) 177 assert (__builtin_cpu_supports ("avx2")); 178 if (ebx & bit_AVX512F) 179 assert (__builtin_cpu_supports ("avx512f")); 180 } 181} 182 183static int __attribute__ ((noinline)) 184__get_cpuid_output (unsigned int __level, 185 unsigned int *__eax, unsigned int *__ebx, 186 unsigned int *__ecx, unsigned int *__edx) 187{ 188 return __get_cpuid (__level, __eax, __ebx, __ecx, __edx); 189} 190 191static int 192check_detailed () 193{ 194 unsigned int eax, ebx, ecx, edx; 195 196 int max_level; 197 unsigned int vendor; 198 unsigned int model, family, brand_id; 199 unsigned int extended_model, extended_family; 200 201 /* Assume cpuid insn present. Run in level 0 to get vendor id. */ 202 if (!__get_cpuid_output (0, &eax, &ebx, &ecx, &edx)) 203 return 0; 204 205 vendor = ebx; 206 max_level = eax; 207 208 if (max_level < 1) 209 return 0; 210 211 if (!__get_cpuid_output (1, &eax, &ebx, &ecx, &edx)) 212 return 0; 213 214 model = (eax >> 4) & 0x0f; 215 family = (eax >> 8) & 0x0f; 216 brand_id = ebx & 0xff; 217 extended_model = (eax >> 12) & 0xf0; 218 extended_family = (eax >> 20) & 0xff; 219 220 if (vendor == signature_INTEL_ebx) 221 { 222 assert (__builtin_cpu_is ("intel")); 223 /* Adjust family and model for Intel CPUs. */ 224 if (family == 0x0f) 225 { 226 family += extended_family; 227 model += extended_model; 228 } 229 else if (family == 0x06) 230 model += extended_model; 231 check_intel_cpu_model (family, model, brand_id); 232 check_features (ecx, edx, max_level); 233 } 234 else if (vendor == signature_AMD_ebx) 235 { 236 assert (__builtin_cpu_is ("amd")); 237 /* Adjust model and family for AMD CPUS. */ 238 if (family == 0x0f) 239 { 240 family += extended_family; 241 model += (extended_model << 4); 242 } 243 check_amd_cpu_model (family, model); 244 check_features (ecx, edx, max_level); 245 } 246 247 return 0; 248} 249 250static int 251quick_check () 252{ 253 /* Check CPU Features. */ 254 assert (__builtin_cpu_supports ("cmov") >= 0); 255 256 assert (__builtin_cpu_supports ("mmx") >= 0); 257 258 assert (__builtin_cpu_supports ("popcnt") >= 0); 259 260 assert (__builtin_cpu_supports ("sse") >= 0); 261 262 assert (__builtin_cpu_supports ("sse2") >= 0); 263 264 assert (__builtin_cpu_supports ("sse3") >= 0); 265 266 assert (__builtin_cpu_supports ("ssse3") >= 0); 267 268 assert (__builtin_cpu_supports ("sse4.1") >= 0); 269 270 assert (__builtin_cpu_supports ("sse4.2") >= 0); 271 272 assert (__builtin_cpu_supports ("avx") >= 0); 273 274 assert (__builtin_cpu_supports ("avx2") >= 0); 275 276 assert (__builtin_cpu_supports ("avx512f") >= 0); 277 278 /* Check CPU type. */ 279 assert (__builtin_cpu_is ("amd") >= 0); 280 281 assert (__builtin_cpu_is ("intel") >= 0); 282 283 assert (__builtin_cpu_is ("atom") >= 0); 284 285 assert (__builtin_cpu_is ("core2") >= 0); 286 287 assert (__builtin_cpu_is ("corei7") >= 0); 288 289 assert (__builtin_cpu_is ("nehalem") >= 0); 290 291 assert (__builtin_cpu_is ("westmere") >= 0); 292 293 assert (__builtin_cpu_is ("sandybridge") >= 0); 294 295 assert (__builtin_cpu_is ("amdfam10h") >= 0); 296 297 assert (__builtin_cpu_is ("barcelona") >= 0); 298 299 assert (__builtin_cpu_is ("shanghai") >= 0); 300 301 assert (__builtin_cpu_is ("istanbul") >= 0); 302 303 assert (__builtin_cpu_is ("amdfam15h") >= 0); 304 305 assert (__builtin_cpu_is ("bdver1") >= 0); 306 307 assert (__builtin_cpu_is ("bdver2") >= 0); 308 309 return 0; 310} 311 312int main () 313{ 314 __builtin_cpu_init (); 315 quick_check (); 316 check_detailed (); 317 return 0; 318} 319