Skip to main content

osom_encoders_x86_64/models/
scale.rs

1use core::mem::transmute;
2
3/// Represents the scale factor for the index register in a memory operand.
4///
5/// # Values
6///
7/// - `Scale1` - The index register is multiplied by 1.
8/// - `Scale2` - The index register is multiplied by 2.
9/// - `Scale4` - The index register is multiplied by 4.
10/// - `Scale8` - The index register is multiplied by 8.
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
12#[repr(u8)]
13#[must_use]
14pub enum Scale {
15    Scale1 = 1, // We start from 1 to allow Option<Scale> optimization
16    Scale2 = 2,
17    Scale4 = 3,
18    Scale8 = 4,
19}
20
21impl Scale {
22    /// Compares two [`Scale`] values for equality.
23    #[inline(always)]
24    #[must_use]
25    pub const fn equals(self, other: Self) -> bool {
26        self.as_u8() == other.as_u8()
27    }
28
29    #[inline(always)]
30    pub(crate) const fn as_u8(self) -> u8 {
31        unsafe {
32            let result = transmute::<Self, u8>(self);
33            core::hint::assert_unchecked(result > 0);
34            core::hint::assert_unchecked(result <= 4);
35            result
36        }
37    }
38
39    #[inline]
40    #[allow(dead_code)]
41    pub(crate) const fn from_u8(value: u8) -> Self {
42        debug_assert!(value > 0 && value <= 4, "Invalid scale value");
43        unsafe { transmute(value) }
44    }
45
46    #[must_use]
47    pub(crate) const fn index(self) -> u8 {
48        match self {
49            Self::Scale1 => 0,
50            Self::Scale2 => 1,
51            Self::Scale4 => 2,
52            Self::Scale8 => 3,
53        }
54    }
55}