Skip to main content

asmkit/masm/
mod.rs

1//! MacroAssembler infrastructure
2//!
3//! This module provides "portable" assembler across all supported architectures.
4//!
5//! It is a best effort to provide a common API across all architectures, but some features may be architecture specific.
6
7use smallvec::SmallVec;
8
9use crate::core::operand::Label;
10
11#[cfg(feature = "x86")]
12use crate::x86::CondCode as X86CondCode;
13
14//pub mod x86;
15
16pub enum ExtensionSize {
17    I8ToI32,
18    I8ToI64,
19    I16ToI32,
20    I16ToI64,
21    I32ToI64,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
25pub enum RelationalCondition {
26    Equal,
27    NotEqual,
28    Above,
29    AboveOrEqual,
30    Below,
31    BelowOrEqual,
32    GreaterThan,
33    GreaterThanOrEqual,
34    LessThan,
35    LessThanOrEqual,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
39pub enum ResultCondition {
40    Carry,
41    Overflow,
42    Signed,
43    PositiveOrZero,
44    Zero,
45    NonZero,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
49pub enum DoubleCondition {
50    EqualAndOrdered,
51    NotEqualAndOrdered,
52    GreaterThanAndOrdered,
53    GreaterThanOrEqualAndOrdered,
54    LessThanAndOrdered,
55    LessThanOrEqualAndOrdered,
56    EqualOrUnordered,
57    NotEqualOrUnordered,
58    GreaterThanOrUnordered,
59    GreaterThanOrEqualOrUnordered,
60    LessThanOrUnordered,
61    LessThanOrEqualOrUnordered,
62}
63
64impl RelationalCondition {
65    pub const fn invert(self) -> Self {
66        match self {
67            Self::Equal => Self::NotEqual,
68            Self::NotEqual => Self::Equal,
69            Self::Above => Self::BelowOrEqual,
70            Self::AboveOrEqual => Self::Below,
71            Self::Below => Self::AboveOrEqual,
72            Self::BelowOrEqual => Self::Above,
73            Self::GreaterThan => Self::LessThanOrEqual,
74            Self::GreaterThanOrEqual => Self::LessThan,
75            Self::LessThan => Self::GreaterThanOrEqual,
76            Self::LessThanOrEqual => Self::GreaterThan,
77        }
78    }
79
80    #[cfg(feature = "x86")]
81    pub const fn x86_condition(self) -> X86CondCode {
82        match self {
83            Self::Equal => X86CondCode::E,
84            Self::NotEqual => X86CondCode::NE,
85            Self::Above => X86CondCode::A,
86            Self::AboveOrEqual => X86CondCode::AE,
87            Self::Below => X86CondCode::B,
88            Self::BelowOrEqual => X86CondCode::BE,
89            Self::GreaterThan => X86CondCode::G,
90            Self::GreaterThanOrEqual => X86CondCode::GE,
91            Self::LessThan => X86CondCode::L,
92            Self::LessThanOrEqual => X86CondCode::LE,
93        }
94    }
95}
96
97impl ResultCondition {
98    pub const fn invert(self) -> Self {
99        match self {
100            Self::Carry => Self::PositiveOrZero,
101            Self::Overflow => Self::NonZero,
102            Self::Signed => Self::PositiveOrZero,
103            Self::PositiveOrZero => Self::Carry,
104            Self::Zero => Self::NonZero,
105            Self::NonZero => Self::Zero,
106        }
107    }
108
109    #[cfg(feature = "x86")]
110    pub const fn x86_condition(self) -> X86CondCode {
111        match self {
112            Self::Carry => X86CondCode::C,
113            Self::Overflow => X86CondCode::O,
114            Self::Signed => X86CondCode::S,
115            Self::PositiveOrZero => X86CondCode::NS,
116            Self::Zero => X86CondCode::E,
117            Self::NonZero => X86CondCode::NE,
118        }
119    }
120}
121
122impl DoubleCondition {
123    pub const fn invert(self) -> Self {
124        match self {
125            Self::EqualAndOrdered => Self::NotEqualOrUnordered,
126            Self::NotEqualAndOrdered => Self::EqualOrUnordered,
127            Self::GreaterThanAndOrdered => Self::LessThanOrEqualOrUnordered,
128            Self::GreaterThanOrEqualAndOrdered => Self::LessThanOrUnordered,
129            Self::LessThanAndOrdered => Self::GreaterThanOrEqualOrUnordered,
130            Self::LessThanOrEqualAndOrdered => Self::GreaterThanOrUnordered,
131            Self::EqualOrUnordered => Self::NotEqualAndOrdered,
132            Self::NotEqualOrUnordered => Self::EqualAndOrdered,
133            Self::GreaterThanOrUnordered => Self::LessThanOrEqualAndOrdered,
134            Self::GreaterThanOrEqualOrUnordered => Self::LessThanAndOrdered,
135            Self::LessThanOrUnordered => Self::GreaterThanOrEqualAndOrdered,
136            Self::LessThanOrEqualOrUnordered => Self::GreaterThanAndOrdered,
137        }
138    }
139
140    /// Convert to x86 condition code, returning a tuple of (special, invert, condition_code)
141    #[cfg(feature = "x86")]
142    pub const fn x86_condition(self) -> (bool, bool, X86CondCode) {
143        match self {
144            Self::EqualAndOrdered => (true, false, X86CondCode::E),
145            Self::NotEqualAndOrdered => (false, false, X86CondCode::NE),
146            Self::GreaterThanAndOrdered => (false, false, X86CondCode::A),
147            Self::GreaterThanOrEqualAndOrdered => (false, false, X86CondCode::AE),
148            Self::LessThanAndOrdered => (false, true, X86CondCode::A),
149            Self::LessThanOrEqualAndOrdered => (false, true, X86CondCode::AE),
150            Self::EqualOrUnordered => (false, false, X86CondCode::E),
151            Self::NotEqualOrUnordered => (true, false, X86CondCode::NP),
152            Self::GreaterThanOrUnordered => (false, true, X86CondCode::B),
153            Self::GreaterThanOrEqualOrUnordered => (false, true, X86CondCode::BE),
154            Self::LessThanOrUnordered => (false, false, X86CondCode::B),
155            Self::LessThanOrEqualOrUnordered => (false, false, X86CondCode::BE),
156        }
157    }
158}
159
160pub const fn imm_fits<const BITS: usize>(imm: i64) -> bool {
161    if BITS >= 64 {
162        return true;
163    }
164    let min = -(1i64 << (BITS - 1));
165    let max = (1i64 << (BITS - 1)) - 1;
166    imm >= min && imm <= max
167}
168
169pub struct JumpList {
170    pub labels: SmallVec<[Label; 4]>,
171}
172
173impl Default for JumpList {
174    fn default() -> Self {
175        Self::new()
176    }
177}
178
179impl JumpList {
180    pub fn new() -> Self {
181        Self {
182            labels: SmallVec::new(),
183        }
184    }
185
186    pub fn push(&mut self, label: Label) {
187        self.labels.push(label);
188    }
189}