82 lines
2.9 KiB
Rust
82 lines
2.9 KiB
Rust
// © 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<u16>, Option<u16>) {
|
|
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}"),
|
|
}
|
|
}
|
|
}
|