disasm_core/
macros.rs

1// !!!! CAUTION !!!!
2// !---------------!
3// !  DANGER ZONE  !
4// !---------------!
5// ! HIGH RISK  OF !
6// ! BRAIN DAMAGE  !
7// !---------------!
8// !   KEEP OUT    !
9// !!!!!!!!!!!!!!!!!
10
11#[macro_export]
12macro_rules! impl_arch_operands {
13    ($(#[$attr:meta])* $vis:vis enum $name:ident {
14        $($op:ident = $n:expr),+ $(,)?
15    }) => (
16        #[repr(u64)]
17        #[derive(Copy, Clone, Debug, PartialEq, Eq)]
18        $(#[$attr])*
19        $vis enum $name {
20            $($op = $n),+
21        }
22
23        impl From<$name> for u64 {
24            fn from(value: $name) -> u64 {
25                value as u64
26            }
27        }
28
29        impl $name {
30            pub fn from_u64(value: u64) -> Option<Self> {
31                Some(match value {
32                    $($n => Self::$op,)+
33                    _ => return None,
34                })
35            }
36        }
37    );
38}
39pub use impl_arch_operands;
40
41#[macro_export]
42macro_rules! impl_opcode_check {
43    ($($mask:expr, $opcode:expr, $name:ident;)*) => ($(
44        #[inline]
45        fn $name(&self) -> bool {
46            self.raw() & $mask == $opcode
47        }
48    )*);
49}
50pub use impl_opcode_check;
51
52#[macro_export]
53macro_rules! impl_field {
54    ($($name:ident =
55        $pos:expr,
56        $len:expr,
57        $ret:tt $(: $cast:ty)?
58        $(,$map:expr $(, $arg:ident: $arg_ty:ty)*)?
59    ;)*) => ($(
60        impl_field!(impl $name, $ret $(: $cast)?, $pos, $len $(,$map $(, $arg: $arg_ty)*)?);
61    )*);
62    (impl
63         $name:ident,
64         bool $(: $cast:ty)?,
65         $pos:expr,
66         $len:expr
67         $(,$map:expr $(, $arg:ident: $arg_ty:ty)*)?
68    ) => (
69        fn $name(&self $($(, $arg: $arg_ty)*)?) -> bool {
70            let ret = zextract(self.raw(), $pos, $len) $(as $cast)?;
71            $(let ret = $map(ret $(, $arg)?);)?
72            ret != 0
73        }
74    );
75    (impl
76        $name:ident,
77        $ret:ty,
78        $pos:expr,
79        $len:expr
80        $(,$map:expr $(, $arg:ident: $arg_ty:ty)*)?
81    ) => (
82        fn $name(&self $($(, $arg: $arg_ty)*)?) -> $ret {
83            let ret = zextract(self.raw(), $pos, $len);
84            $(let ret = $map(ret $(, $arg)?);)?
85            ret as $ret
86        }
87    );
88    (impl
89        $name:ident,
90        $ret:ty: $cast:ty,
91        $pos:expr,
92        $len:expr
93        $(,$map:expr $(, $arg:ident: $arg_ty:ty)*)?
94    ) => (
95        fn $name(&self $($(, $arg: $arg_ty)*)?) -> $ret {
96            let ret = zextract(self.raw(), $pos, $len) as $cast;
97            $(let ret = $map(ret $(, $arg)?);)?
98            ret
99        }
100    );
101}
102pub use impl_field;
103
104#[macro_export]
105macro_rules! define_opcodes {
106    ($($name:ident = $mnemonic:literal),* $(,)?) => (
107        #[allow(non_camel_case_types)]
108        #[repr(u32)]
109        enum Opcodes {
110            $($name),*
111        }
112
113        $(pub const $name: Opcode = Opcode(Opcodes::$name as u32);)*
114
115        #[cfg(feature = "mnemonic")]
116        pub(crate) fn defined_mnemonic(opcode: Opcode) -> Option<&'static str> {
117            Some(match opcode {
118                $($name => $mnemonic,)*
119                _ => return None,
120            })
121        }
122    );
123}
124pub use define_opcodes;