/media/libvpx/vpx_ports/arm_cpudetect.c

http://github.com/zpao/v8monkey · C · 190 lines · 152 code · 11 blank · 27 comment · 34 complexity · 4fe0f5ecbd696637666e11b14d275665 MD5 · raw file

  1. /*
  2. * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "arm.h"
  13. static int arm_cpu_env_flags(int *flags)
  14. {
  15. char *env;
  16. env = getenv("VPX_SIMD_CAPS");
  17. if (env && *env)
  18. {
  19. *flags = (int)strtol(env, NULL, 0);
  20. return 0;
  21. }
  22. *flags = 0;
  23. return -1;
  24. }
  25. static int arm_cpu_env_mask(void)
  26. {
  27. char *env;
  28. env = getenv("VPX_SIMD_CAPS_MASK");
  29. return env && *env ? (int)strtol(env, NULL, 0) : ~0;
  30. }
  31. #if defined(_MSC_VER)
  32. /*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
  33. #define WIN32_LEAN_AND_MEAN
  34. #define WIN32_EXTRA_LEAN
  35. #include <windows.h>
  36. int arm_cpu_caps(void)
  37. {
  38. int flags;
  39. int mask;
  40. if (!arm_cpu_env_flags(&flags))
  41. {
  42. return flags;
  43. }
  44. mask = arm_cpu_env_mask();
  45. /* MSVC has no inline __asm support for ARM, but it does let you __emit
  46. * instructions via their assembled hex code.
  47. * All of these instructions should be essentially nops.
  48. */
  49. #if defined(HAVE_ARMV5TE)
  50. if (mask & HAS_EDSP)
  51. {
  52. __try
  53. {
  54. /*PLD [r13]*/
  55. __emit(0xF5DDF000);
  56. flags |= HAS_EDSP;
  57. }
  58. __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
  59. {
  60. /*Ignore exception.*/
  61. }
  62. }
  63. #if defined(HAVE_ARMV6)
  64. if (mask & HAS_MEDIA)
  65. __try
  66. {
  67. /*SHADD8 r3,r3,r3*/
  68. __emit(0xE6333F93);
  69. flags |= HAS_MEDIA;
  70. }
  71. __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
  72. {
  73. /*Ignore exception.*/
  74. }
  75. }
  76. #if defined(HAVE_ARMV7)
  77. if (mask & HAS_NEON)
  78. {
  79. __try
  80. {
  81. /*VORR q0,q0,q0*/
  82. __emit(0xF2200150);
  83. flags |= HAS_NEON;
  84. }
  85. __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION)
  86. {
  87. /*Ignore exception.*/
  88. }
  89. }
  90. #endif
  91. #endif
  92. #endif
  93. return flags & mask;
  94. }
  95. #elif defined(__linux__)
  96. #include <stdio.h>
  97. int arm_cpu_caps(void)
  98. {
  99. FILE *fin;
  100. int flags;
  101. int mask;
  102. if (!arm_cpu_env_flags(&flags))
  103. {
  104. return flags;
  105. }
  106. mask = arm_cpu_env_mask();
  107. /* Reading /proc/self/auxv would be easier, but that doesn't work reliably
  108. * on Android.
  109. * This also means that detection will fail in Scratchbox.
  110. */
  111. fin = fopen("/proc/cpuinfo","r");
  112. if(fin != NULL)
  113. {
  114. /* 512 should be enough for anybody (it's even enough for all the flags
  115. * that x86 has accumulated... so far).
  116. */
  117. char buf[512];
  118. while (fgets(buf, 511, fin) != NULL)
  119. {
  120. #if defined(HAVE_ARMV5TE) || defined(HAVE_ARMV7)
  121. if (memcmp(buf, "Features", 8) == 0)
  122. {
  123. char *p;
  124. #if defined(HAVE_ARMV5TE)
  125. p=strstr(buf, " edsp");
  126. if (p != NULL && (p[5] == ' ' || p[5] == '\n'))
  127. {
  128. flags |= HAS_EDSP;
  129. }
  130. #if defined(HAVE_ARMV7)
  131. p = strstr(buf, " neon");
  132. if (p != NULL && (p[5] == ' ' || p[5] == '\n'))
  133. {
  134. flags |= HAS_NEON;
  135. }
  136. #endif
  137. #endif
  138. }
  139. #endif
  140. #if defined(HAVE_ARMV6)
  141. if (memcmp(buf, "CPU architecture:",17) == 0){
  142. int version;
  143. version = atoi(buf+17);
  144. if (version >= 6)
  145. {
  146. flags |= HAS_MEDIA;
  147. }
  148. }
  149. #endif
  150. }
  151. fclose(fin);
  152. }
  153. return flags & mask;
  154. }
  155. #elif !CONFIG_RUNTIME_CPU_DETECT
  156. int arm_cpu_caps(void)
  157. {
  158. int flags;
  159. int mask;
  160. if (!arm_cpu_env_flags(&flags))
  161. {
  162. return flags;
  163. }
  164. mask = arm_cpu_env_mask();
  165. #if defined(HAVE_ARMV5TE)
  166. flags |= HAS_EDSP;
  167. #endif
  168. #if defined(HAVE_ARMV6)
  169. flags |= HAS_MEDIA;
  170. #endif
  171. #if defined(HAVE_ARMV7)
  172. flags |= HAS_NEON;
  173. #endif
  174. return flags & mask;
  175. }
  176. #else
  177. #error "--enable-runtime-cpu-detect selected, but no CPU detection method " \
  178. "available for your platform. Reconfigure without --enable-runtime-cpu-detect."
  179. #endif