Skip to main content

osom_encoders_x86_64/models/
memory.rs

1use super::{GPR, Offset, Scale};
2
3/// Represents a memory operand.
4///
5/// # Safety
6///
7/// Not all combinations of are valid for a given instruction.
8/// For specifics refer to the Intel x86 manual.
9///
10/// In particular all the GPRs have to be 64-bit wide.
11#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
12#[repr(u8)]
13#[must_use]
14pub enum Memory {
15    /// Represents a based memory operand, i.e. `[base + offset]`.
16    Based { base: GPR, offset: Offset } = 0,
17
18    /// Represents a scaled memory operand, i.e. `[index * scale + offset]`.
19    ///
20    /// # Safety
21    ///
22    /// `index == GPR::RSP` is not allowed.
23    Scaled { index: GPR, scale: Scale, offset: Offset } = 1,
24
25    /// Represents a based scaled memory operand, i.e. `[base + index * scale + offset]`.
26    ///
27    /// # Safety
28    ///
29    /// `index == GPR::RSP` is not allowed.
30    BasedAndScaled {
31        base: GPR,
32        index: GPR,
33        scale: Scale,
34        offset: Offset,
35    } = 2,
36
37    /// Represents a RIP-relative memory operand, i.e. `[RIP + offset]`.
38    RelativeToRIP { offset: Offset } = 3,
39}
40
41#[must_use]
42pub(crate) struct BaseIndexIsExtended {
43    pub base_is_extended: bool,
44    pub index_is_extended: bool,
45}
46
47impl Memory {
48    pub(crate) const fn base_index_is_extended(self) -> BaseIndexIsExtended {
49        match self {
50            Self::Based { base, .. } => BaseIndexIsExtended {
51                base_is_extended: base.is_extended(),
52                index_is_extended: false,
53            },
54            Self::Scaled { index, .. } => BaseIndexIsExtended {
55                base_is_extended: false,
56                index_is_extended: index.is_extended(),
57            },
58            Self::BasedAndScaled { base, index, .. } => BaseIndexIsExtended {
59                base_is_extended: base.is_extended(),
60                index_is_extended: index.is_extended(),
61            },
62            Self::RelativeToRIP { .. } => BaseIndexIsExtended {
63                base_is_extended: false,
64                index_is_extended: false,
65            },
66        }
67    }
68}