Implemented InstFmt for pseudo::Inst and Directive.

Renamed `PseudoInst` to `Inst`.
This commit is contained in:
2021-01-08 15:53:35 +00:00
parent 0483c63bfd
commit 058da819ee
7 changed files with 83 additions and 17 deletions

View File

@@ -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),
}
}
}

View File

@@ -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}")
}
}

View File

@@ -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.

View File

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

View File

@@ -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<Item = u32> + Clone>) -> Option<Self> {

View File

@@ -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}")
}
}

View File

@@ -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 {
<u32 as fmt::LowerHex>::fmt(&self.0, f)