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