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);