1 /* vim: set shiftwidth=4 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/. */
6 /* compile-time and runtime tests for whether to use SSE instructions */
12 // SSE.h has parallel #ifs which declare MOZILLA_SSE_HAVE_CPUID_DETECTION.
13 // We can't declare these functions in the header file, however, because
14 // <intrin.h> conflicts with <windows.h> on MSVC 2005, and some files want to
15 // include both SSE.h and <windows.h>.
19 // cpuid.h is available on gcc 4.3 and higher on i386 and x86_64
22 enum CPUIDRegister
{ eax
= 0, ebx
= 1, ecx
= 2, edx
= 3 };
25 has_cpuid_bit(unsigned int level
, CPUIDRegister reg
, unsigned int bit
)
28 return __get_cpuid(level
, ®s
[0], ®s
[1], ®s
[2], ®s
[3]) &&
32 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
34 // MSVC 2005 or newer on x86-32 or x86-64
37 enum CPUIDRegister
{ eax
= 0, ebx
= 1, ecx
= 2, edx
= 3 };
40 has_cpuid_bit(unsigned int level
, CPUIDRegister reg
, unsigned int bit
)
42 // Check that the level in question is supported.
44 __cpuid(regs
, level
& 0x80000000u
);
45 if (unsigned(regs
[0]) < level
)
49 return !!(unsigned(regs
[reg
]) & bit
);
52 #elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
54 enum CPUIDRegister
{ eax
= 0, ebx
= 1, ecx
= 2, edx
= 3 };
58 moz_cpuid(int CPUInfo
[4], int InfoType
)
64 "movl %ebx, 4(%edi)\n"
65 "movl %ecx, 8(%edi)\n"
66 "movl %edx, 12(%edi)\n"
69 : "a"(InfoType
), // %eax
71 : "%ecx", "%edx", "%esi"
76 moz_cpuid(int CPUInfo
[4], int InfoType
)
82 "movl %ebx, 4(%rdi)\n"
83 "movl %ecx, 8(%rdi)\n"
84 "movl %edx, 12(%rdi)\n"
87 : "a"(InfoType
), // %eax
89 : "%ecx", "%edx", "%rsi"
95 has_cpuid_bit(unsigned int level
, CPUIDRegister reg
, unsigned int bit
)
97 // Check that the level in question is supported.
99 moz_cpuid((int *)regs
, level
& 0x80000000u
);
100 if (unsigned(regs
[0]) < level
)
103 moz_cpuid((int *)regs
, level
);
104 return !!(unsigned(regs
[reg
]) & bit
);
107 #endif // end CPUID declarations
113 namespace sse_private
{
115 #if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
117 #if !defined(MOZILLA_PRESUME_MMX)
118 bool mmx_enabled
= has_cpuid_bit(1u, edx
, (1u<<23));
121 #if !defined(MOZILLA_PRESUME_SSE)
122 bool sse_enabled
= has_cpuid_bit(1u, edx
, (1u<<25));
125 #if !defined(MOZILLA_PRESUME_SSE2)
126 bool sse2_enabled
= has_cpuid_bit(1u, edx
, (1u<<26));
129 #if !defined(MOZILLA_PRESUME_SSE3)
130 bool sse3_enabled
= has_cpuid_bit(1u, ecx
, (1u<<0));
133 #if !defined(MOZILLA_PRESUME_SSSE3)
134 bool ssse3_enabled
= has_cpuid_bit(1u, ecx
, (1u<<9));
137 #if !defined(MOZILLA_PRESUME_SSE4A)
138 bool sse4a_enabled
= has_cpuid_bit(0x80000001u
, ecx
, (1u<<6));
141 #if !defined(MOZILLA_PRESUME_SSE4_1)
142 bool sse4_1_enabled
= has_cpuid_bit(1u, ecx
, (1u<<19));
145 #if !defined(MOZILLA_PRESUME_SSE4_2)
146 bool sse4_2_enabled
= has_cpuid_bit(1u, ecx
, (1u<<20));
151 } // namespace sse_private
152 } // namespace mozilla