diff options
| author | Taiki Endo <te316e89@gmail.com> | 2023-01-26 00:50:42 +0900 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2023-01-26 23:33:52 +0000 |
| commit | d3bb923c82da9df128a6faad659bdee9e2008821 (patch) | |
| tree | 0c5406f6a1a86deb8ad8cf99a2b4aa1939308689 /library/stdarch/crates/std_detect/src | |
| parent | 674fd58f608a0bf4f551c82fad4a28e8297c5feb (diff) | |
| download | rust-d3bb923c82da9df128a6faad659bdee9e2008821.tar.gz rust-d3bb923c82da9df128a6faad659bdee9e2008821.zip | |
std_detect: Split os/aarch64.rs' detect_features into reading and parsing
Diffstat (limited to 'library/stdarch/crates/std_detect/src')
| -rw-r--r-- | library/stdarch/crates/std_detect/src/detect/os/aarch64.rs | 135 |
1 files changed, 72 insertions, 63 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs index e0e62ee3393..bda5f1bf2de 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs @@ -23,77 +23,86 @@ use core::arch::asm; /// /// This will cause SIGILL if the current OS is not trapping the mrs instruction. pub(crate) fn detect_features() -> cache::Initializer { - let mut value = cache::Initializer::default(); + // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 + let aa64isar0: u64; + unsafe { + asm!( + "mrs {}, ID_AA64ISAR0_EL1", + out(reg) aa64isar0, + options(pure, nomem, preserves_flags, nostack) + ); + } - { - let mut enable_feature = |f, enable| { - if enable { - value.set(f as u32); - } - }; + // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1 + let aa64isar1: u64; + unsafe { + asm!( + "mrs {}, ID_AA64ISAR1_EL1", + out(reg) aa64isar1, + options(pure, nomem, preserves_flags, nostack) + ); + } - // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 - let aa64isar0: u64; - unsafe { - asm!( - "mrs {}, ID_AA64ISAR0_EL1", - out(reg) aa64isar0, - options(pure, nomem, preserves_flags, nostack) - ); - } + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + let aa64pfr0: u64; + unsafe { + asm!( + "mrs {}, ID_AA64PFR0_EL1", + out(reg) aa64pfr0, + options(pure, nomem, preserves_flags, nostack) + ); + } + + parse_system_registers(aa64isar0, aa64isar1, aa64pfr0) +} - enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2); - enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1); - enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1); - enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1); +pub(crate) fn parse_system_registers( + aa64isar0: u64, + aa64isar1: u64, + aa64pfr0: u64, +) -> cache::Initializer { + let mut value = cache::Initializer::default(); - // ID_AA64PFR0_EL1 - Processor Feature Register 0 - let aa64pfr0: u64; - unsafe { - asm!( - "mrs {}, ID_AA64PFR0_EL1", - out(reg) aa64pfr0, - options(pure, nomem, preserves_flags, nostack) - ); + let mut enable_feature = |f, enable| { + if enable { + value.set(f as u32); } + }; - let fp = bits_shift(aa64pfr0, 19, 16) < 0xF; - let fphp = bits_shift(aa64pfr0, 19, 16) >= 1; - let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF; - let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1; - enable_feature(Feature::fp, fp); - enable_feature(Feature::fp16, fphp); - // SIMD support requires float support - if half-floats are - // supported, it also requires half-float support: - enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp)); - // SIMD extensions require SIMD support: - enable_feature(Feature::aes, asimd && bits_shift(aa64isar0, 7, 4) >= 1); - let sha1 = bits_shift(aa64isar0, 11, 8) >= 1; - let sha2 = bits_shift(aa64isar0, 15, 12) >= 1; - enable_feature(Feature::sha2, asimd && sha1 && sha2); - enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1); - enable_feature( - Feature::dotprod, - asimd && bits_shift(aa64isar0, 47, 44) >= 1, - ); - enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1); + // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0 + enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2); + enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1); + enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1); + enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1); - // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1 - let aa64isar1: u64; - unsafe { - asm!( - "mrs {}, ID_AA64ISAR1_EL1", - out(reg) aa64isar1, - options(pure, nomem, preserves_flags, nostack) - ); - } + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + let fp = bits_shift(aa64pfr0, 19, 16) < 0xF; + let fphp = bits_shift(aa64pfr0, 19, 16) >= 1; + let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF; + let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1; + enable_feature(Feature::fp, fp); + enable_feature(Feature::fp16, fphp); + // SIMD support requires float support - if half-floats are + // supported, it also requires half-float support: + enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp)); + // SIMD extensions require SIMD support: + enable_feature(Feature::aes, asimd && bits_shift(aa64isar0, 7, 4) >= 1); + let sha1 = bits_shift(aa64isar0, 11, 8) >= 1; + let sha2 = bits_shift(aa64isar0, 15, 12) >= 1; + enable_feature(Feature::sha2, asimd && sha1 && sha2); + enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1); + enable_feature( + Feature::dotprod, + asimd && bits_shift(aa64isar0, 47, 44) >= 1, + ); + enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1); - // Check for either APA or API field - enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1); - enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1); - // Check for either GPA or GPI field - enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1); - } + // ID_AA64PFR0_EL1 - Processor Feature Register 0 + // Check for either APA or API field + enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1); + enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1); + // Check for either GPA or GPI field + enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1); value } |
