mirror of
https://github.com/google/cpu_features.git
synced 2025-04-27 15:12:30 +02:00
Fix a getauxval comment and expand the Krait idiv workaround (#206)
* Fix getauxval comment (API 18 not 20)
getauxval is available in Android starting with API 18, not 20.
The comment about __ANDROID_API__ appears to have been copied from the
NDK's cpufeatures, which always uses dlopen/dlsym and doesn't assume it
can directly call getauxval, even if __ANDROID_API__ is new enough.
With this project, though, when __ANDROID_API__ is 18 or up, the
CMakeLists.txt file would detect that getauxval is available and define
HAVE_STRONG_GETAUXVAL.
* Broaden Qualcomm Krait idiv workaround
Some Qualcomm Krait CPUs have IDIV support but the kernel doesn't
report it. Previously, this code looked for two CPUs:
- 0x510006F2 (0x51/'Q', variant 0, part 0x06f, rev 2)
- 0x510006F3 (0x51/'Q', variant 0, part 0x06f, rev 3)
This check misses my 2013 Nexus 7 device, which has this CPU ID:
- 0x511006f0 (0x51/'Q', variant 1, part 0x06f, rev 0)
My Nexus 7 device doesn't report idiv through AT_HWCAP or through
/proc/cpuinfo (AT_HWCAP is 0x1b0d7).
Expand the check to anything with:
- implementer 0x51
- architecture 7
- part 0x4d or 0x6f
Part 0x4d appears to be a dual-core Krait (e.g. see
https://crbug.com/341598#c43).
This new matching behavior is a subset of what the upstream kernel
does (patch[1] contributed by CodeAurora), and also closely matches the
behavior of pytorch/cpuinfo.
[1] 120ecfafab
This commit is contained in:
parent
f1801f0ca1
commit
5f5e6d620f
@ -68,13 +68,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
// On Android we probe the system's C library for a 'getauxval' function and
|
||||
// call it if it exits, or return 0 for failure. This function is available
|
||||
// since API level 20.
|
||||
//
|
||||
// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge
|
||||
// case where some NDK developers use headers for a platform that is newer than
|
||||
// the one really targetted by their application. This is typically done to use
|
||||
// newer native APIs only when running on more recent Android versions, and
|
||||
// requires careful symbol management.
|
||||
// since API level 18.
|
||||
//
|
||||
// Note that getauxval() can't really be re-implemented here, because its
|
||||
// implementation does not parse /proc/self/auxv. Instead it depends on values
|
||||
|
@ -152,13 +152,14 @@ static void FixErrors(ArmInfo* const info,
|
||||
// https://crbug.com/341598.
|
||||
info->features.neon = false;
|
||||
break;
|
||||
case 0x510006F2:
|
||||
case 0x510006F3:
|
||||
// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report
|
||||
// IDIV support.
|
||||
info->features.idiva = true;
|
||||
info->features.idivt = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Some Qualcomm Krait kernels forget to report IDIV support.
|
||||
// https://github.com/torvalds/linux/commit/120ecfafabec382c4feb79ff159ef42a39b6d33b
|
||||
if (info->implementer == 0x51 && info->architecture == 7 &&
|
||||
(info->part == 0x4d || info->part == 0x6f)) {
|
||||
info->features.idiva = true;
|
||||
info->features.idivt = true;
|
||||
}
|
||||
|
||||
// Propagate cpu features.
|
||||
|
@ -327,6 +327,24 @@ CPU revision : 3)");
|
||||
EXPECT_EQ(GetArmCpuId(&info), 0x510006f3);
|
||||
}
|
||||
|
||||
// The 2013 Nexus 7 (Qualcomm Krait) kernel configuration forgets to report IDIV
|
||||
// support.
|
||||
TEST(CpuinfoArmTest, Nexus7_2013_0x511006f0) {
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo",
|
||||
R"(CPU implementer : 0x51
|
||||
CPU architecture: 7
|
||||
CPU variant : 0x1
|
||||
CPU part : 0x06f
|
||||
CPU revision : 0)");
|
||||
const auto info = GetArmInfo();
|
||||
EXPECT_TRUE(info.features.idiva);
|
||||
EXPECT_TRUE(info.features.idivt);
|
||||
|
||||
EXPECT_EQ(GetArmCpuId(&info), 0x511006f0);
|
||||
}
|
||||
|
||||
// The emulator-specific Android 4.2 kernel fails to report support for the
|
||||
// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
|
||||
// CPU implemented by the emulator.
|
||||
|
Loading…
x
Reference in New Issue
Block a user