mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-04 00:21:57 +00:00
Removed InstFmt, InstTargetFmt and InstTarget.
This commit is contained in:
parent
8d027e580f
commit
f54325bafe
@ -17,7 +17,7 @@ pub use error::GetKnownError;
|
||||
// Imports
|
||||
use super::Func;
|
||||
use crate::{
|
||||
inst::{basic, Directive, Inst, InstTarget, Register},
|
||||
inst::{basic, Directive, Inst, Register},
|
||||
DataTable, Pos,
|
||||
};
|
||||
use dcb_util::DiscardingSortedMergeIter;
|
||||
|
||||
@ -10,17 +10,15 @@ pub mod parse;
|
||||
pub mod pseudo;
|
||||
pub mod reg;
|
||||
pub mod size;
|
||||
pub mod target;
|
||||
|
||||
// Exports
|
||||
pub use directive::Directive;
|
||||
pub use error::DecodeError;
|
||||
pub use fmt::{DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstTargetFmt};
|
||||
pub use fmt::{DisplayCtx, InstDisplay, InstFmtArg};
|
||||
pub use iter::ParseIter;
|
||||
pub use parse::{Parsable, ParseCtx, ParseError};
|
||||
pub use reg::Register;
|
||||
pub use size::InstSize;
|
||||
pub use target::InstTarget;
|
||||
|
||||
// Imports
|
||||
use self::{basic::Decode as _, pseudo::Decodable as _};
|
||||
@ -133,16 +131,6 @@ impl<'a> InstSize for Inst<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> InstFmt for Inst<'a> {
|
||||
fn fmt(&self, pos: Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Basic(inst) => inst.fmt(pos, f),
|
||||
Self::Pseudo(inst) => inst.fmt(pos, f),
|
||||
Self::Directive(directive) => <Directive as InstFmt>::fmt(directive, pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Label
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub enum Label {
|
||||
|
||||
@ -21,7 +21,6 @@ use super::{
|
||||
parse::{LineArg, Parsable},
|
||||
DisplayCtx, InstDisplay, InstFmtArg, InstSize, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use crate::inst::InstFmt;
|
||||
use std::fmt;
|
||||
|
||||
/// All basic instructions
|
||||
@ -202,24 +201,6 @@ impl<T: Decode> InstSize for T {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
#[rustfmt::skip]
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Alu (inst) => inst.fmt(pos, f),
|
||||
Self::Cond (inst) => inst.fmt(pos, f),
|
||||
Self::Jmp (inst) => inst.fmt(pos, f),
|
||||
Self::Load (inst) => inst.fmt(pos, f),
|
||||
Self::Lui (inst) => inst.fmt(pos, f),
|
||||
Self::Mult (inst) => inst.fmt(pos, f),
|
||||
Self::Shift(inst) => inst.fmt(pos, f),
|
||||
Self::Store(inst) => inst.fmt(pos, f),
|
||||
Self::Sys (inst) => inst.fmt(pos, f),
|
||||
Self::Co (inst) => inst.fmt(pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A decodable basic instruction
|
||||
pub trait Decode: Sized {
|
||||
/// Decodes this instruction
|
||||
|
||||
@ -9,7 +9,7 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError,
|
||||
};
|
||||
|
||||
/// Alu register instructions
|
||||
@ -70,16 +70,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Imm(inst) => inst.fmt(pos, f),
|
||||
Self::Reg(inst) => inst.fmt(pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: crate::inst::Register) -> bool {
|
||||
match self {
|
||||
|
||||
@ -4,11 +4,10 @@
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode, ModifiesReg},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto, fmt};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
/// Instruction kind
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
@ -58,17 +57,6 @@ impl Kind {
|
||||
Kind::SetLessThanUnsigned(value) | Kind::And(value) | Kind::Or(value) | Kind::Xor(value) => i64::from(value),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a displayable with the value of this kind
|
||||
#[must_use]
|
||||
fn value_fmt(self) -> impl fmt::Display {
|
||||
dcb_util::DisplayWrapper::new(move |f| match self {
|
||||
// Signed
|
||||
Self::Add(rhs) | Self::AddUnsigned(rhs) | Self::SetLessThan(rhs) => write!(f, "{:#}", SignedHex(rhs)),
|
||||
// Unsigned
|
||||
Self::SetLessThanUnsigned(rhs) | Self::And(rhs) | Self::Or(rhs) | Self::Xor(rhs) => write!(f, "{rhs:#x}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Alu immediate instructions
|
||||
@ -184,21 +172,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, lhs, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
let value = kind.value_fmt();
|
||||
|
||||
// If we're not `slti[u]` and if `$dst` and `$lhs` are the same,
|
||||
// only print one of them
|
||||
match !matches!(kind, Kind::SetLessThan(_) | Kind::SetLessThanUnsigned(_)) && dst == lhs {
|
||||
true => write!(f, "{mnemonic} {dst}, {value}"),
|
||||
false => write!(f, "{mnemonic} {dst}, {lhs}, {value}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.dst == reg
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode, ModifiesReg},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use std::array;
|
||||
|
||||
@ -106,6 +106,7 @@ impl Decode for Inst {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Inst {
|
||||
#[bitmatch::bitmatch]
|
||||
fn encode(&self) -> u32 {
|
||||
@ -183,20 +184,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, lhs, rhs, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
// If `$dst` and `$lhs` are the same, only print one of them
|
||||
match dst == lhs {
|
||||
true => write!(f, "{mnemonic} {dst}, {rhs}"),
|
||||
false => write!(f, "{mnemonic} {dst}, {lhs}, {rhs}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.dst == reg
|
||||
|
||||
@ -5,9 +5,8 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto, fmt};
|
||||
|
||||
@ -122,6 +121,7 @@ impl Decode for Inst {
|
||||
Some(Self { n, kind })
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Inst {
|
||||
#[bitmatch::bitmatch]
|
||||
fn encode(&self) -> u32 {
|
||||
@ -281,30 +281,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
#[rustfmt::skip]
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Self { n, kind } = self;
|
||||
match kind {
|
||||
Kind::CopN { imm } => write!(f, "cop{n} {imm:#x}"),
|
||||
Kind::MoveFrom { dst, src, kind } => match kind {
|
||||
RegisterKind::Control => write!(f, "cfc{n} {dst}, {src:#x}"),
|
||||
RegisterKind::Data => write!(f, "mfc{n} {dst}, {src:#x}"),
|
||||
}
|
||||
Kind::MoveTo { dst, src, kind } => match kind {
|
||||
RegisterKind::Data => write!(f, "mtc{n} {src}, {dst:#x}"),
|
||||
RegisterKind::Control => write!(f, "ctc{n} {src}, {dst:#x}"),
|
||||
}
|
||||
Kind::Branch { offset, on } => match on {
|
||||
true => write!(f, "bc{n}f {:#}", SignedHex(offset)),
|
||||
false => write!(f, "bc{n}t {:#}", SignedHex(offset)),
|
||||
}
|
||||
Kind::Load { dst, src, offset } => write!(f, "lwc{n} {dst:#x}, {:#}({src})", SignedHex(offset)),
|
||||
Kind::Store { dst, src, offset } => write!(f, "swc{n} {dst:#x}, {:#}({src})", SignedHex(offset)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
match self.kind {
|
||||
|
||||
@ -28,6 +28,7 @@ impl Decodable for Inst {
|
||||
Some(Self { value: raw.i })
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
fn encode(&self) -> u32 {
|
||||
Raw { i: self.value }
|
||||
|
||||
@ -6,12 +6,12 @@ use crate::{
|
||||
inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, InstTarget, InstTargetFmt, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
},
|
||||
Pos,
|
||||
};
|
||||
use int_conv::{SignExtended, Signed, Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto, fmt};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
/// Instruction kind
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
@ -55,6 +55,12 @@ pub struct Inst {
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
/// Returns this instruction's target
|
||||
#[must_use]
|
||||
pub fn target(self, pos: Pos) -> Pos {
|
||||
Self::target_of(self.offset, pos)
|
||||
}
|
||||
|
||||
/// Returns the target using an offset
|
||||
#[must_use]
|
||||
pub fn target_of(offset: i16, pos: Pos) -> Pos {
|
||||
@ -239,37 +245,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstTarget for Inst {
|
||||
fn target(&self, pos: Pos) -> Pos {
|
||||
Self::target_of(self.offset, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl InstTargetFmt for Inst {
|
||||
fn fmt(&self, _pos: Pos, target: impl fmt::Display, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Self { kind, arg, .. } = self;
|
||||
|
||||
// `beq $zr, $zr, offset` => `b offset`
|
||||
// `beq $arg, $zr, offset` => `beqz $arg, offset`
|
||||
// `bne $arg, $zr, offset` => `bnez $arg, offset`
|
||||
match kind {
|
||||
Kind::Equal(Register::Zr) => match arg {
|
||||
Register::Zr => write!(f, "b {target}"),
|
||||
arg => write!(f, "beqz {arg}, {target}"),
|
||||
},
|
||||
Kind::Equal(reg) => write!(f, "beq {arg}, {reg}, {target}"),
|
||||
Kind::NotEqual(Register::Zr) => write!(f, "bnez {arg}, {target}"),
|
||||
Kind::NotEqual(reg) => write!(f, "bne {arg}, {reg}, {target}"),
|
||||
Kind::LessOrEqualZero => write!(f, "blez {arg}, {target}"),
|
||||
Kind::GreaterThanZero => write!(f, "bgtz {arg}, {target}"),
|
||||
Kind::LessThanZero => write!(f, "bltz {arg}, {target}"),
|
||||
Kind::GreaterOrEqualZero => write!(f, "bgez {arg}, {target}"),
|
||||
Kind::LessThanZeroLink => write!(f, "bltzal {arg}, {target}"),
|
||||
Kind::GreaterOrEqualZeroLink => write!(f, "bgezal {arg}, {target}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, _reg: Register) -> bool {
|
||||
false
|
||||
|
||||
@ -9,7 +9,7 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
|
||||
/// Jmp register instructions
|
||||
@ -70,16 +70,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Imm(inst) => inst.fmt(pos, f),
|
||||
Self::Reg(inst) => inst.fmt(pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
match self {
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
inst::{
|
||||
basic::{Decode, Encode, ModifiesReg},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, InstTarget, InstTargetFmt, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
},
|
||||
Pos,
|
||||
};
|
||||
@ -43,6 +43,12 @@ pub struct Inst {
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
/// Returns this instruction's target
|
||||
#[must_use]
|
||||
pub fn target(self, pos: Pos) -> Pos {
|
||||
Self::target_of(self.imm, pos)
|
||||
}
|
||||
|
||||
/// Returns the target using an immediate
|
||||
#[must_use]
|
||||
pub fn target_of(imm: u32, pos: Pos) -> Pos {
|
||||
@ -123,21 +129,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstTarget for Inst {
|
||||
fn target(&self, pos: Pos) -> Pos {
|
||||
Self::target_of(self.imm, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl InstTargetFmt for Inst {
|
||||
fn fmt(&self, _pos: Pos, target: impl std::fmt::Display, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let mnemonic = self.kind.mnemonic();
|
||||
|
||||
write!(f, "{mnemonic} {target}")
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, _reg: Register) -> bool {
|
||||
false
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode, ModifiesReg},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use std::array;
|
||||
|
||||
@ -114,23 +114,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { target, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
match kind {
|
||||
Kind::Jump => write!(f, "{mnemonic} {target}"),
|
||||
Kind::JumpLink(reg) => match reg {
|
||||
// If using `$ra`, don't output it.
|
||||
Register::Ra => write!(f, "{mnemonic} {target}"),
|
||||
reg => write!(f, "{mnemonic} {target}, {reg}"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, _reg: Register) -> bool {
|
||||
false
|
||||
|
||||
@ -5,9 +5,8 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
@ -155,18 +154,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { addr, value, offset, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
match offset {
|
||||
0 => write!(f, "{mnemonic} {value}, {addr}"),
|
||||
_ => write!(f, "{mnemonic} {value}, {:#}({addr})", SignedHex(offset)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.value == reg
|
||||
|
||||
@ -5,7 +5,7 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use int_conv::{Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto};
|
||||
@ -77,14 +77,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, value } = self;
|
||||
|
||||
write!(f, "lui {dst}, {value:#x}")
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.dst == reg
|
||||
|
||||
@ -5,7 +5,7 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use std::array;
|
||||
|
||||
@ -224,16 +224,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let mnemonic = Self::mnemonic(*self);
|
||||
match self {
|
||||
Self::Mult { lhs, rhs, .. } => write!(f, "{mnemonic} {lhs}, {rhs}"),
|
||||
Self::MoveFrom { dst: arg, .. } | Self::MoveTo { src: arg, .. } => write!(f, "{mnemonic} {arg}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
match self {
|
||||
|
||||
@ -8,7 +8,7 @@ pub mod reg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode, ModifiesReg, TryEncode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
|
||||
/// Alu register instructions
|
||||
@ -79,15 +79,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Imm(inst) => inst.fmt(pos, f),
|
||||
Self::Reg(inst) => inst.fmt(pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
match self {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
use crate::inst::{
|
||||
basic::{Decode, ModifiesReg, TryEncode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use int_conv::{Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto};
|
||||
@ -149,19 +149,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, lhs, rhs, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
// If `$dst` and `$lhs` are the same, only print one of them
|
||||
match dst == lhs {
|
||||
true => write!(f, "{mnemonic} {dst}, {rhs:#x}"),
|
||||
false => write!(f, "{mnemonic} {dst}, {lhs}, {rhs:#x}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.dst == reg
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode, ModifiesReg},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use std::array;
|
||||
|
||||
@ -130,19 +130,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, lhs, rhs, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
// If `$dst` and `$lhs` are the same, only print one of them
|
||||
match dst == lhs {
|
||||
true => write!(f, "{mnemonic} {dst}, {rhs}"),
|
||||
false => write!(f, "{mnemonic} {dst}, {lhs}, {rhs}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, reg: Register) -> bool {
|
||||
self.dst == reg
|
||||
|
||||
@ -5,9 +5,8 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, Encode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
@ -86,6 +85,7 @@ impl Decode for Inst {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Inst {
|
||||
#[bitmatch::bitmatch]
|
||||
fn encode(&self) -> u32 {
|
||||
@ -142,18 +142,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { addr, value, offset, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
match offset {
|
||||
0 => write!(f, "{mnemonic} {value}, {addr}"),
|
||||
_ => write!(f, "{mnemonic} {value}, {:#}({addr})", SignedHex(offset)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, _reg: Register) -> bool {
|
||||
false
|
||||
|
||||
@ -5,7 +5,7 @@ use super::ModifiesReg;
|
||||
use crate::inst::{
|
||||
basic::{Decode, TryEncode},
|
||||
parse::LineArg,
|
||||
DisplayCtx, InstDisplay, InstFmt, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
DisplayCtx, InstDisplay, InstFmtArg, Parsable, ParseCtx, ParseError, Register,
|
||||
};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
@ -116,15 +116,6 @@ impl<'a> InstDisplay<'a> for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { comment, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
write!(f, "{mnemonic} {comment:#x}")
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiesReg for Inst {
|
||||
fn modifies_reg(&self, _reg: Register) -> bool {
|
||||
false
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Directives
|
||||
|
||||
// Imports
|
||||
use super::{DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, InstTargetFmt};
|
||||
use super::{DisplayCtx, InstDisplay, InstFmtArg, InstSize};
|
||||
use crate::{DataType, Pos};
|
||||
use ascii::{AsciiChar, AsciiStr};
|
||||
use dcb_util::NextFromBytes;
|
||||
@ -192,30 +192,6 @@ impl<'a> InstSize for Directive<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> InstFmt for Directive<'a> {
|
||||
fn fmt(&self, _pos: Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Dw(value) => write!(f, "dw {value:#x}"),
|
||||
Self::Dh(value) => write!(f, "dh {value:#x}"),
|
||||
Self::Db(value) => write!(f, "db {value:#x}"),
|
||||
Self::Ascii(string) => write!(f, ".ascii \"{}\"", string.as_str().escape_debug()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> InstTargetFmt for Directive<'a> {
|
||||
fn fmt(&self, _pos: Pos, target: impl std::fmt::Display, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Dw(_) => write!(f, "dw {target}"),
|
||||
Self::Dh(_) => write!(f, "dh {target}"),
|
||||
Self::Db(_) => write!(f, "db {target}"),
|
||||
Self::Ascii(_) => write!(f, ".ascii {target}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Reads an ascii string from a byte slice until null, aligned to a word
|
||||
fn read_ascii_until_null(bytes: &[u8]) -> Option<&AsciiStr> {
|
||||
// For each word in the input
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
//! See the [`InstFmt`] type for more details.
|
||||
|
||||
// Imports
|
||||
use super::InstTarget;
|
||||
use crate::{inst::Register, Pos};
|
||||
use dcb_util::SignedHex;
|
||||
use std::fmt;
|
||||
@ -94,27 +93,3 @@ impl<'a> InstFmtArg<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A formattable instruction
|
||||
///
|
||||
/// This trait defines formatting for all instruction, which may require the
|
||||
/// instruction's current position (for relative instructions, such as the
|
||||
/// branching instructions).
|
||||
pub trait InstFmt {
|
||||
/// Formats this instruction
|
||||
fn fmt(&self, pos: Pos, f: &mut fmt::Formatter) -> fmt::Result;
|
||||
}
|
||||
|
||||
/// A formattable instruction that supports overloading it's target.
|
||||
pub trait InstTargetFmt {
|
||||
/// Formats this instruction
|
||||
fn fmt(&self, pos: Pos, target: impl fmt::Display, f: &mut fmt::Formatter) -> fmt::Result;
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ pub mod nop;
|
||||
pub mod store;
|
||||
|
||||
// Imports
|
||||
use super::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize};
|
||||
use super::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize};
|
||||
use core::fmt;
|
||||
|
||||
/// A pseudo instruction
|
||||
@ -101,19 +101,6 @@ impl InstSize for Inst {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::LoadImm(inst) => inst.fmt(pos, f),
|
||||
Self::Nop(inst) => inst.fmt(pos, f),
|
||||
Self::MoveReg(inst) => inst.fmt(pos, f),
|
||||
Self::Load(inst) => inst.fmt(pos, f),
|
||||
Self::Store(inst) => inst.fmt(pos, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A decodable pseudo instruction
|
||||
pub trait Decodable: InstSize + Sized {
|
||||
/// Decodes this instruction
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// Imports
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, InstTarget, InstTargetFmt, Register},
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, Register},
|
||||
Pos,
|
||||
};
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
@ -92,18 +92,3 @@ impl InstSize for Inst {
|
||||
8
|
||||
}
|
||||
}
|
||||
|
||||
impl InstTarget for Inst {
|
||||
fn target(&self, _pos: Pos) -> Pos {
|
||||
self.target
|
||||
}
|
||||
}
|
||||
|
||||
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 { value, kind, .. } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
write!(f, "{mnemonic} {value}, {target}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@
|
||||
// Imports
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, InstTargetFmt, Register},
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, Register},
|
||||
Pos,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
@ -44,18 +43,6 @@ impl Kind {
|
||||
Self::Word(_) | Self::HalfWordUnsigned(_) | Self::HalfWordSigned(_) => "li",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a displayable with the value of this load kind formatted.
|
||||
#[rustfmt::skip]
|
||||
#[must_use]
|
||||
pub fn value_fmt(self) -> impl std::fmt::Display {
|
||||
dcb_util::DisplayWrapper::new(move |f| match self {
|
||||
Self::Address(address) => write!(f, "{address}"),
|
||||
Self::Word(value) => write!(f, "{value:#x}"),
|
||||
Self::HalfWordUnsigned(value) => write!(f, "{value:#x}"),
|
||||
Self::HalfWordSigned(value) => write!(f, "{:#}", SignedHex(value)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Load immediate instruction
|
||||
@ -182,18 +169,3 @@ impl InstSize for Inst {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// Imports
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, Register};
|
||||
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, Register};
|
||||
use std::{array, convert::TryInto};
|
||||
|
||||
/// Move register instruction
|
||||
@ -68,11 +68,3 @@ impl InstSize for Inst {
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, src } = self;
|
||||
|
||||
write!(f, "move {dst}, {src}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// Imports
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, Register};
|
||||
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, Register};
|
||||
use std::{array, convert::TryFrom};
|
||||
|
||||
/// No-op
|
||||
@ -65,12 +65,3 @@ impl InstSize for Inst {
|
||||
4 * self.len
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self.len {
|
||||
1 => write!(f, "nop"),
|
||||
len => write!(f, "nop {}", len),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// Imports
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, InstTarget, InstTargetFmt, Register},
|
||||
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, Register},
|
||||
Pos,
|
||||
};
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
@ -91,18 +91,3 @@ impl InstSize for Inst {
|
||||
8
|
||||
}
|
||||
}
|
||||
|
||||
impl InstTarget for Inst {
|
||||
fn target(&self, _pos: Pos) -> Pos {
|
||||
self.target
|
||||
}
|
||||
}
|
||||
|
||||
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 { value, kind, .. } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
write!(f, "{mnemonic} {value}, {target}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
//! Instructions with a target
|
||||
|
||||
// Imports
|
||||
use crate::Pos;
|
||||
|
||||
/// Instructions that have a target
|
||||
pub trait InstTarget {
|
||||
/// Returns this instruction's target
|
||||
fn target(&self, pos: Pos) -> Pos;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user