|
1 References: |
|
2 https://bugzilla.mozilla.org/show_bug.cgi?id=513422 |
|
3 |
|
4 diff --git a/xpcom/glue/SSE.h b/xpcom/glue/SSE.h |
|
5 --- a/xpcom/glue/SSE.h |
|
6 +++ b/xpcom/glue/SSE.h |
|
7 @@ -234,32 +234,73 @@ |
|
8 #endif |
|
9 #ifdef __SSE4_2__ |
|
10 // It's ok to use SSE4.2 instructions based on the -march option. |
|
11 #define MOZILLA_PRESUME_SSE4_2 1 |
|
12 #endif |
|
13 |
|
14 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) |
|
15 |
|
16 -// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64 |
|
17 -#include <cpuid.h> |
|
18 #define MOZILLA_SSE_HAVE_CPUID_DETECTION |
|
19 |
|
20 namespace mozilla { |
|
21 |
|
22 namespace sse_private { |
|
23 |
|
24 enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 }; |
|
25 |
|
26 + inline void my__cpuid(unsigned int* regs, unsigned int level) |
|
27 + { |
|
28 + regs[0] = level; |
|
29 +# if defined(__i386__) |
|
30 + __asm__ __volatile__( |
|
31 + "pushl %%ebx" "\n\t" |
|
32 + "movl %0, %%edi" "\n\t" |
|
33 + "movl 0(%%edi), %%eax" "\n\t" |
|
34 + "cpuid" "\n\t" |
|
35 + "movl %%eax, 0(%%edi)" "\n\t" |
|
36 + "movl %%ebx, 4(%%edi)" "\n\t" |
|
37 + "movl %%ecx, 8(%%edi)" "\n\t" |
|
38 + "movl %%edx, 12(%%edi)" "\n\t" |
|
39 + "popl %%ebx" "\n" |
|
40 + : /*out*/ |
|
41 + : /*in*/"r"(regs) |
|
42 + : /*trash*/"edi","eax","ecx","edx","memory","cc" |
|
43 + ); |
|
44 +# elif defined(__x86_64__) |
|
45 + __asm__ __volatile__( |
|
46 + "pushq %%rbx" "\n\t" |
|
47 + "movq %0, %%rdi" "\n\t" |
|
48 + "movl 0(%%rdi), %%eax" "\n\t" |
|
49 + "cpuid" "\n\t" |
|
50 + "movl %%eax, 0(%%rdi)" "\n\t" |
|
51 + "movl %%ebx, 4(%%rdi)" "\n\t" |
|
52 + "movl %%ecx, 8(%%rdi)" "\n\t" |
|
53 + "movl %%edx, 12(%%rdi)" "\n\t" |
|
54 + "popq %%rbx" "\n" |
|
55 + : /*out*/ |
|
56 + : /*in*/"r"(regs) |
|
57 + : /*trash*/"rdi","rax","rcx","rdx","memory","cc" |
|
58 + ); |
|
59 +# else |
|
60 +# error "Hmm, unsupported x86-esque platform" |
|
61 +# endif |
|
62 + } |
|
63 + |
|
64 inline bool |
|
65 has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit) |
|
66 { |
|
67 + // Check that the level in question is supported. |
|
68 unsigned int regs[4]; |
|
69 - return __get_cpuid(level, ®s[0], ®s[1], ®s[2], ®s[3]) && |
|
70 - (regs[reg] & bit); |
|
71 + my__cpuid(regs, level & 0x80000000u); |
|
72 + if (unsigned(regs[0]) < level) |
|
73 + return false; |
|
74 + |
|
75 + my__cpuid(regs, level); |
|
76 + return !!(unsigned(regs[reg]) & bit); |
|
77 } |
|
78 |
|
79 } |
|
80 |
|
81 } |
|
82 |
|
83 #endif |
|
84 |