Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2013 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21.  * SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Chris Wilson <chris@chris-wilson.co.uk>
  25.  *
  26.  */
  27.  
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31.  
  32. #include "sna.h"
  33. #include "sna_cpuid.h"
  34.  
  35. #define xgetbv(index,eax,edx)                                   \
  36.         __asm__ ("xgetbv" : "=a"(eax), "=d"(edx) : "c" (index))
  37.  
  38. #define has_YMM 0x1
  39.  
  40. unsigned sna_cpu_detect(void)
  41. {
  42.         unsigned max = __get_cpuid_max(BASIC_CPUID, NULL);
  43.         unsigned int eax, ebx, ecx, edx;
  44.         unsigned features = 0;
  45.         unsigned extra = 0;
  46.  
  47.         if (max >= 1) {
  48.                 __cpuid(1, eax, ebx, ecx, edx);
  49.                 if (ecx & bit_SSE3)
  50.                         features |= SSE3;
  51.  
  52.                 if (ecx & bit_SSSE3)
  53.                         features |= SSSE3;
  54.  
  55.                 if (ecx & bit_SSE4_1)
  56.                         features |= SSE4_1;
  57.  
  58.                 if (ecx & bit_SSE4_2)
  59.                         features |= SSE4_2;
  60.  
  61.                 if (ecx & bit_OSXSAVE) {
  62.                         unsigned int bv_eax, bv_ecx;
  63.                         xgetbv(0, bv_eax, bv_ecx);
  64.                         if ((bv_eax & 6) == 6)
  65.                                 extra |= has_YMM;
  66.                 }
  67.  
  68.                 if ((extra & has_YMM) && (ecx & bit_AVX))
  69.                         features |= AVX;
  70.  
  71.                 if (edx & bit_MMX)
  72.                         features |= MMX;
  73.  
  74.                 if (edx & bit_SSE)
  75.                         features |= SSE;
  76.  
  77.                 if (edx & bit_SSE2)
  78.                         features |= SSE2;
  79.         }
  80.  
  81.         if (max >= 7) {
  82.                 __cpuid_count(7, 0, eax, ebx, ecx, edx);
  83.                 if ((extra & has_YMM) && (ebx & bit_AVX2))
  84.                         features |= AVX2;
  85.         }
  86.  
  87.         return features;
  88. }
  89.  
  90. char *sna_cpu_features_to_string(unsigned features, char *line)
  91. {
  92.         char *ret = line;
  93.  
  94. #ifdef __x86_64__
  95.         line += sprintf (line, "x86-64");
  96. #else
  97.         line += sprintf (line, "x86");
  98. #endif
  99.  
  100.         if (features & SSE2)
  101.                 line += sprintf (line, ", sse2");
  102.         if (features & SSE3)
  103.                 line += sprintf (line, ", sse3");
  104.         if (features & SSSE3)
  105.                 line += sprintf (line, ", ssse3");
  106.         if (features & SSE4_1)
  107.                 line += sprintf (line, ", sse4.1");
  108.         if (features & SSE4_2)
  109.                 line += sprintf (line, ", sse4.2");
  110.         if (features & AVX)
  111.                 line += sprintf (line, ", avx");
  112.         if (features & AVX2)
  113.                 line += sprintf (line, ", avx2");
  114.  
  115.         return ret;
  116. }
  117.