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