1use crate::instruction::Instruction;
2use crate::operand::{Operand, OperandWidth};
3
4use crate::two_operand::*;
5use std::fmt;
6
7pub trait Emulate {
11    fn emulate(&self) -> Option<Instruction>;
12}
13
14pub trait Emulated {
17    fn mnemonic(&self) -> &str;
19    fn destination(&self) -> &Option<Operand>;
21    fn size(&self) -> usize;
25    fn operand_width(&self) -> &Option<OperandWidth>;
27}
28
29macro_rules! emulated {
30    ($t:ident, $n:expr, $o:ident) => {
31        #[derive(Debug, Clone, Copy, PartialEq)]
32        pub struct $t {
33            destination: Option<Operand>,
34            operand_width: Option<OperandWidth>,
35            original: $o,
42        }
43
44        impl $t {
45            pub fn new(
46                destination: Option<Operand>,
47                operand_width: Option<OperandWidth>,
48                original: $o,
49            ) -> $t {
50                $t {
51                    destination,
52                    operand_width,
53                    original,
54                }
55            }
56        }
57
58        impl Emulated for $t {
59            fn mnemonic(&self) -> &str {
60                match self.operand_width {
61                    Some(OperandWidth::Word) | None => $n,
62                    Some(OperandWidth::Byte) => concat!($n, ".b"),
63                }
64            }
65
66            fn destination(&self) -> &Option<Operand> {
67                &self.destination
68            }
69
70            fn size(&self) -> usize {
71                self.original.size()
72            }
73
74            fn operand_width(&self) -> &Option<OperandWidth> {
75                &self.operand_width
76            }
77        }
78
79        impl fmt::Display for $t {
80            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81                if self.destination.is_none() && self.operand_width.is_none() {
82                    write!(f, "{}", $n)
83                } else {
84                    write!(f, "{} {}", self.mnemonic(), self.destination.unwrap())
85                }
86            }
87        }
88    };
89}
90
91emulated!(Adc, "adc", Addc);
92emulated!(Br, "br", Mov);
93emulated!(Clr, "clr", Mov);
94emulated!(Clrc, "clrc", Bic);
95emulated!(Clrn, "clrn", Bic);
96emulated!(Clrz, "clrz", Bic);
97emulated!(Dadc, "dadc", Dadd);
98emulated!(Dec, "dec", Sub);
99emulated!(Decd, "decd", Sub);
100emulated!(Dint, "dint", Bic);
101emulated!(Eint, "eint", Bis);
102emulated!(Inc, "inc", Add);
103emulated!(Incd, "incd", Add);
104emulated!(Inv, "inv", Xor);
105emulated!(Nop, "nop", Mov);
106emulated!(Pop, "pop", Mov);
107emulated!(Ret, "ret", Mov);
108emulated!(Rla, "rla", Add);
109emulated!(Rlc, "rlc", Addc);
110emulated!(Sbc, "sbc", Subc);
111emulated!(Setc, "setc", Bis);
112emulated!(Setn, "Setn", Bis);
113emulated!(Setz, "setz", Bis);
114emulated!(Tst, "tst", Cmp);