It is common to build a u64 from its high and low parts obtained from two 32-bit registers. Conversely, it is also common to split a u64 into two u32s to write them into registers. Add an extension trait for u64 that implement these methods in a new `num` module. It is expected that this trait will be extended with other useful operations, and similar extension traits implemented for other types. Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx> --- rust/kernel/lib.rs | 1 + rust/kernel/num.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 8e76ef9b4346956009a936b1317f7474a83c8dbd..caee059249cf56993d5db698a876f040eda33dd5 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -61,6 +61,7 @@ pub mod miscdevice; #[cfg(CONFIG_NET)] pub mod net; +pub mod num; pub mod of; pub mod page; #[cfg(CONFIG_PCI)] diff --git a/rust/kernel/num.rs b/rust/kernel/num.rs new file mode 100644 index 0000000000000000000000000000000000000000..f03c82f13643412cc13b0b841dfdf3b06490926d --- /dev/null +++ b/rust/kernel/num.rs @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Numerical and binary utilities for primitive types. + +/// Useful operations for `u64`. +pub trait U64Ext { + /// Build a `u64` by combining its `high` and `low` parts. + /// + /// ``` + /// use kernel::num::U64Ext; + /// assert_eq!(u64::from_u32s(0x01234567, 0x89abcdef), 0x01234567_89abcdef); + /// ``` + fn from_u32s(high: u32, low: u32) -> Self; + + fn upper_32_bits(self) -> u32; + fn lower_32_bits(self) -> u32; +} + +impl U64Ext for u64 { + fn from_u32s(high: u32, low: u32) -> Self { + ((high as u64) << u32::BITS) | low as u64 + } + + fn upper_32_bits(self) -> u32 { + (self >> u32::BITS) as u32 + } + + fn lower_32_bits(self) -> u32 { + self as u32 + } +} + +pub const fn upper_32_bits(v: u64) -> u32 { + (v >> u32::BITS) as u32 +} + +pub const fn lower_32_bits(v: u64) -> u32 { + v as u32 +} + +pub const fn u32s_to_u64(high: u32, low: u32) -> u64 { + ((high as u64) << u32::BITS) | low as u64 +} -- 2.48.1