Skip to content

Commit a873d1a

Browse files
committed
std_detect: Only check features that are known to be available on armv8.0 cores if CPU is Exynos 9810
1 parent 0adfbec commit a873d1a

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

crates/std_detect/src/detect/os/linux/aarch64.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::detect::{bit, cache, Feature};
77
/// to read them from /proc/cpuinfo.
88
pub(crate) fn detect_features() -> cache::Initializer {
99
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
10-
{
10+
let is_exynos9810 = {
1111
// Samsung Exynos 9810 has a bug that big and little cores have different
1212
// ISAs. And on older Android (pre-9), the kernel incorrectly reports
1313
// that features available only on some cores are available on all cores.
@@ -21,18 +21,19 @@ pub(crate) fn detect_features() -> cache::Initializer {
2121
};
2222
// On Exynos, ro.arch is not available on Android 12+, but it is fine
2323
// because Android 9+ includes the fix.
24-
if len > 0 && arch.starts_with(b"exynos9810") {
25-
return cache::Initializer::default();
26-
}
27-
}
24+
len > 0 && arch.starts_with(b"exynos9810")
25+
};
26+
#[cfg(not(all(target_arch = "aarch64", target_os = "android")))]
27+
let is_exynos9810 = false;
28+
2829
if let Ok(auxv) = auxvec::auxv() {
2930
let hwcap: AtHwcap = auxv.into();
30-
return hwcap.cache();
31+
return hwcap.cache(is_exynos9810);
3132
}
3233
#[cfg(feature = "std_detect_file_io")]
3334
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
3435
let hwcap: AtHwcap = c.into();
35-
return hwcap.cache();
36+
return hwcap.cache(is_exynos9810);
3637
}
3738
cache::Initializer::default()
3839
}
@@ -228,7 +229,7 @@ impl AtHwcap {
228229
///
229230
/// The feature dependencies here come directly from LLVM's feature definintions:
230231
/// https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AArch64/AArch64.td
231-
fn cache(self) -> cache::Initializer {
232+
fn cache(self, is_exynos9810: bool) -> cache::Initializer {
232233
let mut value = cache::Initializer::default();
233234
{
234235
let mut enable_feature = |f, enable| {
@@ -237,6 +238,24 @@ impl AtHwcap {
237238
}
238239
};
239240

241+
// Samsung Exynos 9810 has a bug that big and little cores have different
242+
// ISAs. And on older Android (pre-9), the kernel incorrectly reports
243+
// that features available only on some cores are available on all cores.
244+
// So, only check features that are known to be available on exynos-m3:
245+
// $ rustc --print cfg --target aarch64-linux-android -C target-cpu=exynos-m3 | grep target_feature
246+
if is_exynos9810 {
247+
enable_feature(Feature::fp, self.fp);
248+
enable_feature(Feature::crc, self.crc32);
249+
// ASIMD support requires float support - if half-floats are
250+
// supported, it also requires half-float support:
251+
let asimd = self.fp && self.asimd && (!self.fphp | self.asimdhp);
252+
enable_feature(Feature::asimd, asimd);
253+
// Cryptographic extensions require ASIMD
254+
enable_feature(Feature::aes, self.aes && asimd);
255+
enable_feature(Feature::sha2, self.sha1 && self.sha2 && asimd);
256+
return value;
257+
}
258+
240259
enable_feature(Feature::fp, self.fp);
241260
// Half-float support requires float support
242261
enable_feature(Feature::fp16, self.fp && self.fphp);

0 commit comments

Comments
 (0)