cpu-features.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  18. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  19. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  21. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  22. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  23. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  24. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  25. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. /* ChangeLog for this library:
  29. *
  30. * NDK r10e?: Add MIPS MSA feature.
  31. *
  32. * NDK r10: Support for 64-bit CPUs (Intel, ARM & MIPS).
  33. *
  34. * NDK r8d: Add android_setCpu().
  35. *
  36. * NDK r8c: Add new ARM CPU features: VFPv2, VFP_D32, VFP_FP16,
  37. * VFP_FMA, NEON_FMA, IDIV_ARM, IDIV_THUMB2 and iWMMXt.
  38. *
  39. * Rewrite the code to parse /proc/self/auxv instead of
  40. * the "Features" field in /proc/cpuinfo.
  41. *
  42. * Dynamically allocate the buffer that hold the content
  43. * of /proc/cpuinfo to deal with newer hardware.
  44. *
  45. * NDK r7c: Fix CPU count computation. The old method only reported the
  46. * number of _active_ CPUs when the library was initialized,
  47. * which could be less than the real total.
  48. *
  49. * NDK r5: Handle buggy kernels which report a CPU Architecture number of 7
  50. * for an ARMv6 CPU (see below).
  51. *
  52. * Handle kernels that only report 'neon', and not 'vfpv3'
  53. * (VFPv3 is mandated by the ARM architecture is Neon is implemented)
  54. *
  55. * Handle kernels that only report 'vfpv3d16', and not 'vfpv3'
  56. *
  57. * Fix x86 compilation. Report ANDROID_CPU_FAMILY_X86 in
  58. * android_getCpuFamily().
  59. *
  60. * NDK r4: Initial release
  61. */
  62. #include "cpu-features.h"
  63. #include <dlfcn.h>
  64. #include <errno.h>
  65. #include <fcntl.h>
  66. #include <pthread.h>
  67. #include <stdio.h>
  68. #include <stdlib.h>
  69. #include <sys/system_properties.h>
  70. #include <unistd.h>
  71. static pthread_once_t g_once;
  72. static int g_inited;
  73. static AndroidCpuFamily g_cpuFamily;
  74. static uint64_t g_cpuFeatures;
  75. static int g_cpuCount;
  76. #ifdef __arm__
  77. static uint32_t g_cpuIdArm;
  78. #endif
  79. static const int android_cpufeatures_debug = 0;
  80. #define D(...) \
  81. do { \
  82. if (android_cpufeatures_debug) { \
  83. printf(__VA_ARGS__); fflush(stdout); \
  84. } \
  85. } while (0)
  86. #ifdef __i386__
  87. static __inline__ void x86_cpuid(int func, int values[4])
  88. {
  89. int a, b, c, d;
  90. /* We need to preserve ebx since we're compiling PIC code */
  91. /* this means we can't use "=b" for the second output register */
  92. __asm__ __volatile__ ( \
  93. "push %%ebx\n"
  94. "cpuid\n" \
  95. "mov %%ebx, %1\n"
  96. "pop %%ebx\n"
  97. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  98. : "a" (func) \
  99. );
  100. values[0] = a;
  101. values[1] = b;
  102. values[2] = c;
  103. values[3] = d;
  104. }
  105. #elif defined(__x86_64__)
  106. static __inline__ void x86_cpuid(int func, int values[4])
  107. {
  108. int64_t a, b, c, d;
  109. /* We need to preserve ebx since we're compiling PIC code */
  110. /* this means we can't use "=b" for the second output register */
  111. __asm__ __volatile__ ( \
  112. "push %%rbx\n"
  113. "cpuid\n" \
  114. "mov %%rbx, %1\n"
  115. "pop %%rbx\n"
  116. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  117. : "a" (func) \
  118. );
  119. values[0] = a;
  120. values[1] = b;
  121. values[2] = c;
  122. values[3] = d;
  123. }
  124. #endif
  125. /* Get the size of a file by reading it until the end. This is needed
  126. * because files under /proc do not always return a valid size when
  127. * using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
  128. */
  129. static int
  130. get_file_size(const char* pathname)
  131. {
  132. int fd, result = 0;
  133. char buffer[256];
  134. fd = open(pathname, O_RDONLY);
  135. if (fd < 0) {
  136. D("Can't open %s: %s\n", pathname, strerror(errno));
  137. return -1;
  138. }
  139. for (;;) {
  140. int ret = read(fd, buffer, sizeof buffer);
  141. if (ret < 0) {
  142. if (errno == EINTR)
  143. continue;
  144. D("Error while reading %s: %s\n", pathname, strerror(errno));
  145. break;
  146. }
  147. if (ret == 0)
  148. break;
  149. result += ret;
  150. }
  151. close(fd);
  152. return result;
  153. }
  154. /* Read the content of /proc/cpuinfo into a user-provided buffer.
  155. * Return the length of the data, or -1 on error. Does *not*
  156. * zero-terminate the content. Will not read more
  157. * than 'buffsize' bytes.
  158. */
  159. static int
  160. read_file(const char* pathname, char* buffer, size_t buffsize)
  161. {
  162. int fd, count;
  163. fd = open(pathname, O_RDONLY);
  164. if (fd < 0) {
  165. D("Could not open %s: %s\n", pathname, strerror(errno));
  166. return -1;
  167. }
  168. count = 0;
  169. while (count < (int)buffsize) {
  170. int ret = read(fd, buffer + count, buffsize - count);
  171. if (ret < 0) {
  172. if (errno == EINTR)
  173. continue;
  174. D("Error while reading from %s: %s\n", pathname, strerror(errno));
  175. if (count == 0)
  176. count = -1;
  177. break;
  178. }
  179. if (ret == 0)
  180. break;
  181. count += ret;
  182. }
  183. close(fd);
  184. return count;
  185. }
  186. #ifdef __arm__
  187. /* Extract the content of a the first occurence of a given field in
  188. * the content of /proc/cpuinfo and return it as a heap-allocated
  189. * string that must be freed by the caller.
  190. *
  191. * Return NULL if not found
  192. */
  193. static char*
  194. extract_cpuinfo_field(const char* buffer, int buflen, const char* field)
  195. {
  196. int fieldlen = strlen(field);
  197. const char* bufend = buffer + buflen;
  198. char* result = NULL;
  199. int len;
  200. const char *p, *q;
  201. /* Look for first field occurence, and ensures it starts the line. */
  202. p = buffer;
  203. for (;;) {
  204. p = memmem(p, bufend-p, field, fieldlen);
  205. if (p == NULL)
  206. goto EXIT;
  207. if (p == buffer || p[-1] == '\n')
  208. break;
  209. p += fieldlen;
  210. }
  211. /* Skip to the first column followed by a space */
  212. p += fieldlen;
  213. p = memchr(p, ':', bufend-p);
  214. if (p == NULL || p[1] != ' ')
  215. goto EXIT;
  216. /* Find the end of the line */
  217. p += 2;
  218. q = memchr(p, '\n', bufend-p);
  219. if (q == NULL)
  220. q = bufend;
  221. /* Copy the line into a heap-allocated buffer */
  222. len = q-p;
  223. result = malloc(len+1);
  224. if (result == NULL)
  225. goto EXIT;
  226. memcpy(result, p, len);
  227. result[len] = '\0';
  228. EXIT:
  229. return result;
  230. }
  231. /* Checks that a space-separated list of items contains one given 'item'.
  232. * Returns 1 if found, 0 otherwise.
  233. */
  234. static int
  235. has_list_item(const char* list, const char* item)
  236. {
  237. const char* p = list;
  238. int itemlen = strlen(item);
  239. if (list == NULL)
  240. return 0;
  241. while (*p) {
  242. const char* q;
  243. /* skip spaces */
  244. while (*p == ' ' || *p == '\t')
  245. p++;
  246. /* find end of current list item */
  247. q = p;
  248. while (*q && *q != ' ' && *q != '\t')
  249. q++;
  250. if (itemlen == q-p && !memcmp(p, item, itemlen))
  251. return 1;
  252. /* skip to next item */
  253. p = q;
  254. }
  255. return 0;
  256. }
  257. #endif /* __arm__ */
  258. /* Parse a number starting from 'input', but not going further
  259. * than 'limit'. Return the value into '*result'.
  260. *
  261. * NOTE: Does not skip over leading spaces, or deal with sign characters.
  262. * NOTE: Ignores overflows.
  263. *
  264. * The function returns NULL in case of error (bad format), or the new
  265. * position after the decimal number in case of success (which will always
  266. * be <= 'limit').
  267. */
  268. static const char*
  269. parse_number(const char* input, const char* limit, int base, int* result)
  270. {
  271. const char* p = input;
  272. int val = 0;
  273. while (p < limit) {
  274. int d = (*p - '0');
  275. if ((unsigned)d >= 10U) {
  276. d = (*p - 'a');
  277. if ((unsigned)d >= 6U)
  278. d = (*p - 'A');
  279. if ((unsigned)d >= 6U)
  280. break;
  281. d += 10;
  282. }
  283. if (d >= base)
  284. break;
  285. val = val*base + d;
  286. p++;
  287. }
  288. if (p == input)
  289. return NULL;
  290. *result = val;
  291. return p;
  292. }
  293. static const char*
  294. parse_decimal(const char* input, const char* limit, int* result)
  295. {
  296. return parse_number(input, limit, 10, result);
  297. }
  298. #ifdef __arm__
  299. static const char*
  300. parse_hexadecimal(const char* input, const char* limit, int* result)
  301. {
  302. return parse_number(input, limit, 16, result);
  303. }
  304. #endif /* __arm__ */
  305. /* This small data type is used to represent a CPU list / mask, as read
  306. * from sysfs on Linux. See http://www.kernel.org/doc/Documentation/cputopology.txt
  307. *
  308. * For now, we don't expect more than 32 cores on mobile devices, so keep
  309. * everything simple.
  310. */
  311. typedef struct {
  312. uint32_t mask;
  313. } CpuList;
  314. static __inline__ void
  315. cpulist_init(CpuList* list) {
  316. list->mask = 0;
  317. }
  318. static __inline__ void
  319. cpulist_and(CpuList* list1, CpuList* list2) {
  320. list1->mask &= list2->mask;
  321. }
  322. static __inline__ void
  323. cpulist_set(CpuList* list, int index) {
  324. if ((unsigned)index < 32) {
  325. list->mask |= (uint32_t)(1U << index);
  326. }
  327. }
  328. static __inline__ int
  329. cpulist_count(CpuList* list) {
  330. return __builtin_popcount(list->mask);
  331. }
  332. /* Parse a textual list of cpus and store the result inside a CpuList object.
  333. * Input format is the following:
  334. * - comma-separated list of items (no spaces)
  335. * - each item is either a single decimal number (cpu index), or a range made
  336. * of two numbers separated by a single dash (-). Ranges are inclusive.
  337. *
  338. * Examples: 0
  339. * 2,4-127,128-143
  340. * 0-1
  341. */
  342. static void
  343. cpulist_parse(CpuList* list, const char* line, int line_len)
  344. {
  345. const char* p = line;
  346. const char* end = p + line_len;
  347. const char* q;
  348. /* NOTE: the input line coming from sysfs typically contains a
  349. * trailing newline, so take care of it in the code below
  350. */
  351. while (p < end && *p != '\n')
  352. {
  353. int val, start_value, end_value;
  354. /* Find the end of current item, and put it into 'q' */
  355. q = memchr(p, ',', end-p);
  356. if (q == NULL) {
  357. q = end;
  358. }
  359. /* Get first value */
  360. p = parse_decimal(p, q, &start_value);
  361. if (p == NULL)
  362. goto BAD_FORMAT;
  363. end_value = start_value;
  364. /* If we're not at the end of the item, expect a dash and
  365. * and integer; extract end value.
  366. */
  367. if (p < q && *p == '-') {
  368. p = parse_decimal(p+1, q, &end_value);
  369. if (p == NULL)
  370. goto BAD_FORMAT;
  371. }
  372. /* Set bits CPU list bits */
  373. for (val = start_value; val <= end_value; val++) {
  374. cpulist_set(list, val);
  375. }
  376. /* Jump to next item */
  377. p = q;
  378. if (p < end)
  379. p++;
  380. }
  381. BAD_FORMAT:
  382. ;
  383. }
  384. /* Read a CPU list from one sysfs file */
  385. static void
  386. cpulist_read_from(CpuList* list, const char* filename)
  387. {
  388. char file[64];
  389. int filelen;
  390. cpulist_init(list);
  391. filelen = read_file(filename, file, sizeof file);
  392. if (filelen < 0) {
  393. D("Could not read %s: %s\n", filename, strerror(errno));
  394. return;
  395. }
  396. cpulist_parse(list, file, filelen);
  397. }
  398. #if defined(__aarch64__)
  399. // see <uapi/asm/hwcap.h> kernel header
  400. #define HWCAP_FP (1 << 0)
  401. #define HWCAP_ASIMD (1 << 1)
  402. #define HWCAP_AES (1 << 3)
  403. #define HWCAP_PMULL (1 << 4)
  404. #define HWCAP_SHA1 (1 << 5)
  405. #define HWCAP_SHA2 (1 << 6)
  406. #define HWCAP_CRC32 (1 << 7)
  407. #endif
  408. #if defined(__arm__)
  409. // See <asm/hwcap.h> kernel header.
  410. #define HWCAP_VFP (1 << 6)
  411. #define HWCAP_IWMMXT (1 << 9)
  412. #define HWCAP_NEON (1 << 12)
  413. #define HWCAP_VFPv3 (1 << 13)
  414. #define HWCAP_VFPv3D16 (1 << 14)
  415. #define HWCAP_VFPv4 (1 << 16)
  416. #define HWCAP_IDIVA (1 << 17)
  417. #define HWCAP_IDIVT (1 << 18)
  418. // see <uapi/asm/hwcap.h> kernel header
  419. #define HWCAP2_AES (1 << 0)
  420. #define HWCAP2_PMULL (1 << 1)
  421. #define HWCAP2_SHA1 (1 << 2)
  422. #define HWCAP2_SHA2 (1 << 3)
  423. #define HWCAP2_CRC32 (1 << 4)
  424. // This is the list of 32-bit ARMv7 optional features that are _always_
  425. // supported by ARMv8 CPUs, as mandated by the ARM Architecture Reference
  426. // Manual.
  427. #define HWCAP_SET_FOR_ARMV8 \
  428. ( HWCAP_VFP | \
  429. HWCAP_NEON | \
  430. HWCAP_VFPv3 | \
  431. HWCAP_VFPv4 | \
  432. HWCAP_IDIVA | \
  433. HWCAP_IDIVT )
  434. #endif
  435. #if defined(__mips__)
  436. // see <uapi/asm/hwcap.h> kernel header
  437. #define HWCAP_MIPS_R6 (1 << 0)
  438. #define HWCAP_MIPS_MSA (1 << 1)
  439. #endif
  440. #if defined(__arm__) || defined(__aarch64__) || defined(__mips__)
  441. #define AT_HWCAP 16
  442. #define AT_HWCAP2 26
  443. // Probe the system's C library for a 'getauxval' function and call it if
  444. // it exits, or return 0 for failure. This function is available since API
  445. // level 20.
  446. //
  447. // This code does *NOT* check for '__ANDROID_API__ >= 20' to support the
  448. // edge case where some NDK developers use headers for a platform that is
  449. // newer than the one really targetted by their application.
  450. // This is typically done to use newer native APIs only when running on more
  451. // recent Android versions, and requires careful symbol management.
  452. //
  453. // Note that getauxval() can't really be re-implemented here, because
  454. // its implementation does not parse /proc/self/auxv. Instead it depends
  455. // on values that are passed by the kernel at process-init time to the
  456. // C runtime initialization layer.
  457. #if 1
  458. // OpenCV calls CPU features check during library initialization stage
  459. // (under other dlopen() call).
  460. // Unfortunatelly, calling dlopen() recursively is not supported on some old
  461. // Android versions. Android fix is here:
  462. // - https://android-review.googlesource.com/#/c/32951/
  463. // - GitHub mirror: https://github.com/android/platform_bionic/commit/e19d702b8e330cef87e0983733c427b5f7842144
  464. __attribute__((weak)) unsigned long getauxval(unsigned long); // Lets linker to handle this symbol
  465. static uint32_t
  466. get_elf_hwcap_from_getauxval(int hwcap_type) {
  467. uint32_t ret = 0;
  468. if(getauxval != 0) {
  469. ret = (uint32_t)getauxval(hwcap_type);
  470. } else {
  471. D("getauxval() is not available\n");
  472. }
  473. return ret;
  474. }
  475. #else
  476. static uint32_t
  477. get_elf_hwcap_from_getauxval(int hwcap_type) {
  478. typedef unsigned long getauxval_func_t(unsigned long);
  479. dlerror();
  480. void* libc_handle = dlopen("libc.so", RTLD_NOW);
  481. if (!libc_handle) {
  482. D("Could not dlopen() C library: %s\n", dlerror());
  483. return 0;
  484. }
  485. uint32_t ret = 0;
  486. getauxval_func_t* func = (getauxval_func_t*)
  487. dlsym(libc_handle, "getauxval");
  488. if (!func) {
  489. D("Could not find getauxval() in C library\n");
  490. } else {
  491. // Note: getauxval() returns 0 on failure. Doesn't touch errno.
  492. ret = (uint32_t)(*func)(hwcap_type);
  493. }
  494. dlclose(libc_handle);
  495. return ret;
  496. }
  497. #endif
  498. #endif
  499. #if defined(__arm__)
  500. // Parse /proc/self/auxv to extract the ELF HW capabilities bitmap for the
  501. // current CPU. Note that this file is not accessible from regular
  502. // application processes on some Android platform releases.
  503. // On success, return new ELF hwcaps, or 0 on failure.
  504. static uint32_t
  505. get_elf_hwcap_from_proc_self_auxv(void) {
  506. const char filepath[] = "/proc/self/auxv";
  507. int fd = TEMP_FAILURE_RETRY(open(filepath, O_RDONLY));
  508. if (fd < 0) {
  509. D("Could not open %s: %s\n", filepath, strerror(errno));
  510. return 0;
  511. }
  512. struct { uint32_t tag; uint32_t value; } entry;
  513. uint32_t result = 0;
  514. for (;;) {
  515. int ret = TEMP_FAILURE_RETRY(read(fd, (char*)&entry, sizeof entry));
  516. if (ret < 0) {
  517. D("Error while reading %s: %s\n", filepath, strerror(errno));
  518. break;
  519. }
  520. // Detect end of list.
  521. if (ret == 0 || (entry.tag == 0 && entry.value == 0))
  522. break;
  523. if (entry.tag == AT_HWCAP) {
  524. result = entry.value;
  525. break;
  526. }
  527. }
  528. close(fd);
  529. return result;
  530. }
  531. /* Compute the ELF HWCAP flags from the content of /proc/cpuinfo.
  532. * This works by parsing the 'Features' line, which lists which optional
  533. * features the device's CPU supports, on top of its reference
  534. * architecture.
  535. */
  536. static uint32_t
  537. get_elf_hwcap_from_proc_cpuinfo(const char* cpuinfo, int cpuinfo_len) {
  538. uint32_t hwcaps = 0;
  539. long architecture = 0;
  540. char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
  541. if (cpuArch) {
  542. architecture = strtol(cpuArch, NULL, 10);
  543. free(cpuArch);
  544. if (architecture >= 8L) {
  545. // This is a 32-bit ARM binary running on a 64-bit ARM64 kernel.
  546. // The 'Features' line only lists the optional features that the
  547. // device's CPU supports, compared to its reference architecture
  548. // which are of no use for this process.
  549. D("Faking 32-bit ARM HWCaps on ARMv%ld CPU\n", architecture);
  550. return HWCAP_SET_FOR_ARMV8;
  551. }
  552. }
  553. char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
  554. if (cpuFeatures != NULL) {
  555. D("Found cpuFeatures = '%s'\n", cpuFeatures);
  556. if (has_list_item(cpuFeatures, "vfp"))
  557. hwcaps |= HWCAP_VFP;
  558. if (has_list_item(cpuFeatures, "vfpv3"))
  559. hwcaps |= HWCAP_VFPv3;
  560. if (has_list_item(cpuFeatures, "vfpv3d16"))
  561. hwcaps |= HWCAP_VFPv3D16;
  562. if (has_list_item(cpuFeatures, "vfpv4"))
  563. hwcaps |= HWCAP_VFPv4;
  564. if (has_list_item(cpuFeatures, "neon"))
  565. hwcaps |= HWCAP_NEON;
  566. if (has_list_item(cpuFeatures, "idiva"))
  567. hwcaps |= HWCAP_IDIVA;
  568. if (has_list_item(cpuFeatures, "idivt"))
  569. hwcaps |= HWCAP_IDIVT;
  570. if (has_list_item(cpuFeatures, "idiv"))
  571. hwcaps |= HWCAP_IDIVA | HWCAP_IDIVT;
  572. if (has_list_item(cpuFeatures, "iwmmxt"))
  573. hwcaps |= HWCAP_IWMMXT;
  574. free(cpuFeatures);
  575. }
  576. return hwcaps;
  577. }
  578. #endif /* __arm__ */
  579. /* Return the number of cpus present on a given device.
  580. *
  581. * To handle all weird kernel configurations, we need to compute the
  582. * intersection of the 'present' and 'possible' CPU lists and count
  583. * the result.
  584. */
  585. static int
  586. get_cpu_count(void)
  587. {
  588. CpuList cpus_present[1];
  589. CpuList cpus_possible[1];
  590. cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
  591. cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
  592. /* Compute the intersection of both sets to get the actual number of
  593. * CPU cores that can be used on this device by the kernel.
  594. */
  595. cpulist_and(cpus_present, cpus_possible);
  596. return cpulist_count(cpus_present);
  597. }
  598. static void
  599. android_cpuInitFamily(void)
  600. {
  601. #if defined(__arm__)
  602. g_cpuFamily = ANDROID_CPU_FAMILY_ARM;
  603. #elif defined(__i386__)
  604. g_cpuFamily = ANDROID_CPU_FAMILY_X86;
  605. #elif defined(__mips64)
  606. /* Needs to be before __mips__ since the compiler defines both */
  607. g_cpuFamily = ANDROID_CPU_FAMILY_MIPS64;
  608. #elif defined(__mips__)
  609. g_cpuFamily = ANDROID_CPU_FAMILY_MIPS;
  610. #elif defined(__aarch64__)
  611. g_cpuFamily = ANDROID_CPU_FAMILY_ARM64;
  612. #elif defined(__x86_64__)
  613. g_cpuFamily = ANDROID_CPU_FAMILY_X86_64;
  614. #else
  615. g_cpuFamily = ANDROID_CPU_FAMILY_UNKNOWN;
  616. #endif
  617. }
  618. static void
  619. android_cpuInit(void)
  620. {
  621. char* cpuinfo = NULL;
  622. int cpuinfo_len;
  623. android_cpuInitFamily();
  624. g_cpuFeatures = 0;
  625. g_cpuCount = 1;
  626. g_inited = 1;
  627. cpuinfo_len = get_file_size("/proc/cpuinfo");
  628. if (cpuinfo_len < 0) {
  629. D("cpuinfo_len cannot be computed!");
  630. return;
  631. }
  632. cpuinfo = malloc(cpuinfo_len);
  633. if (cpuinfo == NULL) {
  634. D("cpuinfo buffer could not be allocated");
  635. return;
  636. }
  637. cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, cpuinfo_len);
  638. D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
  639. cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
  640. if (cpuinfo_len < 0) /* should not happen */ {
  641. free(cpuinfo);
  642. return;
  643. }
  644. /* Count the CPU cores, the value may be 0 for single-core CPUs */
  645. g_cpuCount = get_cpu_count();
  646. if (g_cpuCount == 0) {
  647. g_cpuCount = 1;
  648. }
  649. D("found cpuCount = %d\n", g_cpuCount);
  650. #ifdef __arm__
  651. {
  652. /* Extract architecture from the "CPU Architecture" field.
  653. * The list is well-known, unlike the the output of
  654. * the 'Processor' field which can vary greatly.
  655. *
  656. * See the definition of the 'proc_arch' array in
  657. * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
  658. * same file.
  659. */
  660. char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
  661. if (cpuArch != NULL) {
  662. char* end;
  663. long archNumber;
  664. int hasARMv7 = 0;
  665. D("found cpuArch = '%s'\n", cpuArch);
  666. /* read the initial decimal number, ignore the rest */
  667. archNumber = strtol(cpuArch, &end, 10);
  668. /* Note that ARMv8 is upwards compatible with ARMv7. */
  669. if (end > cpuArch && archNumber >= 7) {
  670. hasARMv7 = 1;
  671. }
  672. /* Unfortunately, it seems that certain ARMv6-based CPUs
  673. * report an incorrect architecture number of 7!
  674. *
  675. * See http://code.google.com/p/android/issues/detail?id=10812
  676. *
  677. * We try to correct this by looking at the 'elf_format'
  678. * field reported by the 'Processor' field, which is of the
  679. * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
  680. * an ARMv6-one.
  681. */
  682. if (hasARMv7) {
  683. char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
  684. "Processor");
  685. if (cpuProc != NULL) {
  686. D("found cpuProc = '%s'\n", cpuProc);
  687. if (has_list_item(cpuProc, "(v6l)")) {
  688. D("CPU processor and architecture mismatch!!\n");
  689. hasARMv7 = 0;
  690. }
  691. free(cpuProc);
  692. }
  693. }
  694. if (hasARMv7) {
  695. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
  696. }
  697. /* The LDREX / STREX instructions are available from ARMv6 */
  698. if (archNumber >= 6) {
  699. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
  700. }
  701. free(cpuArch);
  702. }
  703. /* Extract the list of CPU features from ELF hwcaps */
  704. uint32_t hwcaps = 0;
  705. hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
  706. if (!hwcaps) {
  707. D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
  708. hwcaps = get_elf_hwcap_from_proc_self_auxv();
  709. }
  710. if (!hwcaps) {
  711. // Parsing /proc/self/auxv will fail from regular application
  712. // processes on some Android platform versions, when this happens
  713. // parse proc/cpuinfo instead.
  714. D("Parsing /proc/cpuinfo to extract ELF hwcaps!\n");
  715. hwcaps = get_elf_hwcap_from_proc_cpuinfo(cpuinfo, cpuinfo_len);
  716. }
  717. if (hwcaps != 0) {
  718. int has_vfp = (hwcaps & HWCAP_VFP);
  719. int has_vfpv3 = (hwcaps & HWCAP_VFPv3);
  720. int has_vfpv3d16 = (hwcaps & HWCAP_VFPv3D16);
  721. int has_vfpv4 = (hwcaps & HWCAP_VFPv4);
  722. int has_neon = (hwcaps & HWCAP_NEON);
  723. int has_idiva = (hwcaps & HWCAP_IDIVA);
  724. int has_idivt = (hwcaps & HWCAP_IDIVT);
  725. int has_iwmmxt = (hwcaps & HWCAP_IWMMXT);
  726. // The kernel does a poor job at ensuring consistency when
  727. // describing CPU features. So lots of guessing is needed.
  728. // 'vfpv4' implies VFPv3|VFP_FMA|FP16
  729. if (has_vfpv4)
  730. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3 |
  731. ANDROID_CPU_ARM_FEATURE_VFP_FP16 |
  732. ANDROID_CPU_ARM_FEATURE_VFP_FMA;
  733. // 'vfpv3' or 'vfpv3d16' imply VFPv3. Note that unlike GCC,
  734. // a value of 'vfpv3' doesn't necessarily mean that the D32
  735. // feature is present, so be conservative. All CPUs in the
  736. // field that support D32 also support NEON, so this should
  737. // not be a problem in practice.
  738. if (has_vfpv3 || has_vfpv3d16)
  739. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
  740. // 'vfp' is super ambiguous. Depending on the kernel, it can
  741. // either mean VFPv2 or VFPv3. Make it depend on ARMv7.
  742. if (has_vfp) {
  743. if (g_cpuFeatures & ANDROID_CPU_ARM_FEATURE_ARMv7)
  744. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
  745. else
  746. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2;
  747. }
  748. // Neon implies VFPv3|D32, and if vfpv4 is detected, NEON_FMA
  749. if (has_neon) {
  750. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3 |
  751. ANDROID_CPU_ARM_FEATURE_NEON |
  752. ANDROID_CPU_ARM_FEATURE_VFP_D32;
  753. if (has_vfpv4)
  754. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON_FMA;
  755. }
  756. // VFPv3 implies VFPv2 and ARMv7
  757. if (g_cpuFeatures & ANDROID_CPU_ARM_FEATURE_VFPv3)
  758. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2 |
  759. ANDROID_CPU_ARM_FEATURE_ARMv7;
  760. if (has_idiva)
  761. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM;
  762. if (has_idivt)
  763. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2;
  764. if (has_iwmmxt)
  765. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_iWMMXt;
  766. }
  767. /* Extract the list of CPU features from ELF hwcaps2 */
  768. uint32_t hwcaps2 = 0;
  769. hwcaps2 = get_elf_hwcap_from_getauxval(AT_HWCAP2);
  770. if (hwcaps2 != 0) {
  771. int has_aes = (hwcaps2 & HWCAP2_AES);
  772. int has_pmull = (hwcaps2 & HWCAP2_PMULL);
  773. int has_sha1 = (hwcaps2 & HWCAP2_SHA1);
  774. int has_sha2 = (hwcaps2 & HWCAP2_SHA2);
  775. int has_crc32 = (hwcaps2 & HWCAP2_CRC32);
  776. if (has_aes)
  777. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_AES;
  778. if (has_pmull)
  779. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_PMULL;
  780. if (has_sha1)
  781. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA1;
  782. if (has_sha2)
  783. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA2;
  784. if (has_crc32)
  785. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_CRC32;
  786. }
  787. /* Extract the cpuid value from various fields */
  788. // The CPUID value is broken up in several entries in /proc/cpuinfo.
  789. // This table is used to rebuild it from the entries.
  790. static const struct CpuIdEntry {
  791. const char* field;
  792. char format;
  793. char bit_lshift;
  794. char bit_length;
  795. } cpu_id_entries[] = {
  796. { "CPU implementer", 'x', 24, 8 },
  797. { "CPU variant", 'x', 20, 4 },
  798. { "CPU part", 'x', 4, 12 },
  799. { "CPU revision", 'd', 0, 4 },
  800. };
  801. size_t i;
  802. D("Parsing /proc/cpuinfo to recover CPUID\n");
  803. for (i = 0;
  804. i < sizeof(cpu_id_entries)/sizeof(cpu_id_entries[0]);
  805. ++i) {
  806. const struct CpuIdEntry* entry = &cpu_id_entries[i];
  807. char* value = extract_cpuinfo_field(cpuinfo,
  808. cpuinfo_len,
  809. entry->field);
  810. if (value == NULL)
  811. continue;
  812. D("field=%s value='%s'\n", entry->field, value);
  813. char* value_end = value + strlen(value);
  814. int val = 0;
  815. const char* start = value;
  816. const char* p;
  817. if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) {
  818. start += 2;
  819. p = parse_hexadecimal(start, value_end, &val);
  820. } else if (entry->format == 'x')
  821. p = parse_hexadecimal(value, value_end, &val);
  822. else
  823. p = parse_decimal(value, value_end, &val);
  824. if (p > (const char*)start) {
  825. val &= ((1 << entry->bit_length)-1);
  826. val <<= entry->bit_lshift;
  827. g_cpuIdArm |= (uint32_t) val;
  828. }
  829. free(value);
  830. }
  831. // Handle kernel configuration bugs that prevent the correct
  832. // reporting of CPU features.
  833. static const struct CpuFix {
  834. uint32_t cpuid;
  835. uint64_t or_flags;
  836. } cpu_fixes[] = {
  837. /* The Nexus 4 (Qualcomm Krait) kernel configuration
  838. * forgets to report IDIV support. */
  839. { 0x510006f2, ANDROID_CPU_ARM_FEATURE_IDIV_ARM |
  840. ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 },
  841. { 0x510006f3, ANDROID_CPU_ARM_FEATURE_IDIV_ARM |
  842. ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 },
  843. };
  844. size_t n;
  845. for (n = 0; n < sizeof(cpu_fixes)/sizeof(cpu_fixes[0]); ++n) {
  846. const struct CpuFix* entry = &cpu_fixes[n];
  847. if (g_cpuIdArm == entry->cpuid)
  848. g_cpuFeatures |= entry->or_flags;
  849. }
  850. // Special case: The emulator-specific Android 4.2 kernel fails
  851. // to report support for the 32-bit ARM IDIV instruction.
  852. // Technically, this is a feature of the virtual CPU implemented
  853. // by the emulator. Note that it could also support Thumb IDIV
  854. // in the future, and this will have to be slightly updated.
  855. char* hardware = extract_cpuinfo_field(cpuinfo,
  856. cpuinfo_len,
  857. "Hardware");
  858. if (hardware) {
  859. if (!strcmp(hardware, "Goldfish") &&
  860. g_cpuIdArm == 0x4100c080 &&
  861. (g_cpuFamily & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0) {
  862. g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM;
  863. }
  864. free(hardware);
  865. }
  866. }
  867. #endif /* __arm__ */
  868. #ifdef __aarch64__
  869. {
  870. /* Extract the list of CPU features from ELF hwcaps */
  871. uint32_t hwcaps = 0;
  872. hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
  873. if (hwcaps != 0) {
  874. int has_fp = (hwcaps & HWCAP_FP);
  875. int has_asimd = (hwcaps & HWCAP_ASIMD);
  876. int has_aes = (hwcaps & HWCAP_AES);
  877. int has_pmull = (hwcaps & HWCAP_PMULL);
  878. int has_sha1 = (hwcaps & HWCAP_SHA1);
  879. int has_sha2 = (hwcaps & HWCAP_SHA2);
  880. int has_crc32 = (hwcaps & HWCAP_CRC32);
  881. if(has_fp == 0) {
  882. D("ERROR: Floating-point unit missing, but is required by Android on AArch64 CPUs\n");
  883. }
  884. if(has_asimd == 0) {
  885. D("ERROR: ASIMD unit missing, but is required by Android on AArch64 CPUs\n");
  886. }
  887. if (has_fp)
  888. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_FP;
  889. if (has_asimd)
  890. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_ASIMD;
  891. if (has_aes)
  892. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_AES;
  893. if (has_pmull)
  894. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_PMULL;
  895. if (has_sha1)
  896. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA1;
  897. if (has_sha2)
  898. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA2;
  899. if (has_crc32)
  900. g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_CRC32;
  901. }
  902. }
  903. #endif /* __aarch64__ */
  904. #if defined(__i386__) || defined(__x86_64__)
  905. int regs[4];
  906. /* According to http://en.wikipedia.org/wiki/CPUID */
  907. #define VENDOR_INTEL_b 0x756e6547
  908. #define VENDOR_INTEL_c 0x6c65746e
  909. #define VENDOR_INTEL_d 0x49656e69
  910. x86_cpuid(0, regs);
  911. int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
  912. regs[2] == VENDOR_INTEL_c &&
  913. regs[3] == VENDOR_INTEL_d);
  914. x86_cpuid(1, regs);
  915. if ((regs[2] & (1 << 9)) != 0) {
  916. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3;
  917. }
  918. if ((regs[2] & (1 << 23)) != 0) {
  919. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
  920. }
  921. if ((regs[2] & (1 << 19)) != 0) {
  922. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_1;
  923. }
  924. if ((regs[2] & (1 << 20)) != 0) {
  925. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_2;
  926. }
  927. if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) {
  928. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
  929. }
  930. if ((regs[2] & (1 << 25)) != 0) {
  931. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AES_NI;
  932. }
  933. if ((regs[2] & (1 << 28)) != 0) {
  934. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX;
  935. }
  936. if ((regs[2] & (1 << 30)) != 0) {
  937. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_RDRAND;
  938. }
  939. x86_cpuid(7, regs);
  940. if ((regs[1] & (1 << 5)) != 0) {
  941. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX2;
  942. }
  943. if ((regs[1] & (1 << 29)) != 0) {
  944. g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SHA_NI;
  945. }
  946. #endif
  947. #if defined( __mips__)
  948. { /* MIPS and MIPS64 */
  949. /* Extract the list of CPU features from ELF hwcaps */
  950. uint32_t hwcaps = 0;
  951. hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
  952. if (hwcaps != 0) {
  953. int has_r6 = (hwcaps & HWCAP_MIPS_R6);
  954. int has_msa = (hwcaps & HWCAP_MIPS_MSA);
  955. if (has_r6)
  956. g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6;
  957. if (has_msa)
  958. g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA;
  959. }
  960. }
  961. #endif /* __mips__ */
  962. free(cpuinfo);
  963. }
  964. AndroidCpuFamily
  965. android_getCpuFamily(void)
  966. {
  967. pthread_once(&g_once, android_cpuInit);
  968. return g_cpuFamily;
  969. }
  970. uint64_t
  971. android_getCpuFeatures(void)
  972. {
  973. pthread_once(&g_once, android_cpuInit);
  974. return g_cpuFeatures;
  975. }
  976. int
  977. android_getCpuCount(void)
  978. {
  979. pthread_once(&g_once, android_cpuInit);
  980. return g_cpuCount;
  981. }
  982. static void
  983. android_cpuInitDummy(void)
  984. {
  985. g_inited = 1;
  986. }
  987. int
  988. android_setCpu(int cpu_count, uint64_t cpu_features)
  989. {
  990. /* Fail if the library was already initialized. */
  991. if (g_inited)
  992. return 0;
  993. android_cpuInitFamily();
  994. g_cpuCount = (cpu_count <= 0 ? 1 : cpu_count);
  995. g_cpuFeatures = cpu_features;
  996. pthread_once(&g_once, android_cpuInitDummy);
  997. return 1;
  998. }
  999. #ifdef __arm__
  1000. uint32_t
  1001. android_getCpuIdArm(void)
  1002. {
  1003. pthread_once(&g_once, android_cpuInit);
  1004. return g_cpuIdArm;
  1005. }
  1006. int
  1007. android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id)
  1008. {
  1009. if (!android_setCpu(cpu_count, cpu_features))
  1010. return 0;
  1011. g_cpuIdArm = cpu_id;
  1012. return 1;
  1013. }
  1014. #endif /* __arm__ */
  1015. /*
  1016. * Technical note: Making sense of ARM's FPU architecture versions.
  1017. *
  1018. * FPA was ARM's first attempt at an FPU architecture. There is no Android
  1019. * device that actually uses it since this technology was already obsolete
  1020. * when the project started. If you see references to FPA instructions
  1021. * somewhere, you can be sure that this doesn't apply to Android at all.
  1022. *
  1023. * FPA was followed by "VFP", soon renamed "VFPv1" due to the emergence of
  1024. * new versions / additions to it. ARM considers this obsolete right now,
  1025. * and no known Android device implements it either.
  1026. *
  1027. * VFPv2 added a few instructions to VFPv1, and is an *optional* extension
  1028. * supported by some ARMv5TE, ARMv6 and ARMv6T2 CPUs. Note that a device
  1029. * supporting the 'armeabi' ABI doesn't necessarily support these.
  1030. *
  1031. * VFPv3-D16 adds a few instructions on top of VFPv2 and is typically used
  1032. * on ARMv7-A CPUs which implement a FPU. Note that it is also mandated
  1033. * by the Android 'armeabi-v7a' ABI. The -D16 suffix in its name means
  1034. * that it provides 16 double-precision FPU registers (d0-d15) and 32
  1035. * single-precision ones (s0-s31) which happen to be mapped to the same
  1036. * register banks.
  1037. *
  1038. * VFPv3-D32 is the name of an extension to VFPv3-D16 that provides 16
  1039. * additional double precision registers (d16-d31). Note that there are
  1040. * still only 32 single precision registers.
  1041. *
  1042. * VFPv3xD is a *subset* of VFPv3-D16 that only provides single-precision
  1043. * registers. It is only used on ARMv7-M (i.e. on micro-controllers) which
  1044. * are not supported by Android. Note that it is not compatible with VFPv2.
  1045. *
  1046. * NOTE: The term 'VFPv3' usually designate either VFPv3-D16 or VFPv3-D32
  1047. * depending on context. For example GCC uses it for VFPv3-D32, but
  1048. * the Linux kernel code uses it for VFPv3-D16 (especially in
  1049. * /proc/cpuinfo). Always try to use the full designation when
  1050. * possible.
  1051. *
  1052. * NEON, a.k.a. "ARM Advanced SIMD" is an extension that provides
  1053. * instructions to perform parallel computations on vectors of 8, 16,
  1054. * 32, 64 and 128 bit quantities. NEON requires VFPv32-D32 since all
  1055. * NEON registers are also mapped to the same register banks.
  1056. *
  1057. * VFPv4-D16, adds a few instructions on top of VFPv3-D16 in order to
  1058. * perform fused multiply-accumulate on VFP registers, as well as
  1059. * half-precision (16-bit) conversion operations.
  1060. *
  1061. * VFPv4-D32 is VFPv4-D16 with 32, instead of 16, FPU double precision
  1062. * registers.
  1063. *
  1064. * VPFv4-NEON is VFPv4-D32 with NEON instructions. It also adds fused
  1065. * multiply-accumulate instructions that work on the NEON registers.
  1066. *
  1067. * NOTE: Similarly, "VFPv4" might either reference VFPv4-D16 or VFPv4-D32
  1068. * depending on context.
  1069. *
  1070. * The following information was determined by scanning the binutils-2.22
  1071. * sources:
  1072. *
  1073. * Basic VFP instruction subsets:
  1074. *
  1075. * #define FPU_VFP_EXT_V1xD 0x08000000 // Base VFP instruction set.
  1076. * #define FPU_VFP_EXT_V1 0x04000000 // Double-precision insns.
  1077. * #define FPU_VFP_EXT_V2 0x02000000 // ARM10E VFPr1.
  1078. * #define FPU_VFP_EXT_V3xD 0x01000000 // VFPv3 single-precision.
  1079. * #define FPU_VFP_EXT_V3 0x00800000 // VFPv3 double-precision.
  1080. * #define FPU_NEON_EXT_V1 0x00400000 // Neon (SIMD) insns.
  1081. * #define FPU_VFP_EXT_D32 0x00200000 // Registers D16-D31.
  1082. * #define FPU_VFP_EXT_FP16 0x00100000 // Half-precision extensions.
  1083. * #define FPU_NEON_EXT_FMA 0x00080000 // Neon fused multiply-add
  1084. * #define FPU_VFP_EXT_FMA 0x00040000 // VFP fused multiply-add
  1085. *
  1086. * FPU types (excluding NEON)
  1087. *
  1088. * FPU_VFP_V1xD (EXT_V1xD)
  1089. * |
  1090. * +--------------------------+
  1091. * | |
  1092. * FPU_VFP_V1 (+EXT_V1) FPU_VFP_V3xD (+EXT_V2+EXT_V3xD)
  1093. * | |
  1094. * | |
  1095. * FPU_VFP_V2 (+EXT_V2) FPU_VFP_V4_SP_D16 (+EXT_FP16+EXT_FMA)
  1096. * |
  1097. * FPU_VFP_V3D16 (+EXT_Vx3D+EXT_V3)
  1098. * |
  1099. * +--------------------------+
  1100. * | |
  1101. * FPU_VFP_V3 (+EXT_D32) FPU_VFP_V4D16 (+EXT_FP16+EXT_FMA)
  1102. * | |
  1103. * | FPU_VFP_V4 (+EXT_D32)
  1104. * |
  1105. * FPU_VFP_HARD (+EXT_FMA+NEON_EXT_FMA)
  1106. *
  1107. * VFP architectures:
  1108. *
  1109. * ARCH_VFP_V1xD (EXT_V1xD)
  1110. * |
  1111. * +------------------+
  1112. * | |
  1113. * | ARCH_VFP_V3xD (+EXT_V2+EXT_V3xD)
  1114. * | |
  1115. * | ARCH_VFP_V3xD_FP16 (+EXT_FP16)
  1116. * | |
  1117. * | ARCH_VFP_V4_SP_D16 (+EXT_FMA)
  1118. * |
  1119. * ARCH_VFP_V1 (+EXT_V1)
  1120. * |
  1121. * ARCH_VFP_V2 (+EXT_V2)
  1122. * |
  1123. * ARCH_VFP_V3D16 (+EXT_V3xD+EXT_V3)
  1124. * |
  1125. * +-------------------+
  1126. * | |
  1127. * | ARCH_VFP_V3D16_FP16 (+EXT_FP16)
  1128. * |
  1129. * +-------------------+
  1130. * | |
  1131. * | ARCH_VFP_V4_D16 (+EXT_FP16+EXT_FMA)
  1132. * | |
  1133. * | ARCH_VFP_V4 (+EXT_D32)
  1134. * | |
  1135. * | ARCH_NEON_VFP_V4 (+EXT_NEON+EXT_NEON_FMA)
  1136. * |
  1137. * ARCH_VFP_V3 (+EXT_D32)
  1138. * |
  1139. * +-------------------+
  1140. * | |
  1141. * | ARCH_VFP_V3_FP16 (+EXT_FP16)
  1142. * |
  1143. * ARCH_VFP_V3_PLUS_NEON_V1 (+EXT_NEON)
  1144. * |
  1145. * ARCH_NEON_FP16 (+EXT_FP16)
  1146. *
  1147. * -fpu=<name> values and their correspondance with FPU architectures above:
  1148. *
  1149. * {"vfp", FPU_ARCH_VFP_V2},
  1150. * {"vfp9", FPU_ARCH_VFP_V2},
  1151. * {"vfp3", FPU_ARCH_VFP_V3}, // For backwards compatbility.
  1152. * {"vfp10", FPU_ARCH_VFP_V2},
  1153. * {"vfp10-r0", FPU_ARCH_VFP_V1},
  1154. * {"vfpxd", FPU_ARCH_VFP_V1xD},
  1155. * {"vfpv2", FPU_ARCH_VFP_V2},
  1156. * {"vfpv3", FPU_ARCH_VFP_V3},
  1157. * {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
  1158. * {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
  1159. * {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
  1160. * {"vfpv3xd", FPU_ARCH_VFP_V3xD},
  1161. * {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
  1162. * {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
  1163. * {"neon-fp16", FPU_ARCH_NEON_FP16},
  1164. * {"vfpv4", FPU_ARCH_VFP_V4},
  1165. * {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
  1166. * {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
  1167. * {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
  1168. *
  1169. *
  1170. * Simplified diagram that only includes FPUs supported by Android:
  1171. * Only ARCH_VFP_V3D16 is actually mandated by the armeabi-v7a ABI,
  1172. * all others are optional and must be probed at runtime.
  1173. *
  1174. * ARCH_VFP_V3D16 (EXT_V1xD+EXT_V1+EXT_V2+EXT_V3xD+EXT_V3)
  1175. * |
  1176. * +-------------------+
  1177. * | |
  1178. * | ARCH_VFP_V3D16_FP16 (+EXT_FP16)
  1179. * |
  1180. * +-------------------+
  1181. * | |
  1182. * | ARCH_VFP_V4_D16 (+EXT_FP16+EXT_FMA)
  1183. * | |
  1184. * | ARCH_VFP_V4 (+EXT_D32)
  1185. * | |
  1186. * | ARCH_NEON_VFP_V4 (+EXT_NEON+EXT_NEON_FMA)
  1187. * |
  1188. * ARCH_VFP_V3 (+EXT_D32)
  1189. * |
  1190. * +-------------------+
  1191. * | |
  1192. * | ARCH_VFP_V3_FP16 (+EXT_FP16)
  1193. * |
  1194. * ARCH_VFP_V3_PLUS_NEON_V1 (+EXT_NEON)
  1195. * |
  1196. * ARCH_NEON_FP16 (+EXT_FP16)
  1197. *
  1198. */