From 12f2abc6389ba2ce9c1a9012ef0a6d331a694376 Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Tue, 12 Jan 2021 02:35:39 +0000 Subject: [PATCH] Relaxed requirements of implementing `InstTargetFmt` to allow semi-targetable instructions. `pseudo::load_imm` now implements `InstTargetFmt`. --- dcb-exe/src/exe/inst/fmt.rs | 4 ++-- dcb-exe/src/exe/inst/pseudo/load_imm.rs | 15 ++++++++++----- dcb-tools/src/decompiler/main.rs | 8 +++++++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/dcb-exe/src/exe/inst/fmt.rs b/dcb-exe/src/exe/inst/fmt.rs index 766c358..98371cf 100644 --- a/dcb-exe/src/exe/inst/fmt.rs +++ b/dcb-exe/src/exe/inst/fmt.rs @@ -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 InstFmt for T { +impl InstFmt for T { fn fmt(&self, pos: Pos, f: &mut fmt::Formatter) -> fmt::Result { let target = self.target(pos); self.fmt(pos, target, f) diff --git a/dcb-exe/src/exe/inst/pseudo/load_imm.rs b/dcb-exe/src/exe/inst/pseudo/load_imm.rs index 93a5e11..a2d44f8 100644 --- a/dcb-exe/src/exe/inst/pseudo/load_imm.rs +++ b/dcb-exe/src/exe/inst/pseudo/load_imm.rs @@ -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 { + ::fmt(self, pos, self.kind.value_fmt(), f) } } diff --git a/dcb-tools/src/decompiler/main.rs b/dcb-tools/src/decompiler/main.rs index e330145..9c82930 100644 --- a/dcb-tools/src/decompiler/main.rs +++ b/dcb-tools/src/decompiler/main.rs @@ -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)),