References:
https://bugzilla.mozilla.org/show_bug.cgi?id=513422
diff --git a/xpcom/glue/SSE.h b/xpcom/glue/SSE.h
--- a/xpcom/glue/SSE.h
+++ b/xpcom/glue/SSE.h
@@ -234,32 +234,73 @@
#endif
#ifdef __SSE4_2__
// It's ok to use SSE4.2 instructions based on the -march option.
#define MOZILLA_PRESUME_SSE4_2 1
#endif
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
-// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64
-#include <cpuid.h>
#define MOZILLA_SSE_HAVE_CPUID_DETECTION
namespace mozilla {
namespace sse_private {
enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
+ inline void my__cpuid(unsigned int* regs, unsigned int level)
+ {
+ regs[0] = level;
+# if defined(__i386__)
+ __asm__ __volatile__(
+ "pushl %%ebx" "\n\t"
+ "movl %0, %%edi" "\n\t"
+ "movl 0(%%edi), %%eax" "\n\t"
+ "cpuid" "\n\t"
+ "movl %%eax, 0(%%edi)" "\n\t"
+ "movl %%ebx, 4(%%edi)" "\n\t"
+ "movl %%ecx, 8(%%edi)" "\n\t"
+ "movl %%edx, 12(%%edi)" "\n\t"
+ "popl %%ebx" "\n"
+ : /*out*/
+ : /*in*/"r"(regs)
+ : /*trash*/"edi","eax","ecx","edx","memory","cc"
+ );
+# elif defined(__x86_64__)
+ __asm__ __volatile__(
+ "pushq %%rbx" "\n\t"
+ "movq %0, %%rdi" "\n\t"
+ "movl 0(%%rdi), %%eax" "\n\t"
+ "cpuid" "\n\t"
+ "movl %%eax, 0(%%rdi)" "\n\t"
+ "movl %%ebx, 4(%%rdi)" "\n\t"
+ "movl %%ecx, 8(%%rdi)" "\n\t"
+ "movl %%edx, 12(%%rdi)" "\n\t"
+ "popq %%rbx" "\n"
+ : /*out*/
+ : /*in*/"r"(regs)
+ : /*trash*/"rdi","rax","rcx","rdx","memory","cc"
+ );
+# else
+# error "Hmm, unsupported x86-esque platform"
+# endif
+ }
+
inline bool
has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit)
{
+ // Check that the level in question is supported.
unsigned int regs[4];
- return __get_cpuid(level, ®s[0], ®s[1], ®s[2], ®s[3]) &&
- (regs[reg] & bit);
+ my__cpuid(regs, level & 0x80000000u);
+ if (unsigned(regs[0]) < level)
+ return false;
+
+ my__cpuid(regs, level);
+ return !!(unsigned(regs[reg]) & bit);
}
}
}
#endif