Relaxed requirements of implementing InstTargetFmt to allow semi-targetable instructions.

`pseudo::load_imm` now implements `InstTargetFmt`.
This commit is contained in:
2021-01-12 02:35:39 +00:00
parent dbfdc01a2e
commit 12f2abc638
3 changed files with 19 additions and 8 deletions

View File

@@ -19,12 +19,12 @@ pub trait InstFmt {
}
/// A formattable instruction that supports overloading it's target.
pub trait InstTargetFmt: InstTarget {
pub trait InstTargetFmt {
/// Formats this instruction
fn fmt(&self, pos: Pos, target: impl fmt::Display, f: &mut fmt::Formatter) -> fmt::Result;
}
impl<T: InstTargetFmt> InstFmt for T {
impl<T: InstTarget + InstTargetFmt> InstFmt for T {
fn fmt(&self, pos: Pos, f: &mut fmt::Formatter) -> fmt::Result {
let target = self.target(pos);
self.fmt(pos, target, f)

View File

@@ -3,7 +3,7 @@
// Imports
use super::Decodable;
use crate::{
exe::inst::{basic, InstFmt, InstSize, Register},
exe::inst::{basic, InstFmt, InstSize, InstTargetFmt, Register},
Pos,
};
use dcb_util::SignedHex;
@@ -114,12 +114,17 @@ impl InstSize for Inst {
}
}
impl InstFmt for Inst {
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
impl InstTargetFmt for Inst {
fn fmt(&self, _pos: crate::Pos, target: impl std::fmt::Display, 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}")
write!(f, "{mnemonic} {dst}, {target}")
}
}
impl InstFmt for Inst {
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
<Self as InstTargetFmt>::fmt(self, pos, self.kind.value_fmt(), f)
}
}

View File

@@ -172,7 +172,13 @@ pub fn inst_display<'a>(inst: &'a Inst, exe: &'a Exe, func: Option<&'a Func>, po
Inst::Basic(basic::Inst::Jmp(basic::jmp::Inst::Imm(inst))) => {
write!(f, "{}", self::inst_target_fmt(inst, pos, self::inst_target(exe, func, inst.target(pos))))
},
Inst::Pseudo(pseudo::Inst::LoadImm(inst)) => write!(f, "{}", self::inst_fmt(inst, pos)),
Inst::Pseudo(pseudo::Inst::LoadImm(
inst
@ pseudo::load_imm::Inst {
kind: pseudo::load_imm::Kind::Address(Pos(target)) | pseudo::load_imm::Kind::Word(target),
..
},
)) => write!(f, "{}", self::inst_target_fmt(inst, pos, self::inst_target(exe, func, Pos(*target)))),
Inst::Pseudo(pseudo::Inst::Load(inst)) => write!(f, "{}", self::inst_fmt(inst, pos)),
Inst::Pseudo(pseudo::Inst::Store(inst)) => write!(f, "{}", self::inst_fmt(inst, pos)),
inst => write!(f, "{}", self::inst_fmt(inst, pos)),