123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /* compile-time and runtime tests for whether to use SSE instructions */
- #ifndef mozilla_SSE_h_
- #define mozilla_SSE_h_
- // for definition of MFBT_DATA
- #include "mozilla/Types.h"
- /**
- * The public interface of this header consists of a set of macros and
- * functions for Intel CPU features.
- *
- * DETECTING ISA EXTENSIONS
- * ========================
- *
- * This header provides the following functions for determining whether the
- * current CPU supports a particular instruction set extension:
- *
- * mozilla::supports_mmx
- * mozilla::supports_sse
- * mozilla::supports_sse2
- * mozilla::supports_sse3
- * mozilla::supports_ssse3
- * mozilla::supports_sse4a
- * mozilla::supports_sse4_1
- * mozilla::supports_sse4_2
- * mozilla::supports_avx
- * mozilla::supports_avx2
- *
- * If you're writing code using inline assembly, you should guard it with a
- * call to one of these functions. For instance:
- *
- * if (mozilla::supports_sse2()) {
- * asm(" ... ");
- * }
- * else {
- * ...
- * }
- *
- * Note that these functions depend on cpuid intrinsics only available in gcc
- * 4.3 or later and MSVC 8.0 (Visual C++ 2005) or later, so they return false
- * in older compilers. (This could be fixed by replacing the code with inline
- * assembly.)
- *
- *
- * USING INTRINSICS
- * ================
- *
- * This header also provides support for coding using CPU intrinsics.
- *
- * For each mozilla::supports_abc function, we define a MOZILLA_MAY_SUPPORT_ABC
- * macro which indicates that the target/compiler combination we're using is
- * compatible with the ABC extension. For instance, x86_64 with MSVC 2003 is
- * compatible with SSE2 but not SSE3, since although there exist x86_64 CPUs
- * with SSE3 support, MSVC 2003 only supports through SSE2.
- *
- * Until gcc fixes #pragma target [1] [2] or our x86 builds require SSE2,
- * you'll need to separate code using intrinsics into a file separate from your
- * regular code. Here's the recommended pattern:
- *
- * #ifdef MOZILLA_MAY_SUPPORT_ABC
- * namespace mozilla {
- * namespace ABC {
- * void foo();
- * }
- * }
- * #endif
- *
- * void foo() {
- * #ifdef MOZILLA_MAY_SUPPORT_ABC
- * if (mozilla::supports_abc()) {
- * mozilla::ABC::foo(); // in a separate file
- * return;
- * }
- * #endif
- *
- * foo_unvectorized();
- * }
- *
- * You'll need to define mozilla::ABC::foo() in a separate file and add the
- * -mabc flag when using gcc.
- *
- * [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39787 and
- * [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41201 being fixed.
- *
- */
- #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
- #ifdef __MMX__
- // It's ok to use MMX instructions based on the -march option (or
- // the default for x86_64 or for Intel Mac).
- #define MOZILLA_PRESUME_MMX 1
- #endif
- #ifdef __SSE__
- // It's ok to use SSE instructions based on the -march option (or
- // the default for x86_64 or for Intel Mac).
- #define MOZILLA_PRESUME_SSE 1
- #endif
- #ifdef __SSE2__
- // It's ok to use SSE2 instructions based on the -march option (or
- // the default for x86_64 or for Intel Mac).
- #define MOZILLA_PRESUME_SSE2 1
- #endif
- #ifdef __SSE3__
- // It's ok to use SSE3 instructions based on the -march option (or the
- // default for Intel Mac).
- #define MOZILLA_PRESUME_SSE3 1
- #endif
- #ifdef __SSSE3__
- // It's ok to use SSSE3 instructions based on the -march option.
- #define MOZILLA_PRESUME_SSSE3 1
- #endif
- #ifdef __SSE4A__
- // It's ok to use SSE4A instructions based on the -march option.
- #define MOZILLA_PRESUME_SSE4A 1
- #endif
- #ifdef __SSE4_1__
- // It's ok to use SSE4.1 instructions based on the -march option.
- #define MOZILLA_PRESUME_SSE4_1 1
- #endif
- #ifdef __SSE4_2__
- // It's ok to use SSE4.2 instructions based on the -march option.
- #define MOZILLA_PRESUME_SSE4_2 1
- #endif
- #ifdef __AVX__
- // It's ok to use AVX instructions based on the -march option.
- #define MOZILLA_PRESUME_AVX 1
- #endif
- #ifdef __AVX2__
- // It's ok to use AVX instructions based on the -march option.
- #define MOZILLA_PRESUME_AVX2 1
- #endif
- #ifdef HAVE_CPUID_H
- #define MOZILLA_SSE_HAVE_CPUID_DETECTION
- #endif
- #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
- #define MOZILLA_SSE_HAVE_CPUID_DETECTION
- #if defined(_M_IX86_FP)
- #if _M_IX86_FP >= 1
- // It's ok to use SSE instructions based on the /arch option
- #define MOZILLA_PRESUME_SSE
- #endif
- #if _M_IX86_FP >= 2
- // It's ok to use SSE2 instructions based on the /arch option
- #define MOZILLA_PRESUME_SSE2
- #endif
- #elif defined(_M_AMD64)
- // MSVC for AMD64 doesn't support MMX, so don't presume it here.
- // SSE is always available on AMD64.
- #define MOZILLA_PRESUME_SSE
- // SSE2 is always available on AMD64.
- #define MOZILLA_PRESUME_SSE2
- #endif
- #elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
- // Sun Studio on x86 or amd64
- #define MOZILLA_SSE_HAVE_CPUID_DETECTION
- #if defined(__x86_64__)
- // MMX is always available on AMD64.
- #define MOZILLA_PRESUME_MMX
- // SSE is always available on AMD64.
- #define MOZILLA_PRESUME_SSE
- // SSE2 is always available on AMD64.
- #define MOZILLA_PRESUME_SSE2
- #endif
- #endif
- namespace mozilla {
- namespace sse_private {
- #if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #if !defined(MOZILLA_PRESUME_MMX)
- extern bool MFBT_DATA mmx_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE)
- extern bool MFBT_DATA sse_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE2)
- extern bool MFBT_DATA sse2_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE3)
- extern bool MFBT_DATA sse3_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSSE3)
- extern bool MFBT_DATA ssse3_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE4A)
- extern bool MFBT_DATA sse4a_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE4_1)
- extern bool MFBT_DATA sse4_1_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_SSE4_2)
- extern bool MFBT_DATA sse4_2_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_AVX)
- extern bool MFBT_DATA avx_enabled;
- #endif
- #if !defined(MOZILLA_PRESUME_AVX2)
- extern bool MFBT_DATA avx2_enabled;
- #endif
- #endif
- } // namespace sse_private
- #if defined(MOZILLA_PRESUME_MMX)
- #define MOZILLA_MAY_SUPPORT_MMX 1
- inline bool supports_mmx() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #if !(defined(_MSC_VER) && defined(_M_AMD64))
- // Define MOZILLA_MAY_SUPPORT_MMX only if we're not on MSVC for
- // AMD64, since that compiler doesn't support MMX.
- #define MOZILLA_MAY_SUPPORT_MMX 1
- #endif
- inline bool supports_mmx() { return sse_private::mmx_enabled; }
- #else
- inline bool supports_mmx() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE)
- #define MOZILLA_MAY_SUPPORT_SSE 1
- inline bool supports_sse() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE 1
- inline bool supports_sse() { return sse_private::sse_enabled; }
- #else
- inline bool supports_sse() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE2)
- #define MOZILLA_MAY_SUPPORT_SSE2 1
- inline bool supports_sse2() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE2 1
- inline bool supports_sse2() { return sse_private::sse2_enabled; }
- #else
- inline bool supports_sse2() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE3)
- #define MOZILLA_MAY_SUPPORT_SSE3 1
- inline bool supports_sse3() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE3 1
- inline bool supports_sse3() { return sse_private::sse3_enabled; }
- #else
- inline bool supports_sse3() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSSE3)
- #define MOZILLA_MAY_SUPPORT_SSSE3 1
- inline bool supports_ssse3() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSSE3 1
- inline bool supports_ssse3() { return sse_private::ssse3_enabled; }
- #else
- inline bool supports_ssse3() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE4A)
- #define MOZILLA_MAY_SUPPORT_SSE4A 1
- inline bool supports_sse4a() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE4A 1
- inline bool supports_sse4a() { return sse_private::sse4a_enabled; }
- #else
- inline bool supports_sse4a() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE4_1)
- #define MOZILLA_MAY_SUPPORT_SSE4_1 1
- inline bool supports_sse4_1() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE4_1 1
- inline bool supports_sse4_1() { return sse_private::sse4_1_enabled; }
- #else
- inline bool supports_sse4_1() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_SSE4_2)
- #define MOZILLA_MAY_SUPPORT_SSE4_2 1
- inline bool supports_sse4_2() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_SSE4_2 1
- inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; }
- #else
- inline bool supports_sse4_2() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_AVX)
- #define MOZILLA_MAY_SUPPORT_AVX 1
- inline bool supports_avx() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_AVX 1
- inline bool supports_avx() { return sse_private::avx_enabled; }
- #else
- inline bool supports_avx() { return false; }
- #endif
- #if defined(MOZILLA_PRESUME_AVX2)
- #define MOZILLA_MAY_SUPPORT_AVX2 1
- inline bool supports_avx2() { return true; }
- #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
- #define MOZILLA_MAY_SUPPORT_AVX2 1
- inline bool supports_avx2() { return sse_private::avx2_enabled; }
- #else
- inline bool supports_avx2() { return false; }
- #endif
- } // namespace mozilla
- #endif /* !defined(mozilla_SSE_h_) */
|