Commit dfcc456c authored by Jan Schmidt's avatar Jan Schmidt

Add fallback CPU feature detection for Android

On Android, /proc/self/auxv might not be readable (except
when debuggable=true in the build, annoyingly), so do what
the android cpufeatures detection code does and fall back to
/proc/cpuinfo string matching.

Without this, release builds run really slowly, due to ORC always
doing emulation.
parent 3c7cb2d3
......@@ -71,6 +71,7 @@ orc_check_neon_proc_auxv (void)
fd = open("/proc/self/auxv", O_RDONLY);
if (fd < 0) {
ORC_LOG ("Failed to open /proc/self/auxv");
return 0;
}
......@@ -99,39 +100,7 @@ orc_check_neon_proc_auxv (void)
}
#endif
#ifdef unused
static void
orc_cpu_arm_getflags_cpuinfo (char *cpuinfo)
{
char *cpuinfo_flags;
char **flags;
char **f;
cpuinfo_flags = get_cpuinfo_line(cpuinfo, "Features");
if (cpuinfo_flags == NULL) {
free (cpuinfo);
return;
}
flags = strsplit(cpuinfo_flags, ' ');
for (f = flags; *f; f++) {
#if 0
if (strcmp (*f, "edsp") == 0) {
ORC_DEBUG ("cpu feature %s", *f);
orc_cpu_flags |= ORC_CPU_FLAG_EDSP;
}
if (strcmp (*f, "vfp") == 0) {
ORC_DEBUG ("cpu feature %s", *f);
orc_cpu_flags |= ORC_CPU_FLAG_VFP;
}
#endif
free (*f);
}
free (flags);
free (cpuinfo_flags);
}
#ifdef ANDROID
static char *
get_proc_cpuinfo (void)
{
......@@ -160,56 +129,96 @@ get_proc_cpuinfo (void)
return cpuinfo;
}
#endif
unsigned long
orc_arm_get_cpu_flags (void)
static char *
get_cpuinfo_line (char *cpuinfo, const char *tag)
{
unsigned long neon_flags = 0;
char *flags;
char *end;
char *colon;
#ifdef __linux__
neon_flags = orc_check_neon_proc_auxv ();
#endif
#ifdef unused
#ifdef __linux__
int arm_implementer = 0;
flags = strstr(cpuinfo,tag);
if (flags == NULL) return NULL;
end = strchr(flags, '\n');
if (end == NULL) return NULL;
colon = strchr (flags, ':');
if (colon == NULL) return NULL;
colon++;
if(colon >= end) return NULL;
return _strndup (colon, end-colon);
}
static unsigned long
orc_cpu_arm_getflags_cpuinfo ()
{
unsigned long ret = 0;
char *cpuinfo;
char *s;
char *cpuinfo_line;
char **flags;
char **f;
cpuinfo = get_proc_cpuinfo();
if (cpuinfo == NULL) return;
if (cpuinfo == NULL) {
ORC_DEBUG ("Failed to read /proc/cpuinfo");
return 0;
}
cpuinfo_line = get_cpuinfo_line(cpuinfo, "CPU architecture");
if (cpuinfo_line) {
int arm_arch = strtoul (cpuinfo_line, NULL, 0);
if (arm_arch >= 8L) {
/* Armv8 always supports these, but they won't be listed
* in the CPU info optional features */
ret = ORC_TARGET_ARM_EDSP | ORC_TARGET_NEON_NEON;
goto out;
}
s = get_cpuinfo_line(cpuinfo, "CPU implementer");
if (s) {
arm_implementer = strtoul (s, NULL, 0);
free(s);
free(cpuinfo_line);
}
switch(arm_implementer) {
case 0x69: /* Intel */
case 0x41: /* ARM */
/* ARM chips are known to not have timestamping available from
* user space */
break;
default:
break;
cpuinfo_line = get_cpuinfo_line(cpuinfo, "Features");
if (cpuinfo_line == NULL) {
free (cpuinfo);
return 0;
}
#if 0
s = get_cpuinfo_line(cpuinfo, "CPU architecture");
if (s) {
int arm_arch;
arm_arch = strtoul (s, NULL, 0);
if (arm_arch >= 6)
orc_cpu_flags |= ORC_CPU_FLAG_ARM6;
free(s);
flags = strsplit(cpuinfo_line, ' ');
for (f = flags; *f; f++) {
if (strcmp (*f, "edsp") == 0)
ret |= ORC_TARGET_ARM_EDSP;
else if (strcmp (*f, "neon") == 0)
ret |= ORC_TARGET_NEON_NEON;
free (*f);
}
#endif
orc_cpu_arm_getflags_cpuinfo (cpuinfo);
free (flags);
out:
free (cpuinfo_line);
free (cpuinfo);
return ret;
}
#endif
unsigned long
orc_arm_get_cpu_flags (void)
{
unsigned long neon_flags = 0;
#ifdef __linux__
neon_flags = orc_check_neon_proc_auxv ();
#endif
#ifdef ANDROID
if (!neon_flags) {
/* On ARM, /proc/self/auxv might not be accessible.
* Fall back to /proc/cpuinfo */
neon_flags = orc_cpu_arm_getflags_cpuinfo ();
}
#endif
if (orc_compiler_flag_check ("-neon")) {
neon_flags &= ~ORC_TARGET_NEON_NEON;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment