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}