mozglue/build/arm.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     5 /* compile-time and runtime tests for whether to use various ARM extensions */
     7 #include "mozilla/NullPtr.h"
     9 #include "arm.h"
    11 #if defined(MOZILLA_ARM_HAVE_CPUID_DETECTION)
    12 namespace {
    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.
    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>
    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
    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
    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
    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
   108 #  elif defined(__linux__) || defined(ANDROID)
   109 #    include <stdio.h>
   110 #    include <stdlib.h>
   111 #    include <string.h>
   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 };
   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 }
   185 // Cache a local copy so we only have to read /proc/cpuinfo once.
   186 static unsigned arm_cpu_flags = get_arm_cpu_flags();
   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
   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
   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
   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
   220 #  endif // defined(__linux__) || defined(ANDROID)
   222 }
   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
   241 #endif // MOZILLA_ARM_HAVE_CPUID_DETECTION

mercurial