// © 2023 John Breaux //! An [`Encoding`] represents the set of arguments for a given [msp430 opcode](Opcode) use super::*; pub mod number; pub mod register; pub mod width; pub mod jump_target; pub mod primary_operand; pub mod secondary_operand; mod builder; pub mod encoding_parser; use builder::{DoubleBuilder, JumpBuilder, ReflexiveBuilder, SingleBuilder}; use encoding_parser::EncodingParser; /// Represents an [instruction encoding](https://mspgcc.sourceforge.net/manual/x223.html) /// /// # Examples /// ```rust /// use msp430_asm::{preamble::*, parser::preamble::*}; /// // Create a token sequence /// let asm_file = r".b 8000(r15)"; /// // Create a single-operand encoding parser /// let single: EncodingParser = Encoding::single().end(); /// // Parse an Encoding from it /// let encoding: Encoding = single /// .parse(&Default::default(), &mut Tokenizer::new(asm_file).ignore_spaces()) /// .unwrap(); /// // Print the Encoding /// println!("{encoding}"); /// ``` #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Encoding { Single { width: Width, dst: PrimaryOperand }, Jump { target: JumpTarget }, Double { width: Width, src: PrimaryOperand, dst: SecondaryOperand }, } impl Encoding { /// Returns a builder for [Encoding::Single] pub fn single() -> SingleBuilder { Default::default() } /// Returns a builder for [Encoding::Jump] pub fn jump() -> JumpBuilder { Default::default() } /// Returns a builder for [Encoding::Double] pub fn double() -> DoubleBuilder { Default::default() } /// Returns a builder for [Encoding::Double] /// /// The reflexive pseudo-[Encoding] is a [Double](Encoding::Double) where the src and /// dst are the same pub fn reflexive() -> ReflexiveBuilder { Default::default() } /// pub fn word(&self) -> u16 { match *self { Encoding::Single { width, dst } => u16::from(width) | dst.mode() | dst.register() as u16, Encoding::Jump { target } => target.word(), Encoding::Double { width, src, dst } => { u16::from(width) | src.mode() | dst.mode() | dst.register() as u16 | ((src.register() as u16) << 8) } } } /// Returns extwords for instruction pub fn extwords(&self) -> (Option, Option) { match self { Encoding::Double { src, dst, .. } => (src.ext_word(), dst.ext_word()), Encoding::Single { dst, .. } => (dst.ext_word(), None), Encoding::Jump { .. } => (None, None), } } } impl Display for Encoding { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Encoding::Single { width, dst } => write!(f, "{width} {dst}"), Encoding::Jump { target } => write!(f, " {target}"), Encoding::Double { width, src, dst } => write!(f, "{width} {src}, {dst}"), } } }