diff --git a/dcb-exe/src/exe/inst.rs b/dcb-exe/src/exe/inst.rs index 1c5823a..b14e256 100644 --- a/dcb-exe/src/exe/inst.rs +++ b/dcb-exe/src/exe/inst.rs @@ -25,7 +25,7 @@ pub enum Inst { Basic(basic::Inst), /// A pseudo instruction - Pseudo(pseudo::PseudoInst), + Pseudo(pseudo::Inst), /// A directive Directive(Directive), @@ -44,16 +44,16 @@ impl InstFmt for Inst { fn mnemonic(&self) -> &'static str { match self { Self::Basic(inst) => inst.mnemonic(), - Self::Pseudo(_) => todo!(), - Self::Directive(_) => todo!(), + Self::Pseudo(inst) => inst.mnemonic(), + Self::Directive(directive) => directive.mnemonic(), } } fn fmt(&self, pos: Pos, bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Basic(inst) => inst.fmt(pos, bytes, f), - Self::Pseudo(_) => todo!(), - Self::Directive(_) => todo!(), + Self::Pseudo(inst) => inst.fmt(pos, bytes, f), + Self::Directive(directive) => directive.fmt(pos, bytes, f), } } } diff --git a/dcb-exe/src/exe/inst/basic/alu/imm.rs b/dcb-exe/src/exe/inst/basic/alu/imm.rs index abaef09..fe1f948 100644 --- a/dcb-exe/src/exe/inst/basic/alu/imm.rs +++ b/dcb-exe/src/exe/inst/basic/alu/imm.rs @@ -149,7 +149,9 @@ impl InstFmt for Inst { fn fmt(&self, _pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result { let Self { dst, lhs, kind } = self; + let mnemonic = kind.mnemonic(); + let value = kind.value_fmt(); - write!(f, "{} {dst}, {lhs}, {}", kind.mnemonic(), kind.value_fmt()) + write!(f, "{mnemonic} {dst}, {lhs}, {value}") } } diff --git a/dcb-exe/src/exe/inst/directive.rs b/dcb-exe/src/exe/inst/directive.rs index 6070f59..5a148dd 100644 --- a/dcb-exe/src/exe/inst/directive.rs +++ b/dcb-exe/src/exe/inst/directive.rs @@ -2,9 +2,9 @@ // Imports //use super::{FromRawIter, Instruction, Raw}; -use super::Inst; +use super::{Inst, InstFmt}; use crate::exe::Pos; -use ascii::AsciiChar; +use ascii::{AsciiChar, AsciiStr}; use dcb_util::NextFromBytes; use std::ops::{ Bound::{self, Excluded, Included, Unbounded}, @@ -139,6 +139,34 @@ impl Directive { } } +impl InstFmt for Directive { + fn mnemonic(&self) -> &'static str { + match self { + Self::Dw(_) => "dw", + Self::Dh(_) => "dh", + Self::Db(_) => "db", + Self::Ascii { .. } => ".ascii", + } + } + + fn fmt(&self, pos: Pos, bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result { + let mnemonic = self.mnemonic(); + #[allow(clippy::as_conversions)] // `len` will always fit into a `usize`. + #[allow(clippy::indexing_slicing)] // `pos .. pos + len` will always be valid. + match self { + Self::Dw(value) => write!(f, "{mnemonic} {value:#x}"), + Self::Dh(value) => write!(f, "{mnemonic} {value:#x}"), + Self::Db(value) => write!(f, "{mnemonic} {value:#x}"), + &Self::Ascii { len } => { + let pos = pos.as_mem_idx(); + let string = &bytes[pos..pos + len as usize]; + let string = AsciiStr::from_ascii(string).expect("Ascii string was invalid").as_str(); + write!(f, "{mnemonic} \"{}\"", string.escape_debug()) + }, + } + } +} + /// Reads an ascii string from a byte slice until null. /// /// Will always read in multiples of a word (4 bytes), including the null. diff --git a/dcb-exe/src/exe/inst/iter.rs b/dcb-exe/src/exe/inst/iter.rs index 78e82fd..4d726b5 100644 --- a/dcb-exe/src/exe/inst/iter.rs +++ b/dcb-exe/src/exe/inst/iter.rs @@ -48,7 +48,7 @@ impl<'a> Iterator for ParseIter<'a> { self.bytes = &self.bytes[4..]; let pos = self.cur_pos; self.cur_pos += 4; - match pseudo::PseudoInst::decode(inst, self.bytes) { + match pseudo::Inst::decode(inst, self.bytes) { Some((inst, len)) => { self.bytes = &self.bytes[len..]; self.cur_pos += len as u32; diff --git a/dcb-exe/src/exe/inst/pseudo.rs b/dcb-exe/src/exe/inst/pseudo.rs index 7c64d41..3735213 100644 --- a/dcb-exe/src/exe/inst/pseudo.rs +++ b/dcb-exe/src/exe/inst/pseudo.rs @@ -13,12 +13,11 @@ pub mod alu_assign; //pub mod store; // Imports -use super::basic; +use super::{basic, InstFmt}; /// A pseudo instruction #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[derive(derive_more::Display)] -pub enum PseudoInst { +pub enum Inst { /// Alu self-assign AluAssign(alu_assign::Inst), /* @@ -61,7 +60,7 @@ pub enum PseudoInst { */ } -impl PseudoInst { +impl Inst { /// Attempts to parse a pseudo instruction from a start /// basic instruction and remaining bytes #[must_use] @@ -70,6 +69,20 @@ impl PseudoInst { } } +impl InstFmt for Inst { + fn mnemonic(&self) -> &'static str { + match self { + Self::AluAssign(inst) => inst.mnemonic(), + } + } + + fn fmt(&self, pos: crate::Pos, bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::AluAssign(inst) => inst.fmt(pos, bytes, f), + } + } +} + /* impl PseudoInst { pub fn decode(iter: InstIter<'_, impl Iterator + Clone>) -> Option { diff --git a/dcb-exe/src/exe/inst/pseudo/alu_assign.rs b/dcb-exe/src/exe/inst/pseudo/alu_assign.rs index 176316b..f8bfe5c 100644 --- a/dcb-exe/src/exe/inst/pseudo/alu_assign.rs +++ b/dcb-exe/src/exe/inst/pseudo/alu_assign.rs @@ -3,7 +3,7 @@ // Imports use crate::exe::inst::{ basic::{self, alu}, - Register, + InstFmt, Register, }; use std::fmt; @@ -62,8 +62,6 @@ impl Kind { /// [alu] $dst, $dst, $i /// ``` #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[derive(derive_more::Display)] -#[display(fmt = "{} {dst}, {}", "kind.mnemonic()", "kind.value_fmt()")] pub struct Inst { /// Destination and source register pub dst: Register, @@ -94,3 +92,18 @@ impl Inst { inst.map(|inst| (inst, 0)) } } + + +impl InstFmt for Inst { + fn mnemonic(&self) -> &'static str { + self.kind.mnemonic() + } + + fn fmt(&self, _pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result { + let Self { dst, kind } = self; + let mnemonic = kind.mnemonic(); + let value = kind.value_fmt(); + + write!(f, "{mnemonic} {dst}, {value}") + } +} diff --git a/dcb-exe/src/exe/pos.rs b/dcb-exe/src/exe/pos.rs index d766d4c..698a2d6 100644 --- a/dcb-exe/src/exe/pos.rs +++ b/dcb-exe/src/exe/pos.rs @@ -5,14 +5,24 @@ use int_conv::{SignExtended, Signed}; use std::{convert::TryFrom, fmt, ops}; +use crate::Exe; + /// An instruction position #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)] #[derive(ref_cast::RefCast)] #[derive(derive_more::Display)] -#[display(fmt = "{_0:#x?}")] +#[display(fmt = "{_0:#x}")] #[repr(transparent)] pub struct Pos(pub u32); +impl Pos { + /// Returns the memory position of this position + #[must_use] + pub fn as_mem_idx(self) -> usize { + usize::try_from(self - Exe::START_MEM_ADDRESS).expect("Failed to compute index") + } +} + impl fmt::LowerHex for Pos { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ::fmt(&self.0, f)