103b705cfSriastradh/* 203b705cfSriastradh * Copyright (c) 2013 Intel Corporation 303b705cfSriastradh * 403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a 503b705cfSriastradh * copy of this software and associated documentation files (the "Software"), 603b705cfSriastradh * to deal in the Software without restriction, including without limitation 703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the 903b705cfSriastradh * Software is furnished to do so, subject to the following conditions: 1003b705cfSriastradh * 1103b705cfSriastradh * The above copyright notice and this permission notice (including the next 1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the 1303b705cfSriastradh * Software. 1403b705cfSriastradh * 1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2103b705cfSriastradh * SOFTWARE. 2203b705cfSriastradh * 2303b705cfSriastradh * Authors: 2403b705cfSriastradh * Chris Wilson <chris@chris-wilson.co.uk> 2503b705cfSriastradh * 2603b705cfSriastradh */ 2703b705cfSriastradh 2803b705cfSriastradh#ifdef HAVE_CONFIG_H 2903b705cfSriastradh#include "config.h" 3003b705cfSriastradh#endif 3103b705cfSriastradh 3203b705cfSriastradh#include "sna.h" 3303b705cfSriastradh#include "sna_cpuid.h" 3403b705cfSriastradh 3503b705cfSriastradh#define xgetbv(index,eax,edx) \ 3603b705cfSriastradh __asm__ ("xgetbv" : "=a"(eax), "=d"(edx) : "c" (index)) 3703b705cfSriastradh 3803b705cfSriastradh#define has_YMM 0x1 3903b705cfSriastradh 4003b705cfSriastradhunsigned sna_cpu_detect(void) 4103b705cfSriastradh{ 4203b705cfSriastradh unsigned max = __get_cpuid_max(BASIC_CPUID, NULL); 4342542f5fSchristos unsigned eax, ebx, ecx, edx; 4403b705cfSriastradh unsigned features = 0; 4503b705cfSriastradh unsigned extra = 0; 4603b705cfSriastradh 4703b705cfSriastradh if (max >= 1) { 4803b705cfSriastradh __cpuid(1, eax, ebx, ecx, edx); 4942542f5fSchristos 5003b705cfSriastradh if (ecx & bit_SSE3) 5103b705cfSriastradh features |= SSE3; 5203b705cfSriastradh 5303b705cfSriastradh if (ecx & bit_SSSE3) 5403b705cfSriastradh features |= SSSE3; 5503b705cfSriastradh 5603b705cfSriastradh if (ecx & bit_SSE4_1) 5703b705cfSriastradh features |= SSE4_1; 5803b705cfSriastradh 5903b705cfSriastradh if (ecx & bit_SSE4_2) 6003b705cfSriastradh features |= SSE4_2; 6103b705cfSriastradh 6203b705cfSriastradh if (ecx & bit_OSXSAVE) { 6303b705cfSriastradh unsigned int bv_eax, bv_ecx; 6403b705cfSriastradh xgetbv(0, bv_eax, bv_ecx); 6503b705cfSriastradh if ((bv_eax & 6) == 6) 6603b705cfSriastradh extra |= has_YMM; 6703b705cfSriastradh } 6803b705cfSriastradh 6903b705cfSriastradh if ((extra & has_YMM) && (ecx & bit_AVX)) 7003b705cfSriastradh features |= AVX; 7103b705cfSriastradh 7203b705cfSriastradh if (edx & bit_MMX) 7303b705cfSriastradh features |= MMX; 7403b705cfSriastradh 7503b705cfSriastradh if (edx & bit_SSE) 7603b705cfSriastradh features |= SSE; 7703b705cfSriastradh 7803b705cfSriastradh if (edx & bit_SSE2) 7903b705cfSriastradh features |= SSE2; 8003b705cfSriastradh } 8103b705cfSriastradh 8203b705cfSriastradh if (max >= 7) { 8303b705cfSriastradh __cpuid_count(7, 0, eax, ebx, ecx, edx); 8442542f5fSchristos 8503b705cfSriastradh if ((extra & has_YMM) && (ebx & bit_AVX2)) 8603b705cfSriastradh features |= AVX2; 8703b705cfSriastradh } 8803b705cfSriastradh 8903b705cfSriastradh return features; 9003b705cfSriastradh} 9103b705cfSriastradh 9203b705cfSriastradhchar *sna_cpu_features_to_string(unsigned features, char *line) 9303b705cfSriastradh{ 9403b705cfSriastradh char *ret = line; 9503b705cfSriastradh 9603b705cfSriastradh#ifdef __x86_64__ 9703b705cfSriastradh line += sprintf (line, "x86-64"); 9803b705cfSriastradh#else 9903b705cfSriastradh line += sprintf (line, "x86"); 10003b705cfSriastradh#endif 10103b705cfSriastradh 10203b705cfSriastradh if (features & SSE2) 10303b705cfSriastradh line += sprintf (line, ", sse2"); 10403b705cfSriastradh if (features & SSE3) 10503b705cfSriastradh line += sprintf (line, ", sse3"); 10603b705cfSriastradh if (features & SSSE3) 10703b705cfSriastradh line += sprintf (line, ", ssse3"); 10803b705cfSriastradh if (features & SSE4_1) 10903b705cfSriastradh line += sprintf (line, ", sse4.1"); 11003b705cfSriastradh if (features & SSE4_2) 11103b705cfSriastradh line += sprintf (line, ", sse4.2"); 11203b705cfSriastradh if (features & AVX) 11303b705cfSriastradh line += sprintf (line, ", avx"); 11403b705cfSriastradh if (features & AVX2) 11503b705cfSriastradh line += sprintf (line, ", avx2"); 11603b705cfSriastradh 11703b705cfSriastradh return ret; 11803b705cfSriastradh} 119