@@ -7,7 +7,7 @@ use crate::detect::{bit, cache, Feature};
77/// to read them from /proc/cpuinfo.
88pub ( 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