diff options
| author | Folkert de Vries <folkert@folkertdev.nl> | 2025-06-12 17:53:42 +0200 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2025-06-19 15:31:16 +0000 |
| commit | 359f986dddd987b7ab1c7c5b141eba71f4a2ffad (patch) | |
| tree | d87d1512f48b206308708843d719575021d4d9ff /library/stdarch/crates/std_detect/src/detect | |
| parent | 26b7dd430436ec1441c6115c709acbbc69bd9c67 (diff) | |
| download | rust-359f986dddd987b7ab1c7c5b141eba71f4a2ffad.tar.gz rust-359f986dddd987b7ab1c7c5b141eba71f4a2ffad.zip | |
s390x: add feature detection for the z17 target features
Diffstat (limited to 'library/stdarch/crates/std_detect/src/detect')
| -rw-r--r-- | library/stdarch/crates/std_detect/src/detect/arch/s390x.rs | 21 | ||||
| -rw-r--r-- | library/stdarch/crates/std_detect/src/detect/os/linux/s390x.rs | 132 |
2 files changed, 97 insertions, 56 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/arch/s390x.rs b/library/stdarch/crates/std_detect/src/detect/arch/s390x.rs index f05081da9af..4c20d011680 100644 --- a/library/stdarch/crates/std_detect/src/detect/arch/s390x.rs +++ b/library/stdarch/crates/std_detect/src/detect/arch/s390x.rs @@ -22,9 +22,30 @@ features! { @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] high_word: "high-word"; /// s390x high-word facility #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension3: "message-security-assist-extension3"; + /// s390x message-security-assist-extension3 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension4: "message-security-assist-extension4"; + /// s390x message-security-assist-extension4 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension5: "message-security-assist-extension5"; + /// s390x message-security-assist-extension5 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension8: "message-security-assist-extension8"; + /// s390x message-security-assist-extension8 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension9: "message-security-assist-extension9"; + /// s390x message-security-assist-extension9 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; + /// s390x miscellaneous-extensions-2 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; + /// s390x miscellaneous-extensions-3 facility + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] @FEATURE: #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/s390x.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/s390x.rs index 5cc35fd3025..9b53f526d61 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/linux/s390x.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/linux/s390x.rs @@ -5,19 +5,11 @@ use crate::detect::{Feature, bit, cache}; /// Try to read the features from the auxiliary vector pub(crate) fn detect_features() -> cache::Initializer { - if let Ok(auxv) = auxvec::auxv() { - let hwcap: AtHwcap = auxv.into(); - return hwcap.cache(); - } - - cache::Initializer::default() + let opt_hwcap: Option<AtHwcap> = auxvec::auxv().ok().map(Into::into); + let facilities = ExtendedFacilityList::new(); + cache(opt_hwcap, facilities) } -/// These values are part of the platform-specific [asm/elf.h][kernel], and are a selection of the -/// fields found in the [Facility Indications]. -/// -/// [Facility Indications]: https://www.ibm.com/support/pages/sites/default/files/2021-05/SA22-7871-10.pdf#page=63 -/// [kernel]: https://github.com/torvalds/linux/blob/b62cef9a5c673f1b8083159f5dc03c1c5daced2f/arch/s390/include/asm/elf.h#L129 #[derive(Debug, Default, PartialEq)] struct AtHwcap { esan3: bool, @@ -76,57 +68,85 @@ impl From<auxvec::AuxVec> for AtHwcap { } } -impl AtHwcap { - /// Initializes the cache from the feature bits. - fn cache(self) -> cache::Initializer { - let mut value = cache::Initializer::default(); - { - let mut enable_feature = |f, enable| { - if enable { - value.set(f as u32); - } - }; - - // vector and related - - // bit 129 of the extended facility list - enable_feature(Feature::vector, self.vxrs); - - // bit 135 of the extended facility list - enable_feature(Feature::vector_enhancements_1, self.vxrs_ext); - - // bit 148 of the extended facility list - enable_feature(Feature::vector_enhancements_2, self.vxrs_ext2); - - // bit 134 of the extended facility list - enable_feature(Feature::vector_packed_decimal, self.vxrs_bcd); - - // bit 152 of the extended facility list - enable_feature(Feature::vector_packed_decimal_enhancement, self.vxrs_pde); - - // bit 192 of the extended facility list - enable_feature(Feature::vector_packed_decimal_enhancement_2, self.vxrs_pde2); - - // bit 165 of the extended facility list - enable_feature(Feature::nnp_assist, self.nnpa); +struct ExtendedFacilityList([u64; 4]); + +impl ExtendedFacilityList { + fn new() -> Self { + let mut result: [u64; 4] = [0; 4]; + // SAFETY: rust/llvm only support s390x version with the `stfle` instruction. + unsafe { + core::arch::asm!( + // equivalently ".insn s, 0xb2b00000, 0({1})", + "stfle 0({})", + in(reg_addr) result.as_mut_ptr() , + inout("r0") result.len() as u64 - 1 => _, + options(nostack) + ); + } + Self(result) + } - // others + const fn get_bit(&self, n: usize) -> bool { + // NOTE: bits are numbered from the left. + self.0[n / 64] & (1 << (63 - (n % 64))) != 0 + } +} - // bit 45 of the extended facility list - enable_feature(Feature::high_word, self.high_gprs); +/// Initializes the cache from the feature bits. +/// +/// These values are part of the platform-specific [asm/elf.h][kernel], and are a selection of the +/// fields found in the [Facility Indications]. +/// +/// [Facility Indications]: https://www.ibm.com/support/pages/sites/default/files/2021-05/SA22-7871-10.pdf#page=63 +/// [kernel]: https://github.com/torvalds/linux/blob/b62cef9a5c673f1b8083159f5dc03c1c5daced2f/arch/s390/include/asm/elf.h#L129 +fn cache(hwcap: Option<AtHwcap>, facilities: ExtendedFacilityList) -> cache::Initializer { + let mut value = cache::Initializer::default(); + + { + let mut enable_if_set = |bit_index, f| { + if facilities.get_bit(bit_index) { + value.set(f as u32); + } + }; + + // We use HWCAP for `vector` because it requires both hardware and kernel support. + if let Some(AtHwcap { vxrs: true, .. }) = hwcap { + // vector and related - // bit 73 of the extended facility list - enable_feature(Feature::transactional_execution, self.te); + enable_if_set(129, Feature::vector); - // bit 133 of the extended facility list - enable_feature(Feature::guarded_storage, self.gs); + enable_if_set(135, Feature::vector_enhancements_1); + enable_if_set(148, Feature::vector_enhancements_2); + enable_if_set(198, Feature::vector_enhancements_3); - // bit 150 of the extended facility list - enable_feature(Feature::enhanced_sort, self.sort); + enable_if_set(134, Feature::vector_packed_decimal); + enable_if_set(152, Feature::vector_packed_decimal_enhancement); + enable_if_set(192, Feature::vector_packed_decimal_enhancement_2); + enable_if_set(199, Feature::vector_packed_decimal_enhancement_3); - // bit 151 of the extended facility list - enable_feature(Feature::deflate_conversion, self.dflt); + enable_if_set(165, Feature::nnp_assist); } - value + + // others + + enable_if_set(76, Feature::message_security_assist_extension3); + enable_if_set(77, Feature::message_security_assist_extension4); + enable_if_set(57, Feature::message_security_assist_extension5); + enable_if_set(146, Feature::message_security_assist_extension8); + enable_if_set(155, Feature::message_security_assist_extension9); + enable_if_set(86, Feature::message_security_assist_extension12); + + enable_if_set(58, Feature::miscellaneous_extensions_2); + enable_if_set(61, Feature::miscellaneous_extensions_3); + enable_if_set(84, Feature::miscellaneous_extensions_4); + + enable_if_set(45, Feature::high_word); + enable_if_set(73, Feature::transactional_execution); + enable_if_set(133, Feature::guarded_storage); + enable_if_set(150, Feature::enhanced_sort); + enable_if_set(151, Feature::deflate_conversion); + enable_if_set(201, Feature::concurrent_functions); } + + value } |
