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_) */