mozglue/build/SSE.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mozglue/build/SSE.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,291 @@
     1.4 +/* vim: set shiftwidth=2 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 +#ifndef mozilla_SSE_h_
    1.12 +#define mozilla_SSE_h_
    1.13 +
    1.14 +// for definition of MFBT_DATA
    1.15 +#include "mozilla/Types.h"
    1.16 +
    1.17 +/**
    1.18 + * The public interface of this header consists of a set of macros and
    1.19 + * functions for Intel CPU features.
    1.20 + *
    1.21 + * DETECTING ISA EXTENSIONS
    1.22 + * ========================
    1.23 + *
    1.24 + * This header provides the following functions for determining whether the
    1.25 + * current CPU supports a particular instruction set extension:
    1.26 + *
    1.27 + *    mozilla::supports_mmx
    1.28 + *    mozilla::supports_sse
    1.29 + *    mozilla::supports_sse2
    1.30 + *    mozilla::supports_sse3
    1.31 + *    mozilla::supports_ssse3
    1.32 + *    mozilla::supports_sse4a
    1.33 + *    mozilla::supports_sse4_1
    1.34 + *    mozilla::supports_sse4_2
    1.35 + *
    1.36 + * If you're writing code using inline assembly, you should guard it with a
    1.37 + * call to one of these functions.  For instance:
    1.38 + *
    1.39 + *   if (mozilla::supports_sse2()) {
    1.40 + *     asm(" ... ");
    1.41 + *   }
    1.42 + *   else {
    1.43 + *     ...
    1.44 + *   }
    1.45 + *
    1.46 + * Note that these functions depend on cpuid intrinsics only available in gcc
    1.47 + * 4.3 or later and MSVC 8.0 (Visual C++ 2005) or later, so they return false
    1.48 + * in older compilers.  (This could be fixed by replacing the code with inline
    1.49 + * assembly.)
    1.50 + *
    1.51 + *
    1.52 + * USING INTRINSICS
    1.53 + * ================
    1.54 + *
    1.55 + * This header also provides support for coding using CPU intrinsics.
    1.56 + *
    1.57 + * For each mozilla::supports_abc function, we define a MOZILLA_MAY_SUPPORT_ABC
    1.58 + * macro which indicates that the target/compiler combination we're using is
    1.59 + * compatible with the ABC extension.  For instance, x86_64 with MSVC 2003 is
    1.60 + * compatible with SSE2 but not SSE3, since although there exist x86_64 CPUs
    1.61 + * with SSE3 support, MSVC 2003 only supports through SSE2.
    1.62 + *
    1.63 + * Until gcc fixes #pragma target [1] [2] or our x86 builds require SSE2,
    1.64 + * you'll need to separate code using intrinsics into a file separate from your
    1.65 + * regular code.  Here's the recommended pattern:
    1.66 + *
    1.67 + *  #ifdef MOZILLA_MAY_SUPPORT_ABC
    1.68 + *    namespace mozilla {
    1.69 + *      namespace ABC {
    1.70 + *        void foo();
    1.71 + *      }
    1.72 + *    }
    1.73 + *  #endif
    1.74 + *
    1.75 + *  void foo() {
    1.76 + *    #ifdef MOZILLA_MAY_SUPPORT_ABC
    1.77 + *      if (mozilla::supports_abc()) {
    1.78 + *        mozilla::ABC::foo(); // in a separate file
    1.79 + *        return;
    1.80 + *      }
    1.81 + *    #endif
    1.82 + *
    1.83 + *    foo_unvectorized();
    1.84 + *  }
    1.85 + *
    1.86 + * You'll need to define mozilla::ABC::foo() in a separate file and add the
    1.87 + * -mabc flag when using gcc.
    1.88 + *
    1.89 + * [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39787 and
    1.90 + * [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41201 being fixed.
    1.91 + *
    1.92 + */
    1.93 +
    1.94 +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
    1.95 +
    1.96 +#ifdef __MMX__
    1.97 +  // It's ok to use MMX instructions based on the -march option (or
    1.98 +  // the default for x86_64 or for Intel Mac).
    1.99 +  #define MOZILLA_PRESUME_MMX 1
   1.100 +#endif
   1.101 +#ifdef __SSE__
   1.102 +  // It's ok to use SSE instructions based on the -march option (or
   1.103 +  // the default for x86_64 or for Intel Mac).
   1.104 +  #define MOZILLA_PRESUME_SSE 1
   1.105 +#endif
   1.106 +#ifdef __SSE2__
   1.107 +  // It's ok to use SSE2 instructions based on the -march option (or
   1.108 +  // the default for x86_64 or for Intel Mac).
   1.109 +  #define MOZILLA_PRESUME_SSE2 1
   1.110 +#endif
   1.111 +#ifdef __SSE3__
   1.112 +  // It's ok to use SSE3 instructions based on the -march option (or the
   1.113 +  // default for Intel Mac).
   1.114 +  #define MOZILLA_PRESUME_SSE3 1
   1.115 +#endif
   1.116 +#ifdef __SSSE3__
   1.117 +  // It's ok to use SSSE3 instructions based on the -march option.
   1.118 +  #define MOZILLA_PRESUME_SSSE3 1
   1.119 +#endif
   1.120 +#ifdef __SSE4A__
   1.121 +  // It's ok to use SSE4A instructions based on the -march option.
   1.122 +  #define MOZILLA_PRESUME_SSE4A 1
   1.123 +#endif
   1.124 +#ifdef __SSE4_1__
   1.125 +  // It's ok to use SSE4.1 instructions based on the -march option.
   1.126 +  #define MOZILLA_PRESUME_SSE4_1 1
   1.127 +#endif
   1.128 +#ifdef __SSE4_2__
   1.129 +  // It's ok to use SSE4.2 instructions based on the -march option.
   1.130 +  #define MOZILLA_PRESUME_SSE4_2 1
   1.131 +#endif
   1.132 +
   1.133 +#ifdef HAVE_CPUID_H
   1.134 +  #define MOZILLA_SSE_HAVE_CPUID_DETECTION
   1.135 +#endif
   1.136 +
   1.137 +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
   1.138 +
   1.139 +#define MOZILLA_SSE_HAVE_CPUID_DETECTION
   1.140 +
   1.141 +#if defined(_M_IX86_FP)
   1.142 +
   1.143 +#if _M_IX86_FP >= 1
   1.144 +  // It's ok to use SSE instructions based on the /arch option
   1.145 +  #define MOZILLA_PRESUME_SSE
   1.146 +#endif
   1.147 +#if _M_IX86_FP >= 2
   1.148 +  // It's ok to use SSE2 instructions based on the /arch option
   1.149 +  #define MOZILLA_PRESUME_SSE2
   1.150 +#endif
   1.151 +
   1.152 +#elif defined(_M_AMD64)
   1.153 +  // MSVC for AMD64 doesn't support MMX, so don't presume it here.
   1.154 +
   1.155 +  // SSE is always available on AMD64.
   1.156 +  #define MOZILLA_PRESUME_SSE
   1.157 +  // SSE2 is always available on AMD64.
   1.158 +  #define MOZILLA_PRESUME_SSE2
   1.159 +#endif
   1.160 +
   1.161 +#elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
   1.162 +// Sun Studio on x86 or amd64
   1.163 +
   1.164 +#define MOZILLA_SSE_HAVE_CPUID_DETECTION
   1.165 +
   1.166 +#if defined(__x86_64__)
   1.167 +  // MMX is always available on AMD64.
   1.168 +  #define MOZILLA_PRESUME_MMX
   1.169 +  // SSE is always available on AMD64.
   1.170 +  #define MOZILLA_PRESUME_SSE
   1.171 +  // SSE2 is always available on AMD64.
   1.172 +  #define MOZILLA_PRESUME_SSE2
   1.173 +#endif
   1.174 +
   1.175 +#endif
   1.176 +
   1.177 +namespace mozilla {
   1.178 +
   1.179 +  namespace sse_private {
   1.180 +#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.181 +#if !defined(MOZILLA_PRESUME_MMX)
   1.182 +    extern bool MFBT_DATA mmx_enabled;
   1.183 +#endif
   1.184 +#if !defined(MOZILLA_PRESUME_SSE)
   1.185 +    extern bool MFBT_DATA sse_enabled;
   1.186 +#endif
   1.187 +#if !defined(MOZILLA_PRESUME_SSE2)
   1.188 +    extern bool MFBT_DATA sse2_enabled;
   1.189 +#endif
   1.190 +#if !defined(MOZILLA_PRESUME_SSE3)
   1.191 +    extern bool MFBT_DATA sse3_enabled;
   1.192 +#endif
   1.193 +#if !defined(MOZILLA_PRESUME_SSSE3)
   1.194 +    extern bool MFBT_DATA ssse3_enabled;
   1.195 +#endif
   1.196 +#if !defined(MOZILLA_PRESUME_SSE4A)
   1.197 +    extern bool MFBT_DATA sse4a_enabled;
   1.198 +#endif
   1.199 +#if !defined(MOZILLA_PRESUME_SSE4_1)
   1.200 +    extern bool MFBT_DATA sse4_1_enabled;
   1.201 +#endif
   1.202 +#if !defined(MOZILLA_PRESUME_SSE4_2)
   1.203 +    extern bool MFBT_DATA sse4_2_enabled;
   1.204 +#endif
   1.205 +#endif
   1.206 +  }
   1.207 +
   1.208 +#if defined(MOZILLA_PRESUME_MMX)
   1.209 +#define MOZILLA_MAY_SUPPORT_MMX 1
   1.210 +  inline bool supports_mmx() { return true; }
   1.211 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.212 +#if !(defined(_MSC_VER) && defined(_M_AMD64))
   1.213 +  // Define MOZILLA_MAY_SUPPORT_MMX only if we're not on MSVC for
   1.214 +  // AMD64, since that compiler doesn't support MMX.
   1.215 +#define MOZILLA_MAY_SUPPORT_MMX 1
   1.216 +#endif
   1.217 +  inline bool supports_mmx() { return sse_private::mmx_enabled; }
   1.218 +#else
   1.219 +  inline bool supports_mmx() { return false; }
   1.220 +#endif
   1.221 +
   1.222 +#if defined(MOZILLA_PRESUME_SSE)
   1.223 +#define MOZILLA_MAY_SUPPORT_SSE 1
   1.224 +  inline bool supports_sse() { return true; }
   1.225 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.226 +#define MOZILLA_MAY_SUPPORT_SSE 1
   1.227 +  inline bool supports_sse() { return sse_private::sse_enabled; }
   1.228 +#else
   1.229 +  inline bool supports_sse() { return false; }
   1.230 +#endif
   1.231 +
   1.232 +#if defined(MOZILLA_PRESUME_SSE2)
   1.233 +#define MOZILLA_MAY_SUPPORT_SSE2 1
   1.234 +  inline bool supports_sse2() { return true; }
   1.235 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.236 +#define MOZILLA_MAY_SUPPORT_SSE2 1
   1.237 +  inline bool supports_sse2() { return sse_private::sse2_enabled; }
   1.238 +#else
   1.239 +  inline bool supports_sse2() { return false; }
   1.240 +#endif
   1.241 +
   1.242 +#if defined(MOZILLA_PRESUME_SSE3)
   1.243 +#define MOZILLA_MAY_SUPPORT_SSE3 1
   1.244 +  inline bool supports_sse3() { return true; }
   1.245 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.246 +#define MOZILLA_MAY_SUPPORT_SSE3 1
   1.247 +  inline bool supports_sse3() { return sse_private::sse3_enabled; }
   1.248 +#else
   1.249 +  inline bool supports_sse3() { return false; }
   1.250 +#endif
   1.251 +
   1.252 +#if defined(MOZILLA_PRESUME_SSSE3)
   1.253 +#define MOZILLA_MAY_SUPPORT_SSSE3 1
   1.254 +  inline bool supports_ssse3() { return true; }
   1.255 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.256 +#define MOZILLA_MAY_SUPPORT_SSSE3 1
   1.257 +  inline bool supports_ssse3() { return sse_private::ssse3_enabled; }
   1.258 +#else
   1.259 +  inline bool supports_ssse3() { return false; }
   1.260 +#endif
   1.261 +
   1.262 +#if defined(MOZILLA_PRESUME_SSE4A)
   1.263 +#define MOZILLA_MAY_SUPPORT_SSE4A 1
   1.264 +  inline bool supports_sse4a() { return true; }
   1.265 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.266 +#define MOZILLA_MAY_SUPPORT_SSE4A 1
   1.267 +  inline bool supports_sse4a() { return sse_private::sse4a_enabled; }
   1.268 +#else
   1.269 +  inline bool supports_sse4a() { return false; }
   1.270 +#endif
   1.271 +
   1.272 +#if defined(MOZILLA_PRESUME_SSE4_1)
   1.273 +#define MOZILLA_MAY_SUPPORT_SSE4_1 1
   1.274 +  inline bool supports_sse4_1() { return true; }
   1.275 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.276 +#define MOZILLA_MAY_SUPPORT_SSE4_1 1
   1.277 +  inline bool supports_sse4_1() { return sse_private::sse4_1_enabled; }
   1.278 +#else
   1.279 +  inline bool supports_sse4_1() { return false; }
   1.280 +#endif
   1.281 +
   1.282 +#if defined(MOZILLA_PRESUME_SSE4_2)
   1.283 +#define MOZILLA_MAY_SUPPORT_SSE4_2 1
   1.284 +  inline bool supports_sse4_2() { return true; }
   1.285 +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
   1.286 +#define MOZILLA_MAY_SUPPORT_SSE4_2 1
   1.287 +  inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; }
   1.288 +#else
   1.289 +  inline bool supports_sse4_2() { return false; }
   1.290 +#endif
   1.291 +
   1.292 +}
   1.293 +
   1.294 +#endif /* !defined(mozilla_SSE_h_) */

mercurial