mozglue/build/SSE.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mozglue/build/SSE.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,152 @@
     1.4 +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/* compile-time and runtime tests for whether to use SSE instructions */
    1.10 +
    1.11 +#include "SSE.h"
    1.12 +
    1.13 +namespace {
    1.14 +
    1.15 +// SSE.h has parallel #ifs which declare MOZILLA_SSE_HAVE_CPUID_DETECTION.
    1.16 +// We can't declare these functions in the header file, however, because
    1.17 +// <intrin.h> conflicts with <windows.h> on MSVC 2005, and some files want to
    1.18 +// include both SSE.h and <windows.h>.
    1.19 +
    1.20 +#ifdef HAVE_CPUID_H
    1.21 +
    1.22 +// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64
    1.23 +#include <cpuid.h>
    1.24 +
    1.25 +enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
    1.26 +
    1.27 +static bool
    1.28 +has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit)
    1.29 +{
    1.30 +  unsigned int regs[4];
    1.31 +  return __get_cpuid(level, &regs[0], &regs[1], &regs[2], &regs[3]) &&
    1.32 +         (regs[reg] & bit);
    1.33 +}
    1.34 +
    1.35 +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
    1.36 +
    1.37 +// MSVC 2005 or newer on x86-32 or x86-64
    1.38 +#include <intrin.h>
    1.39 +
    1.40 +enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
    1.41 +
    1.42 +static bool
    1.43 +has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit)
    1.44 +{
    1.45 +  // Check that the level in question is supported.
    1.46 +  int regs[4];
    1.47 +  __cpuid(regs, level & 0x80000000u);
    1.48 +  if (unsigned(regs[0]) < level)
    1.49 +    return false;
    1.50 +
    1.51 +  __cpuid(regs, level);
    1.52 +  return !!(unsigned(regs[reg]) & bit);
    1.53 +}
    1.54 +
    1.55 +#elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
    1.56 +
    1.57 +enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
    1.58 +
    1.59 +#ifdef __i386
    1.60 +static void
    1.61 +moz_cpuid(int CPUInfo[4], int InfoType)
    1.62 +{
    1.63 +  asm (
    1.64 +    "xchg %esi, %ebx\n"
    1.65 +    "cpuid\n"
    1.66 +    "movl %eax, (%edi)\n"
    1.67 +    "movl %ebx, 4(%edi)\n"
    1.68 +    "movl %ecx, 8(%edi)\n"
    1.69 +    "movl %edx, 12(%edi)\n"
    1.70 +    "xchg %esi, %ebx\n"
    1.71 +    :
    1.72 +    : "a"(InfoType), // %eax
    1.73 +      "D"(CPUInfo) // %edi
    1.74 +    : "%ecx", "%edx", "%esi"
    1.75 +  );
    1.76 +}
    1.77 +#else
    1.78 +static void
    1.79 +moz_cpuid(int CPUInfo[4], int InfoType)
    1.80 +{
    1.81 +  asm (
    1.82 +    "xchg %rsi, %rbx\n"
    1.83 +    "cpuid\n"
    1.84 +    "movl %eax, (%rdi)\n"
    1.85 +    "movl %ebx, 4(%rdi)\n"
    1.86 +    "movl %ecx, 8(%rdi)\n"
    1.87 +    "movl %edx, 12(%rdi)\n"
    1.88 +    "xchg %rsi, %rbx\n"
    1.89 +    :
    1.90 +    : "a"(InfoType), // %eax
    1.91 +      "D"(CPUInfo) // %rdi
    1.92 +    : "%ecx", "%edx", "%rsi"
    1.93 +  );
    1.94 +}
    1.95 +#endif
    1.96 +
    1.97 +static bool
    1.98 +has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit)
    1.99 +{
   1.100 +  // Check that the level in question is supported.
   1.101 +  volatile int regs[4];
   1.102 +  moz_cpuid((int *)regs, level & 0x80000000u);
   1.103 +  if (unsigned(regs[0]) < level)
   1.104 +    return false;
   1.105 +
   1.106 +  moz_cpuid((int *)regs, level);
   1.107 +  return !!(unsigned(regs[reg]) & bit);
   1.108 +}
   1.109 +
   1.110 +#endif // end CPUID declarations
   1.111 +
   1.112 +}
   1.113 +
   1.114 +namespace mozilla {
   1.115 +
   1.116 +namespace sse_private {
   1.117 +
   1.118 +#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.119 +
   1.120 +#if !defined(MOZILLA_PRESUME_MMX)
   1.121 +  bool mmx_enabled = has_cpuid_bit(1u, edx, (1u<<23));
   1.122 +#endif
   1.123 +
   1.124 +#if !defined(MOZILLA_PRESUME_SSE)
   1.125 +  bool sse_enabled = has_cpuid_bit(1u, edx, (1u<<25));
   1.126 +#endif
   1.127 +
   1.128 +#if !defined(MOZILLA_PRESUME_SSE2)
   1.129 +  bool sse2_enabled = has_cpuid_bit(1u, edx, (1u<<26));
   1.130 +#endif
   1.131 +
   1.132 +#if !defined(MOZILLA_PRESUME_SSE3)
   1.133 +  bool sse3_enabled = has_cpuid_bit(1u, ecx, (1u<<0));
   1.134 +#endif
   1.135 +
   1.136 +#if !defined(MOZILLA_PRESUME_SSSE3)
   1.137 +  bool ssse3_enabled = has_cpuid_bit(1u, ecx, (1u<<9));
   1.138 +#endif
   1.139 +
   1.140 +#if !defined(MOZILLA_PRESUME_SSE4A)
   1.141 +  bool sse4a_enabled = has_cpuid_bit(0x80000001u, ecx, (1u<<6));
   1.142 +#endif
   1.143 +
   1.144 +#if !defined(MOZILLA_PRESUME_SSE4_1)
   1.145 +  bool sse4_1_enabled = has_cpuid_bit(1u, ecx, (1u<<19));
   1.146 +#endif
   1.147 +
   1.148 +#if !defined(MOZILLA_PRESUME_SSE4_2)
   1.149 +  bool sse4_2_enabled = has_cpuid_bit(1u, ecx, (1u<<20));
   1.150 +#endif
   1.151 +
   1.152 +#endif
   1.153 +
   1.154 +} // namespace sse_private
   1.155 +} // namespace mozilla

mercurial