cpu-features.c 41 KB

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