osom_asm_x86_64/models/
gpr.rs

1use osom_encoders_x86_64::models as enc_models;
2
3use super::{GPRKind, Size};
4
5/// Represents an error that occurs when creating a new general purpose register.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[repr(u8)]
8pub enum NewGPRError {
9    /// Error when creating a new `GPR` from a [`GPRKind::Bit8High`] and `index` outside of the `4..=7` range.
10    InvalidBit8HighIndex,
11
12    /// Error when creating a new `GPR` from a `kind` and `index` outside of the `0..=15` range.
13    IndexOutOfRange,
14}
15
16/// Represents an `x86_64` general purpose register.
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18#[repr(transparent)]
19#[must_use]
20pub struct GPR {
21    value: enc_models::GPR,
22}
23
24impl GPR {
25    pub const RAX: Self = unsafe { Self::new_unchecked(enc_models::GPR::RAX) };
26    pub const RCX: Self = unsafe { Self::new_unchecked(enc_models::GPR::RCX) };
27    pub const RDX: Self = unsafe { Self::new_unchecked(enc_models::GPR::RDX) };
28    pub const RBX: Self = unsafe { Self::new_unchecked(enc_models::GPR::RBX) };
29    pub const RSP: Self = unsafe { Self::new_unchecked(enc_models::GPR::RSP) };
30    pub const RBP: Self = unsafe { Self::new_unchecked(enc_models::GPR::RBP) };
31    pub const RSI: Self = unsafe { Self::new_unchecked(enc_models::GPR::RSI) };
32    pub const RDI: Self = unsafe { Self::new_unchecked(enc_models::GPR::RDI) };
33    pub const R8: Self = unsafe { Self::new_unchecked(enc_models::GPR::R8) };
34    pub const R9: Self = unsafe { Self::new_unchecked(enc_models::GPR::R9) };
35    pub const R10: Self = unsafe { Self::new_unchecked(enc_models::GPR::R10) };
36    pub const R11: Self = unsafe { Self::new_unchecked(enc_models::GPR::R11) };
37    pub const R12: Self = unsafe { Self::new_unchecked(enc_models::GPR::R12) };
38    pub const R13: Self = unsafe { Self::new_unchecked(enc_models::GPR::R13) };
39    pub const R14: Self = unsafe { Self::new_unchecked(enc_models::GPR::R14) };
40    pub const R15: Self = unsafe { Self::new_unchecked(enc_models::GPR::R15) };
41
42    pub const EAX: Self = unsafe { Self::new_unchecked(enc_models::GPR::EAX) };
43    pub const ECX: Self = unsafe { Self::new_unchecked(enc_models::GPR::ECX) };
44    pub const EDX: Self = unsafe { Self::new_unchecked(enc_models::GPR::EDX) };
45    pub const EBX: Self = unsafe { Self::new_unchecked(enc_models::GPR::EBX) };
46    pub const ESP: Self = unsafe { Self::new_unchecked(enc_models::GPR::ESP) };
47    pub const EBP: Self = unsafe { Self::new_unchecked(enc_models::GPR::EBP) };
48    pub const ESI: Self = unsafe { Self::new_unchecked(enc_models::GPR::ESI) };
49    pub const EDI: Self = unsafe { Self::new_unchecked(enc_models::GPR::EDI) };
50    pub const R8D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R8D) };
51    pub const R9D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R9D) };
52    pub const R10D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R10D) };
53    pub const R11D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R11D) };
54    pub const R12D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R12D) };
55    pub const R13D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R13D) };
56    pub const R14D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R14D) };
57    pub const R15D: Self = unsafe { Self::new_unchecked(enc_models::GPR::R15D) };
58
59    pub const AX: Self = unsafe { Self::new_unchecked(enc_models::GPR::AX) };
60    pub const CX: Self = unsafe { Self::new_unchecked(enc_models::GPR::CX) };
61    pub const DX: Self = unsafe { Self::new_unchecked(enc_models::GPR::DX) };
62    pub const BX: Self = unsafe { Self::new_unchecked(enc_models::GPR::BX) };
63    pub const SP: Self = unsafe { Self::new_unchecked(enc_models::GPR::SP) };
64    pub const BP: Self = unsafe { Self::new_unchecked(enc_models::GPR::BP) };
65    pub const SI: Self = unsafe { Self::new_unchecked(enc_models::GPR::SI) };
66    pub const DI: Self = unsafe { Self::new_unchecked(enc_models::GPR::DI) };
67    pub const R8W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R8W) };
68    pub const R9W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R9W) };
69    pub const R10W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R10W) };
70    pub const R11W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R11W) };
71    pub const R12W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R12W) };
72    pub const R13W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R13W) };
73    pub const R14W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R14W) };
74    pub const R15W: Self = unsafe { Self::new_unchecked(enc_models::GPR::R15W) };
75
76    pub const AL: Self = unsafe { Self::new_unchecked(enc_models::GPR::AL) };
77    pub const CL: Self = unsafe { Self::new_unchecked(enc_models::GPR::CL) };
78    pub const DL: Self = unsafe { Self::new_unchecked(enc_models::GPR::DL) };
79    pub const BL: Self = unsafe { Self::new_unchecked(enc_models::GPR::BL) };
80    pub const SPL: Self = unsafe { Self::new_unchecked(enc_models::GPR::SPL) };
81    pub const BPL: Self = unsafe { Self::new_unchecked(enc_models::GPR::BPL) };
82    pub const SIL: Self = unsafe { Self::new_unchecked(enc_models::GPR::SIL) };
83    pub const DIL: Self = unsafe { Self::new_unchecked(enc_models::GPR::DIL) };
84    pub const R8B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R8B) };
85    pub const R9B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R9B) };
86    pub const R10B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R10B) };
87    pub const R11B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R11B) };
88    pub const R12B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R12B) };
89    pub const R13B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R13B) };
90    pub const R14B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R14B) };
91    pub const R15B: Self = unsafe { Self::new_unchecked(enc_models::GPR::R15B) };
92
93    pub const AH: Self = unsafe { Self::new_unchecked(enc_models::GPR::AH) };
94    pub const CH: Self = unsafe { Self::new_unchecked(enc_models::GPR::CH) };
95    pub const DH: Self = unsafe { Self::new_unchecked(enc_models::GPR::DH) };
96    pub const BH: Self = unsafe { Self::new_unchecked(enc_models::GPR::BH) };
97
98    pub(crate) const unsafe fn new_unchecked(gpr: enc_models::GPR) -> Self {
99        Self { value: gpr }
100    }
101
102    #[inline]
103    pub fn new(kind: GPRKind, index: u8) -> Result<Self, NewGPRError> {
104        if kind.equals(GPRKind::Bit8High) && !(4..=7).contains(&index) {
105            return Err(NewGPRError::InvalidBit8HighIndex);
106        }
107
108        if index > 15 {
109            return Err(NewGPRError::IndexOutOfRange);
110        }
111
112        unsafe {
113            let enc_gpr = enc_models::GPR::new_unchecked(kind.into(), index);
114            Ok(Self::new_unchecked(enc_gpr))
115        }
116    }
117
118    #[inline(always)]
119    pub fn kind(self) -> GPRKind {
120        GPRKind::from(self.value.kind())
121    }
122
123    #[inline(always)]
124    pub fn size(self) -> Size {
125        Size::from(self.value.size())
126    }
127
128    #[inline(always)]
129    pub(crate) fn as_enc_gpr(self) -> enc_models::GPR {
130        self.value
131    }
132
133    #[inline(always)]
134    pub(crate) fn as_enc_mem(self) -> enc_models::GPROrMemory {
135        enc_models::GPROrMemory::GPR { gpr: self.value }
136    }
137}
138
139impl From<enc_models::GPR> for GPR {
140    #[inline(always)]
141    fn from(gpr: enc_models::GPR) -> Self {
142        unsafe { Self::new_unchecked(gpr) }
143    }
144}
145
146impl From<GPR> for enc_models::GPR {
147    #[inline(always)]
148    fn from(gpr: GPR) -> Self {
149        gpr.value
150    }
151}