msp430_asm/
single_operand.rs

1use crate::operand::{Operand, OperandWidth};
2
3use std::fmt;
4
5/// All single operand instructions implement this trait to provide a common
6/// interface and polymorphism
7pub trait SingleOperand {
8    /// Return the mnemonic for the instruction. This is operand width aware
9    fn mnemonic(&self) -> &str;
10    /// Returns the source operand
11    fn source(&self) -> &Operand;
12    /// Returns the size of the instruction (in bytes)
13    fn size(&self) -> usize;
14    /// Returns the operand width if one is specified
15    fn operand_width(&self) -> &Option<OperandWidth>;
16}
17
18macro_rules! single_operand {
19    ($t:ident, $n:expr) => {
20        #[derive(Debug, Clone, Copy, PartialEq)]
21        pub struct $t {
22            source: Operand,
23            operand_width: Option<OperandWidth>,
24        }
25
26        impl $t {
27            pub fn new(source: Operand, operand_width: Option<OperandWidth>) -> $t {
28                $t {
29                    source,
30                    operand_width,
31                }
32            }
33        }
34
35        impl SingleOperand for $t {
36            fn mnemonic(&self) -> &str {
37                match self.operand_width {
38                    Some(OperandWidth::Word) | None => $n,
39                    Some(OperandWidth::Byte) => concat!($n, ".b"),
40                }
41            }
42
43            fn source(&self) -> &Operand {
44                &self.source
45            }
46
47            fn size(&self) -> usize {
48                2 + self.source.size()
49            }
50
51            fn operand_width(&self) -> &Option<OperandWidth> {
52                &self.operand_width
53            }
54        }
55
56        impl fmt::Display for $t {
57            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58                write!(f, "{} {}", self.mnemonic(), self.source)
59            }
60        }
61    };
62}
63
64single_operand!(Rrc, "rrc");
65single_operand!(Swpb, "swpb");
66single_operand!(Rra, "rra");
67single_operand!(Sxt, "sxt");
68single_operand!(Push, "push");
69single_operand!(Call, "call");
70
71#[derive(Debug, Clone, Copy, PartialEq, Default)]
72pub struct Reti {}
73
74impl Reti {
75    pub fn new() -> Reti {
76        Reti {}
77    }
78
79    pub fn size(&self) -> usize {
80        2
81    }
82}
83
84impl fmt::Display for Reti {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        write!(f, "reti")
87    }
88}