osiris_data/data/
atomic.rs

1//! This module defines [Word] and [HalfWord].
2
3/// Describes the machine's base type. Every base operation occurs on this type.
4#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
5pub struct Word(u64);
6
7/// Describes a half-word. This type is the half of the size of [Word].
8#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
9pub struct HalfWord(u32);
10
11impl HalfWord {
12    /// Creates a new half-word from its 32 bits value.
13    pub const fn new(value: u32) -> Self {
14        Self(value)
15    }
16
17    /// Returns a 32 bits value representing the half-word.
18    pub const fn to_u32(&self) -> u32 { self.0 }
19
20    /// Returns a 64 bits value representing the half-word. The 32 bits on the top (left) are always zeros.
21    pub const fn to_u64(&self) -> u64 { self.0 as u64 }
22}
23
24impl Word {
25    /// Creates a new word from its 64 bits value.
26    pub const fn new(value: u64) -> Self {
27        Self(value)
28    }
29    /// Creates a new word from its 64 bits value.
30    pub const fn from_usize(value: usize) -> Self {
31        Self(value as u64)
32    }
33
34    /// Create a native endian integer value from its representation as a byte array in big endian.
35    pub const fn from_be_bytes(value: [u8; 8]) -> Self {
36        Self::new(u64::from_be_bytes(value))
37    }
38
39    /// Creates a new word from two half-words.
40    pub const fn merge(top: HalfWord, bottom: HalfWord) -> Self {
41        Self(top.to_u64() << 32 | bottom.to_u64())
42    }
43
44    /// Returns a 64 bits value representing the word.
45    pub const fn to_u64(&self) -> u64 { self.0 }
46
47    /// Return the memory representation of this integer as a byte array in big-endian (network) byte order.
48    pub const fn to_be_bytes(&self) -> [u8; 8] { self.0.to_be_bytes() }
49
50    /// Returns two 32 bits half-words splitting the 64 bits word.
51    pub const fn split(&self) -> [HalfWord; 2] {
52        let top = (self.0 >> 32) as u32;
53        let bottom = self.0 as u32;
54        [HalfWord(top), HalfWord(bottom)]
55    }
56
57    /// Returns two 32 bits half-words splitting the 64 bits word.
58    #[inline]
59    pub const fn pair(&self) -> (HalfWord, HalfWord) {
60        let [a, b] = self.split();
61        (a, b)
62    }
63
64    /// Returns the 32 first left bits of the word.
65    pub const fn top(&self) -> HalfWord {
66        let [top, _] = self.split();
67        top
68    }
69
70    /// Returns the 32 last right bits of the word.
71    pub const fn bottom(&self) -> HalfWord {
72        let [_, bottom] = self.split();
73        bottom
74    }
75}
76
77impl HalfWord {
78    /// Merges the current [HalfWord] with another into a whole [Word].
79    ///
80    /// The current half-word is the top of the new word while `other` is the bottom.
81    ///
82    /// ### Example
83    /// ```
84    /// use osiris_data::data::atomic::{HalfWord, Word};
85    ///
86    /// let top = HalfWord::default();
87    /// let bottom = HalfWord::default();
88    ///
89    /// let whole: Word = top.with(bottom);
90    ///
91    /// let [top, bottom] = whole.split();
92    ///
93    /// let whole = Word::merge(top, bottom);
94    /// ```
95    pub const fn with(self, other: HalfWord) -> Word {
96        Word::merge(self, other)
97    }
98}