LCOV - code coverage report
Current view: top level - mozglue/build - SSE.h (source / functions) Hit Total Coverage
Test: output.info Lines: 11 11 100.0 %
Date: 2017-07-14 16:53:18 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /* compile-time and runtime tests for whether to use SSE instructions */
       7             : 
       8             : #ifndef mozilla_SSE_h_
       9             : #define mozilla_SSE_h_
      10             : 
      11             : // for definition of MFBT_DATA
      12             : #include "mozilla/Types.h"
      13             : 
      14             : /**
      15             :  * The public interface of this header consists of a set of macros and
      16             :  * functions for Intel CPU features.
      17             :  *
      18             :  * DETECTING ISA EXTENSIONS
      19             :  * ========================
      20             :  *
      21             :  * This header provides the following functions for determining whether the
      22             :  * current CPU supports a particular instruction set extension:
      23             :  *
      24             :  *    mozilla::supports_mmx
      25             :  *    mozilla::supports_sse
      26             :  *    mozilla::supports_sse2
      27             :  *    mozilla::supports_sse3
      28             :  *    mozilla::supports_ssse3
      29             :  *    mozilla::supports_sse4a
      30             :  *    mozilla::supports_sse4_1
      31             :  *    mozilla::supports_sse4_2
      32             :  *    mozilla::supports_avx
      33             :  *    mozilla::supports_avx2
      34             :  *    mozilla::supports_aes
      35             :  *
      36             :  * If you're writing code using inline assembly, you should guard it with a
      37             :  * call to one of these functions.  For instance:
      38             :  *
      39             :  *   if (mozilla::supports_sse2()) {
      40             :  *     asm(" ... ");
      41             :  *   }
      42             :  *   else {
      43             :  *     ...
      44             :  *   }
      45             :  *
      46             :  * Note that these functions depend on cpuid intrinsics only available in gcc
      47             :  * 4.3 or later and MSVC 8.0 (Visual C++ 2005) or later, so they return false
      48             :  * in older compilers.  (This could be fixed by replacing the code with inline
      49             :  * assembly.)
      50             :  *
      51             :  *
      52             :  * USING INTRINSICS
      53             :  * ================
      54             :  *
      55             :  * This header also provides support for coding using CPU intrinsics.
      56             :  *
      57             :  * For each mozilla::supports_abc function, we define a MOZILLA_MAY_SUPPORT_ABC
      58             :  * macro which indicates that the target/compiler combination we're using is
      59             :  * compatible with the ABC extension.  For instance, x86_64 with MSVC 2003 is
      60             :  * compatible with SSE2 but not SSE3, since although there exist x86_64 CPUs
      61             :  * with SSE3 support, MSVC 2003 only supports through SSE2.
      62             :  *
      63             :  * Until gcc fixes #pragma target [1] [2] or our x86 builds require SSE2,
      64             :  * you'll need to separate code using intrinsics into a file separate from your
      65             :  * regular code.  Here's the recommended pattern:
      66             :  *
      67             :  *  #ifdef MOZILLA_MAY_SUPPORT_ABC
      68             :  *    namespace mozilla {
      69             :  *      namespace ABC {
      70             :  *        void foo();
      71             :  *      }
      72             :  *    }
      73             :  *  #endif
      74             :  *
      75             :  *  void foo() {
      76             :  *    #ifdef MOZILLA_MAY_SUPPORT_ABC
      77             :  *      if (mozilla::supports_abc()) {
      78             :  *        mozilla::ABC::foo(); // in a separate file
      79             :  *        return;
      80             :  *      }
      81             :  *    #endif
      82             :  *
      83             :  *    foo_unvectorized();
      84             :  *  }
      85             :  *
      86             :  * You'll need to define mozilla::ABC::foo() in a separate file and add the
      87             :  * -mabc flag when using gcc.
      88             :  *
      89             :  * [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39787 and
      90             :  * [2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41201 being fixed.
      91             :  *
      92             :  */
      93             : 
      94             : #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
      95             : 
      96             : #ifdef __MMX__
      97             :   // It's ok to use MMX instructions based on the -march option (or
      98             :   // the default for x86_64 or for Intel Mac).
      99             :   #define MOZILLA_PRESUME_MMX 1
     100             : #endif
     101             : #ifdef __SSE__
     102             :   // It's ok to use SSE instructions based on the -march option (or
     103             :   // the default for x86_64 or for Intel Mac).
     104             :   #define MOZILLA_PRESUME_SSE 1
     105             : #endif
     106             : #ifdef __SSE2__
     107             :   // It's ok to use SSE2 instructions based on the -march option (or
     108             :   // the default for x86_64 or for Intel Mac).
     109             :   #define MOZILLA_PRESUME_SSE2 1
     110             : #endif
     111             : #ifdef __SSE3__
     112             :   // It's ok to use SSE3 instructions based on the -march option (or the
     113             :   // default for Intel Mac).
     114             :   #define MOZILLA_PRESUME_SSE3 1
     115             : #endif
     116             : #ifdef __SSSE3__
     117             :   // It's ok to use SSSE3 instructions based on the -march option.
     118             :   #define MOZILLA_PRESUME_SSSE3 1
     119             : #endif
     120             : #ifdef __SSE4A__
     121             :   // It's ok to use SSE4A instructions based on the -march option.
     122             :   #define MOZILLA_PRESUME_SSE4A 1
     123             : #endif
     124             : #ifdef __SSE4_1__
     125             :   // It's ok to use SSE4.1 instructions based on the -march option.
     126             :   #define MOZILLA_PRESUME_SSE4_1 1
     127             : #endif
     128             : #ifdef __SSE4_2__
     129             :   // It's ok to use SSE4.2 instructions based on the -march option.
     130             :   #define MOZILLA_PRESUME_SSE4_2 1
     131             : #endif
     132             : #ifdef __AVX__
     133             :   // It's ok to use AVX instructions based on the -march option.
     134             :   #define MOZILLA_PRESUME_AVX 1
     135             : #endif
     136             : #ifdef __AVX2__
     137             :   // It's ok to use AVX instructions based on the -march option.
     138             :   #define MOZILLA_PRESUME_AVX2 1
     139             : #endif
     140             : #ifdef __AES__
     141             :   // It's ok to use AES instructions based on the -march option.
     142             :   #define MOZILLA_PRESUME_AES 1
     143             : #endif
     144             : 
     145             : 
     146             : 
     147             : #ifdef HAVE_CPUID_H
     148             :   #define MOZILLA_SSE_HAVE_CPUID_DETECTION
     149             : #endif
     150             : 
     151             : #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
     152             : 
     153             : #define MOZILLA_SSE_HAVE_CPUID_DETECTION
     154             : 
     155             : #if defined(_M_IX86_FP)
     156             : 
     157             : #if _M_IX86_FP >= 1
     158             :   // It's ok to use SSE instructions based on the /arch option
     159             :   #define MOZILLA_PRESUME_SSE
     160             : #endif
     161             : #if _M_IX86_FP >= 2
     162             :   // It's ok to use SSE2 instructions based on the /arch option
     163             :   #define MOZILLA_PRESUME_SSE2
     164             : #endif
     165             : 
     166             : #elif defined(_M_AMD64)
     167             :   // MSVC for AMD64 doesn't support MMX, so don't presume it here.
     168             : 
     169             :   // SSE is always available on AMD64.
     170             :   #define MOZILLA_PRESUME_SSE
     171             :   // SSE2 is always available on AMD64.
     172             :   #define MOZILLA_PRESUME_SSE2
     173             : #endif
     174             : 
     175             : #elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
     176             : // Sun Studio on x86 or amd64
     177             : 
     178             : #define MOZILLA_SSE_HAVE_CPUID_DETECTION
     179             : 
     180             : #if defined(__x86_64__)
     181             :   // MMX is always available on AMD64.
     182             :   #define MOZILLA_PRESUME_MMX
     183             :   // SSE is always available on AMD64.
     184             :   #define MOZILLA_PRESUME_SSE
     185             :   // SSE2 is always available on AMD64.
     186             :   #define MOZILLA_PRESUME_SSE2
     187             : #endif
     188             : 
     189             : #endif
     190             : 
     191             : namespace mozilla {
     192             : 
     193             :   namespace sse_private {
     194             : #if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     195             : #if !defined(MOZILLA_PRESUME_MMX)
     196             :     extern bool MFBT_DATA mmx_enabled;
     197             : #endif
     198             : #if !defined(MOZILLA_PRESUME_SSE)
     199             :     extern bool MFBT_DATA sse_enabled;
     200             : #endif
     201             : #if !defined(MOZILLA_PRESUME_SSE2)
     202             :     extern bool MFBT_DATA sse2_enabled;
     203             : #endif
     204             : #if !defined(MOZILLA_PRESUME_SSE3)
     205             :     extern bool MFBT_DATA sse3_enabled;
     206             : #endif
     207             : #if !defined(MOZILLA_PRESUME_SSSE3)
     208             :     extern bool MFBT_DATA ssse3_enabled;
     209             : #endif
     210             : #if !defined(MOZILLA_PRESUME_SSE4A)
     211             :     extern bool MFBT_DATA sse4a_enabled;
     212             : #endif
     213             : #if !defined(MOZILLA_PRESUME_SSE4_1)
     214             :     extern bool MFBT_DATA sse4_1_enabled;
     215             : #endif
     216             : #if !defined(MOZILLA_PRESUME_SSE4_2)
     217             :     extern bool MFBT_DATA sse4_2_enabled;
     218             : #endif
     219             : #if !defined(MOZILLA_PRESUME_AVX)
     220             :     extern bool MFBT_DATA avx_enabled;
     221             : #endif
     222             : #if !defined(MOZILLA_PRESUME_AVX2)
     223             :     extern bool MFBT_DATA avx2_enabled;
     224             : #endif
     225             : #if !defined(MOZILLA_PRESUME_AES)
     226             :     extern bool MFBT_DATA aes_enabled;
     227             : #endif
     228             : 
     229             : 
     230             : #endif
     231             :   } // namespace sse_private
     232             : 
     233             : #if defined(MOZILLA_PRESUME_MMX)
     234             : #define MOZILLA_MAY_SUPPORT_MMX 1
     235           1 :   inline bool supports_mmx() { return true; }
     236             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     237             : #if !(defined(_MSC_VER) && defined(_M_AMD64))
     238             :   // Define MOZILLA_MAY_SUPPORT_MMX only if we're not on MSVC for
     239             :   // AMD64, since that compiler doesn't support MMX.
     240             : #define MOZILLA_MAY_SUPPORT_MMX 1
     241             : #endif
     242             :   inline bool supports_mmx() { return sse_private::mmx_enabled; }
     243             : #else
     244             :   inline bool supports_mmx() { return false; }
     245             : #endif
     246             : 
     247             : #if defined(MOZILLA_PRESUME_SSE)
     248             : #define MOZILLA_MAY_SUPPORT_SSE 1
     249           1 :   inline bool supports_sse() { return true; }
     250             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     251             : #define MOZILLA_MAY_SUPPORT_SSE 1
     252             :   inline bool supports_sse() { return sse_private::sse_enabled; }
     253             : #else
     254             :   inline bool supports_sse() { return false; }
     255             : #endif
     256             : 
     257             : #if defined(MOZILLA_PRESUME_SSE2)
     258             : #define MOZILLA_MAY_SUPPORT_SSE2 1
     259        9802 :   inline bool supports_sse2() { return true; }
     260             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     261             : #define MOZILLA_MAY_SUPPORT_SSE2 1
     262             :   inline bool supports_sse2() { return sse_private::sse2_enabled; }
     263             : #else
     264             :   inline bool supports_sse2() { return false; }
     265             : #endif
     266             : 
     267             : #if defined(MOZILLA_PRESUME_SSE3)
     268             : #define MOZILLA_MAY_SUPPORT_SSE3 1
     269             :   inline bool supports_sse3() { return true; }
     270             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     271             : #define MOZILLA_MAY_SUPPORT_SSE3 1
     272           1 :   inline bool supports_sse3() { return sse_private::sse3_enabled; }
     273             : #else
     274             :   inline bool supports_sse3() { return false; }
     275             : #endif
     276             : 
     277             : #if defined(MOZILLA_PRESUME_SSSE3)
     278             : #define MOZILLA_MAY_SUPPORT_SSSE3 1
     279             :   inline bool supports_ssse3() { return true; }
     280             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     281             : #define MOZILLA_MAY_SUPPORT_SSSE3 1
     282           1 :   inline bool supports_ssse3() { return sse_private::ssse3_enabled; }
     283             : #else
     284             :   inline bool supports_ssse3() { return false; }
     285             : #endif
     286             : 
     287             : #if defined(MOZILLA_PRESUME_SSE4A)
     288             : #define MOZILLA_MAY_SUPPORT_SSE4A 1
     289             :   inline bool supports_sse4a() { return true; }
     290             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     291             : #define MOZILLA_MAY_SUPPORT_SSE4A 1
     292           1 :   inline bool supports_sse4a() { return sse_private::sse4a_enabled; }
     293             : #else
     294             :   inline bool supports_sse4a() { return false; }
     295             : #endif
     296             : 
     297             : #if defined(MOZILLA_PRESUME_SSE4_1)
     298             : #define MOZILLA_MAY_SUPPORT_SSE4_1 1
     299             :   inline bool supports_sse4_1() { return true; }
     300             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     301             : #define MOZILLA_MAY_SUPPORT_SSE4_1 1
     302           1 :   inline bool supports_sse4_1() { return sse_private::sse4_1_enabled; }
     303             : #else
     304             :   inline bool supports_sse4_1() { return false; }
     305             : #endif
     306             : 
     307             : #if defined(MOZILLA_PRESUME_SSE4_2)
     308             : #define MOZILLA_MAY_SUPPORT_SSE4_2 1
     309             :   inline bool supports_sse4_2() { return true; }
     310             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     311             : #define MOZILLA_MAY_SUPPORT_SSE4_2 1
     312           1 :   inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; }
     313             : #else
     314             :   inline bool supports_sse4_2() { return false; }
     315             : #endif
     316             : 
     317             : #if defined(MOZILLA_PRESUME_AVX)
     318             : #define MOZILLA_MAY_SUPPORT_AVX 1
     319             :   inline bool supports_avx() { return true; }
     320             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     321             : #define MOZILLA_MAY_SUPPORT_AVX 1
     322           1 :   inline bool supports_avx() { return sse_private::avx_enabled; }
     323             : #else
     324             :   inline bool supports_avx() { return false; }
     325             : #endif
     326             : 
     327             : #if defined(MOZILLA_PRESUME_AVX2)
     328             : #define MOZILLA_MAY_SUPPORT_AVX2 1
     329             :   inline bool supports_avx2() { return true; }
     330             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     331             : #define MOZILLA_MAY_SUPPORT_AVX2 1
     332           1 :   inline bool supports_avx2() { return sse_private::avx2_enabled; }
     333             : #else
     334             :   inline bool supports_avx2() { return false; }
     335             : #endif
     336             : 
     337             : #if defined(MOZILLA_PRESUME_AES)
     338             : #define MOZILLA_MAY_SUPPORT_AES 1
     339             :   inline bool supports_aes() { return true; }
     340             : #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
     341             : #define MOZILLA_MAY_SUPPORT_AES 1
     342           1 :   inline bool supports_aes() { return sse_private::aes_enabled; }
     343             : #else
     344             :   inline bool supports_aes() { return false; }
     345             : #endif
     346             : 
     347             : 
     348             : } // namespace mozilla
     349             : 
     350             : #endif /* !defined(mozilla_SSE_h_) */

Generated by: LCOV version 1.13