summaryrefslogtreecommitdiffstats
path: root/mozglue/build/arm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mozglue/build/arm.cpp')
-rw-r--r--mozglue/build/arm.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/mozglue/build/arm.cpp b/mozglue/build/arm.cpp
new file mode 100644
index 0000000000..20eb9b5821
--- /dev/null
+++ b/mozglue/build/arm.cpp
@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* compile-time and runtime tests for whether to use various ARM extensions */
+
+#include "arm.h"
+
+#if defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
+
+// arm.h has parallel #ifs which declare MOZILLA_ARM_HAVE_CPUID_DETECTION.
+// We don't check it here so that we get compile errors if it's defined, but
+// we don't compile one of these detection methods. The detection code here is
+// based on the CPU detection in libtheora.
+
+# if defined(__linux__) || defined(ANDROID)
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+enum {
+ MOZILLA_HAS_EDSP_FLAG = 1,
+ MOZILLA_HAS_ARMV6_FLAG = 2,
+ MOZILLA_HAS_ARMV7_FLAG = 4,
+ MOZILLA_HAS_NEON_FLAG = 8,
+ MOZILLA_HAS_AES_FLAG = 16
+};
+
+static unsigned get_arm_cpu_flags(void) {
+ unsigned flags;
+ FILE* fin;
+ bool armv6_processor = false;
+ flags = 0;
+ /*Reading /proc/self/auxv would be easier, but that doesn't work reliably on
+ Android. This also means that detection will fail in Scratchbox, which is
+ desirable, as NEON does not work in the qemu shipped with the Maemo 5 SDK.
+ I don't know if /proc/self/auxv would do any better in that case, anyway,
+ or if it would return random flags from the host CPU.*/
+ fin = fopen("/proc/cpuinfo", "r");
+ if (fin != nullptr) {
+ /*512 should be enough for anybody (it's even enough for all the flags that
+ x86 has accumulated... so far).*/
+ char buf[512];
+ while (fgets(buf, 511, fin) != nullptr) {
+ if (memcmp(buf, "Features", 8) == 0) {
+ char* p;
+ p = strstr(buf, " edsp");
+ if (p != nullptr && (p[5] == ' ' || p[5] == '\n'))
+ flags |= MOZILLA_HAS_EDSP_FLAG;
+ p = strstr(buf, " neon");
+ if (p != nullptr && (p[5] == ' ' || p[5] == '\n'))
+ flags |= MOZILLA_HAS_NEON_FLAG;
+ p = strstr(buf, " aes");
+ if (p != nullptr && (p[4] == ' ' || p[4] == '\n')) {
+ flags |= MOZILLA_HAS_AES_FLAG;
+ }
+ }
+ if (memcmp(buf, "CPU architecture:", 17) == 0) {
+ int version;
+ version = atoi(buf + 17);
+ if (version >= 6) flags |= MOZILLA_HAS_ARMV6_FLAG;
+ if (version >= 7) flags |= MOZILLA_HAS_ARMV7_FLAG;
+ }
+ /* media/webrtc/trunk/src/system_wrappers/source/cpu_features_arm.c
+ * Unfortunately, it seems that certain ARMv6-based CPUs
+ * report an incorrect architecture number of 7!
+ *
+ * We try to correct this by looking at the 'elf_format'
+ * field reported by the 'Processor' field, which is of the
+ * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
+ * an ARMv6-one.
+ */
+ if (memcmp(buf, "Processor\t:", 11) == 0) {
+ if (strstr(buf, "(v6l)") != 0) {
+ armv6_processor = true;
+ }
+ }
+ }
+ fclose(fin);
+ }
+ if (armv6_processor) {
+ // ARMv6 pretending to be ARMv7? clear flag
+ if (flags & MOZILLA_HAS_ARMV7_FLAG) {
+ flags &= ~MOZILLA_HAS_ARMV7_FLAG;
+ }
+ }
+ return flags;
+}
+
+// Cache a local copy so we only have to read /proc/cpuinfo once.
+static unsigned arm_cpu_flags = get_arm_cpu_flags();
+
+# if !defined(MOZILLA_PRESUME_EDSP)
+static bool check_edsp(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_EDSP_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_ARMV6)
+static bool check_armv6(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_ARMV6_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_ARMV7)
+static bool check_armv7(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_ARMV7_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_NEON)
+static bool check_neon(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_NEON_FLAG) != 0;
+}
+# endif
+
+# if !defined(MOZILLA_PRESUME_ARM_AES)
+static bool check_aes(void) {
+ return (arm_cpu_flags & MOZILLA_HAS_AES_FLAG) != 0;
+}
+# endif
+
+# endif // defined(__linux__) || defined(ANDROID)
+
+namespace mozilla {
+namespace arm_private {
+# if !defined(MOZILLA_PRESUME_EDSP)
+bool edsp_enabled = check_edsp();
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV6)
+bool armv6_enabled = check_armv6();
+# endif
+# if !defined(MOZILLA_PRESUME_ARMV7)
+bool armv7_enabled = check_armv7();
+# endif
+# if !defined(MOZILLA_PRESUME_NEON)
+bool neon_enabled = check_neon();
+# endif
+# if !defined(MOZILLA_PRESUME_ARM_AES)
+bool aes_enabled = check_aes();
+# endif
+} // namespace arm_private
+} // namespace mozilla
+
+#endif // MOZILLA_ARM_HAVE_CPUID_DETECTION