mozglue/build/arm.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:6e976b6e4212
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 /* compile-time and runtime tests for whether to use various ARM extensions */
6
7 #include "mozilla/NullPtr.h"
8
9 #include "arm.h"
10
11 #if defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
12 namespace {
13
14 // arm.h has parallel #ifs which declare MOZILLA_ARM_HAVE_CPUID_DETECTION.
15 // We don't check it here so that we get compile errors if it's defined, but
16 // we don't compile one of these detection methods. The detection code here is
17 // based on the CPU detection in libtheora.
18
19 # if defined(_MSC_VER)
20 //For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.
21 # define WIN32_LEAN_AND_MEAN
22 # define WIN32_EXTRA_LEAN
23 # include <windows.h>
24
25 # if !defined(MOZILLA_PRESUME_EDSP)
26 static bool
27 check_edsp(void)
28 {
29 # if defined(MOZILLA_MAY_SUPPORT_EDSP)
30 __try
31 {
32 //PLD [r13]
33 __emit(0xF5DDF000);
34 return true;
35 }
36 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
37 {
38 //Ignore exception.
39 }
40 # endif
41 return false;
42 }
43 # endif // !MOZILLA_PRESUME_EDSP
44
45 # if !defined(MOZILLA_PRESUME_ARMV6)
46 static bool
47 check_armv6(void)
48 {
49 # if defined(MOZILLA_MAY_SUPPORT_ARMV6)
50 __try
51 {
52 //SHADD8 r3,r3,r3
53 __emit(0xE6333F93);
54 return true;
55 }
56 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
57 {
58 //Ignore exception.
59 }
60 # endif
61 return false;
62 }
63 # endif // !MOZILLA_PRESUME_ARMV6
64
65 # if !defined(MOZILLA_PRESUME_ARMV7)
66 static bool
67 check_armv7(void)
68 {
69 # if defined(MOZILLA_MAY_SUPPORT_ARMV7)
70 __try
71 {
72 // ARMv7 DMB (Data Memory Barrier) for stores (DMB.ST)
73 // The Data Memory Barrier existed before ARMv7 as a
74 // cp15 operation, but ARMv7 introduced a dedicated
75 // instruction, DMB.
76 emit(0xF57FF05E);
77 return true;
78 }
79 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
80 {
81 //Ignore exception.
82 }
83 # endif
84 return false;
85 }
86 # endif // !MOZILLA_PRESUME_ARMV7
87
88 # if !defined(MOZILLA_PRESUME_NEON)
89 static bool
90 check_neon(void)
91 {
92 # if defined(MOZILLA_MAY_SUPPORT_NEON)
93 __try
94 {
95 //VORR q0,q0,q0
96 __emit(0xF2200150);
97 return true;
98 }
99 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION)
100 {
101 //Ignore exception.
102 }
103 # endif
104 return false;
105 }
106 # endif // !MOZILLA_PRESUME_NEON
107
108 # elif defined(__linux__) || defined(ANDROID)
109 # include <stdio.h>
110 # include <stdlib.h>
111 # include <string.h>
112
113 enum{
114 MOZILLA_HAS_EDSP_FLAG=1,
115 MOZILLA_HAS_ARMV6_FLAG=2,
116 MOZILLA_HAS_ARMV7_FLAG=4,
117 MOZILLA_HAS_NEON_FLAG=8
118 };
119
120 static unsigned
121 get_arm_cpu_flags(void)
122 {
123 unsigned flags;
124 FILE *fin;
125 bool armv6_processor = false;
126 flags = 0;
127 /*Reading /proc/self/auxv would be easier, but that doesn't work reliably on
128 Android. This also means that detection will fail in Scratchbox, which is
129 desirable, as NEON does not work in the qemu shipped with the Maemo 5 SDK.
130 I don't know if /proc/self/auxv would do any better in that case, anyway,
131 or if it would return random flags from the host CPU.*/
132 fin = fopen ("/proc/cpuinfo","r");
133 if (fin != nullptr)
134 {
135 /*512 should be enough for anybody (it's even enough for all the flags that
136 x86 has accumulated... so far).*/
137 char buf[512];
138 while (fgets(buf, 511, fin) != nullptr)
139 {
140 if (memcmp(buf, "Features", 8) == 0)
141 {
142 char *p;
143 p = strstr(buf, " edsp");
144 if (p != nullptr && (p[5] == ' ' || p[5] == '\n'))
145 flags |= MOZILLA_HAS_EDSP_FLAG;
146 p = strstr(buf, " neon");
147 if( p != nullptr && (p[5] == ' ' || p[5] == '\n'))
148 flags |= MOZILLA_HAS_NEON_FLAG;
149 }
150 if (memcmp(buf, "CPU architecture:", 17) == 0)
151 {
152 int version;
153 version = atoi(buf + 17);
154 if (version >= 6)
155 flags |= MOZILLA_HAS_ARMV6_FLAG;
156 if (version >= 7)
157 flags |= MOZILLA_HAS_ARMV7_FLAG;
158 }
159 /* media/webrtc/trunk/src/system_wrappers/source/cpu_features_arm.c
160 * Unfortunately, it seems that certain ARMv6-based CPUs
161 * report an incorrect architecture number of 7!
162 *
163 * We try to correct this by looking at the 'elf_format'
164 * field reported by the 'Processor' field, which is of the
165 * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
166 * an ARMv6-one.
167 */
168 if (memcmp(buf, "Processor\t:", 11) == 0) {
169 if (strstr(buf, "(v6l)") != 0) {
170 armv6_processor = true;
171 }
172 }
173 }
174 fclose(fin);
175 }
176 if (armv6_processor) {
177 // ARMv6 pretending to be ARMv7? clear flag
178 if (flags & MOZILLA_HAS_ARMV7_FLAG) {
179 flags &= ~MOZILLA_HAS_ARMV7_FLAG;
180 }
181 }
182 return flags;
183 }
184
185 // Cache a local copy so we only have to read /proc/cpuinfo once.
186 static unsigned arm_cpu_flags = get_arm_cpu_flags();
187
188 # if !defined(MOZILLA_PRESUME_EDSP)
189 static bool
190 check_edsp(void)
191 {
192 return (arm_cpu_flags & MOZILLA_HAS_EDSP_FLAG) != 0;
193 }
194 # endif
195
196 # if !defined(MOZILLA_PRESUME_ARMV6)
197 static bool
198 check_armv6(void)
199 {
200 return (arm_cpu_flags & MOZILLA_HAS_ARMV6_FLAG) != 0;
201 }
202 # endif
203
204 # if !defined(MOZILLA_PRESUME_ARMV7)
205 static bool
206 check_armv7(void)
207 {
208 return (arm_cpu_flags & MOZILLA_HAS_ARMV7_FLAG) != 0;
209 }
210 # endif
211
212 # if !defined(MOZILLA_PRESUME_NEON)
213 static bool
214 check_neon(void)
215 {
216 return (arm_cpu_flags & MOZILLA_HAS_NEON_FLAG) != 0;
217 }
218 # endif
219
220 # endif // defined(__linux__) || defined(ANDROID)
221
222 }
223
224 namespace mozilla {
225 namespace arm_private {
226 # if !defined(MOZILLA_PRESUME_EDSP)
227 bool edsp_enabled = check_edsp();
228 # endif
229 # if !defined(MOZILLA_PRESUME_ARMV6)
230 bool armv6_enabled = check_armv6();
231 # endif
232 # if !defined(MOZILLA_PRESUME_ARMV7)
233 bool armv7_enabled = check_armv7();
234 # endif
235 # if !defined(MOZILLA_PRESUME_NEON)
236 bool neon_enabled = check_neon();
237 # endif
238 } // namespace arm_private
239 } // namespace mozilla
240
241 #endif // MOZILLA_ARM_HAVE_CPUID_DETECTION

mercurial