peakrdl_rust/
endian.rs

1//! Register endianness implementations
2
3use num_traits::PrimInt;
4
5/// Endianness of a register
6#[allow(private_bounds)]
7pub trait Endian: Sealed + Copy {
8    /// Convert from native endianness to register endianness.
9    fn to_register_endian<T: PrimInt>(value: T) -> T;
10
11    /// Convert from register endianness to native endianness.
12    fn from_register_endian<T: PrimInt>(value: T) -> T;
13
14    /// Given the address order of a subword, return the sigificance order
15    /// of the subword.
16    ///
17    /// For example, if `address_order_to_significance(1, 2) == 0`, it indicates
18    /// that the subword at the second-to-lowest address (`address_order == 1`)
19    /// is the least significant subword in the register (`== 0`).
20    fn address_order_to_significance(address_order: usize, num_subwords: usize) -> usize;
21}
22
23/// Big endian byte and word ordering
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct BigEndian;
26/// Little endian byte and word ordering
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct LittleEndian;
29
30trait Sealed {}
31impl Sealed for BigEndian {}
32impl Sealed for LittleEndian {}
33
34impl Endian for BigEndian {
35    fn to_register_endian<T: PrimInt>(value: T) -> T {
36        value.to_be()
37    }
38
39    fn from_register_endian<T: PrimInt>(value: T) -> T {
40        T::from_be(value)
41    }
42
43    fn address_order_to_significance(address_order: usize, num_subwords: usize) -> usize {
44        // The lowest address is the most significant word
45        num_subwords - 1 - address_order
46    }
47}
48
49impl Endian for LittleEndian {
50    fn to_register_endian<T: PrimInt>(value: T) -> T {
51        value.to_le()
52    }
53
54    fn from_register_endian<T: PrimInt>(value: T) -> T {
55        T::from_le(value)
56    }
57
58    fn address_order_to_significance(address_order: usize, _num_subwords: usize) -> usize {
59        // The lowest address is the least significant word
60        address_order
61    }
62}