From 7c196ec4a991889e1c04fcdc2e1b7d1b310414ad Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Fri, 8 Jan 2021 14:33:49 +0000 Subject: [PATCH] Added `dcb_exe::exe::inst::basic::{Decodable, Encodable}`. --- dcb-exe/src/exe.rs | 1 - dcb-exe/src/exe/inst.rs | 2 + dcb-exe/src/exe/inst/basic.rs | 46 ++++++++++---- dcb-exe/src/exe/inst/basic/alu.rs | 19 +++--- dcb-exe/src/exe/inst/basic/alu/imm.rs | 19 +++--- dcb-exe/src/exe/inst/basic/alu/reg.rs | 20 ++++--- dcb-exe/src/exe/inst/basic/cond.rs | 19 +++--- dcb-exe/src/exe/inst/basic/iter.rs | 86 --------------------------- dcb-exe/src/exe/inst/basic/jmp.rs | 19 +++--- dcb-exe/src/exe/inst/basic/jmp/imm.rs | 17 +++--- dcb-exe/src/exe/inst/basic/jmp/reg.rs | 19 +++--- dcb-exe/src/exe/inst/basic/load.rs | 19 +++--- dcb-exe/src/exe/inst/basic/lui.rs | 20 ++++--- dcb-exe/src/exe/inst/basic/mult.rs | 33 +++++----- dcb-exe/src/exe/inst/basic/store.rs | 20 ++++--- dcb-exe/src/exe/inst/basic/sys.rs | 22 +++---- 16 files changed, 175 insertions(+), 206 deletions(-) delete mode 100644 dcb-exe/src/exe/inst/basic/iter.rs diff --git a/dcb-exe/src/exe.rs b/dcb-exe/src/exe.rs index a965ce4..8ab4da6 100644 --- a/dcb-exe/src/exe.rs +++ b/dcb-exe/src/exe.rs @@ -19,7 +19,6 @@ pub use pos::Pos; //pub use func::Func; // Imports -use self::inst::Inst; use dcb_bytes::{ByteArray, Bytes}; use dcb_io::GameFile; use std::io::{Read, Seek, Write}; diff --git a/dcb-exe/src/exe/inst.rs b/dcb-exe/src/exe/inst.rs index 9edda61..b019455 100644 --- a/dcb-exe/src/exe/inst.rs +++ b/dcb-exe/src/exe/inst.rs @@ -16,6 +16,8 @@ pub use reg::Register; use crate::Pos; use dcb_util::NextFromBytes; +use self::basic::Decodable; + /// An assembler instruction #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Inst { diff --git a/dcb-exe/src/exe/inst/basic.rs b/dcb-exe/src/exe/inst/basic.rs index 82afdbc..145ff4e 100644 --- a/dcb-exe/src/exe/inst/basic.rs +++ b/dcb-exe/src/exe/inst/basic.rs @@ -6,7 +6,6 @@ // Modules pub mod alu; pub mod cond; -//pub mod iter; pub mod jmp; pub mod load; pub mod lui; @@ -40,24 +39,24 @@ pub enum Inst { Sys(sys::Inst), } -impl Inst { - /// Decodes an instruction - #[must_use] +impl Decodable for Inst { + type Raw = u32; + #[bitmatch::bitmatch] #[allow(clippy::many_single_char_names)] // `bitmatch` can only output single character names. - pub fn decode(raw: u32) -> Option { + fn decode(raw: Self::Raw) -> Option { let inst = #[bitmatch] match raw { // Jump - "00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => Self::Jmp(jmp::Inst::decode(jmp::imm::Raw { p, i })?), - "000000_sssss_?????_ddddd_?????_00100f" => Self::Jmp(jmp::Inst::decode(jmp::reg::Raw { s, d, f })?), + "00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => Self::Jmp(jmp::Inst::decode_from(jmp::imm::Raw { p, i })?), + "000000_sssss_?????_ddddd_?????_00100f" => Self::Jmp(jmp::Inst::decode_from(jmp::reg::Raw { s, d, f })?), "000ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Cond(cond::Inst::decode(cond::Raw { p, s, t, i })?), "001111_?????_ttttt_iiiii_iiiii_iiiiii" => Self::Lui(lui::Inst::decode(lui::Raw { t, i })?), // Alu - "000000_sssss_ttttt_ddddd_?????_10ffff" => Self::Alu(alu::Inst::decode(alu::reg::Raw { s, t, d, f })?), - "001ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Alu(alu::Inst::decode(alu::imm::Raw { p, s, t, i })?), + "000000_sssss_ttttt_ddddd_?????_10ffff" => Self::Alu(alu::Inst::decode_from(alu::reg::Raw { s, t, d, f })?), + "001ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Alu(alu::Inst::decode_from(alu::imm::Raw { p, s, t, i })?), // Syscall "000000_ccccc_ccccc_ccccc_ccccc_00110f" => Self::Sys(sys::Inst::decode(sys::Raw { c, f })?), @@ -84,11 +83,11 @@ impl Inst { Some(inst) } +} - /// Encodes this instruction - #[must_use] +impl Encodable for Inst { #[bitmatch::bitmatch] - pub fn encode(self) -> u32 { + fn encode(&self) -> u32 { match self { Self::Jmp(inst) => match inst.encode() { jmp::Raw::Imm(jmp::imm::Raw { p, i }) => bitpack!("00001p_iiiii_iiiii_iiiii_iiiii_iiiiii"), @@ -121,3 +120,26 @@ impl Inst { } } } + +/// A decodable basic instruction +pub trait Decodable: Sized { + /// 'Raw' type to parse from + type Raw; + + /// Decodes this instruction + #[must_use] + fn decode(raw: Self::Raw) -> Option; + + /// Decodes this instruction from any type that can be converted into the raw form + #[must_use] + fn decode_from(raw: impl Into) -> Option { + Self::decode(raw.into()) + } +} + +/// An encodable basic instruction +pub trait Encodable: Decodable { + /// Encodes this instruction + #[must_use] + fn encode(&self) -> Self::Raw; +} diff --git a/dcb-exe/src/exe/inst/basic/alu.rs b/dcb-exe/src/exe/inst/basic/alu.rs index e8a6adf..c115f64 100644 --- a/dcb-exe/src/exe/inst/basic/alu.rs +++ b/dcb-exe/src/exe/inst/basic/alu.rs @@ -4,6 +4,9 @@ pub mod imm; pub mod reg; +// Imports +use crate::exe::inst::basic::{Decodable, Encodable}; + /// Raw representation #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[derive(derive_more::From)] @@ -26,19 +29,19 @@ pub enum Inst { Reg(reg::Inst), } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: impl Into) -> Option { - match raw.into() { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { + match raw { Raw::Imm(raw) => Some(Self::Imm(imm::Inst::decode(raw)?)), Raw::Reg(raw) => Some(Self::Reg(reg::Inst::decode(raw)?)), } } +} - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Self::Raw { match self { Self::Imm(inst) => Raw::Imm(inst.encode()), Self::Reg(inst) => Raw::Reg(inst.encode()), diff --git a/dcb-exe/src/exe/inst/basic/alu/imm.rs b/dcb-exe/src/exe/inst/basic/alu/imm.rs index 5aebe23..70411c8 100644 --- a/dcb-exe/src/exe/inst/basic/alu/imm.rs +++ b/dcb-exe/src/exe/inst/basic/alu/imm.rs @@ -1,7 +1,10 @@ //! Alu immediate instructions // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use dcb_util::SignedHex; use int_conv::{Signed, Truncated, ZeroExtended}; use std::fmt; @@ -98,10 +101,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { #[rustfmt::skip] let kind = match raw.p { 0x0 => Kind::Add (raw.i.truncated::().as_signed()), @@ -120,10 +123,10 @@ impl Inst { kind, }) } +} - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Self::Raw { #[rustfmt::skip] let (p, i) = match self.kind { Kind::Add (rhs) => (0x0, rhs.as_unsigned().zero_extended::()), diff --git a/dcb-exe/src/exe/inst/basic/alu/reg.rs b/dcb-exe/src/exe/inst/basic/alu/reg.rs index b66814e..12a0dc5 100644 --- a/dcb-exe/src/exe/inst/basic/alu/reg.rs +++ b/dcb-exe/src/exe/inst/basic/alu/reg.rs @@ -1,7 +1,10 @@ //! Alu register instructions // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; /// Alu register instruction kind #[derive(PartialEq, Eq, Clone, Copy, Debug)] @@ -90,10 +93,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let kind = match raw.f { 0x0 => Kind::Add, 0x1 => Kind::AddUnsigned, @@ -115,10 +118,9 @@ impl Inst { kind, }) } - - /// Encodes this instruction - #[must_use] - pub const fn encode(self) -> Raw { +} +impl Encodable for Inst { + fn encode(&self) -> Raw { let f = match self.kind { Kind::Add => 0x0, Kind::AddUnsigned => 0x1, diff --git a/dcb-exe/src/exe/inst/basic/cond.rs b/dcb-exe/src/exe/inst/basic/cond.rs index b394e52..9138293 100644 --- a/dcb-exe/src/exe/inst/basic/cond.rs +++ b/dcb-exe/src/exe/inst/basic/cond.rs @@ -1,7 +1,10 @@ //! Condition branches // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use dcb_util::SignedHex; use int_conv::{Signed, Truncated, ZeroExtended}; use std::fmt; @@ -63,10 +66,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let kind = match raw.p { 0x1 => match raw.t { 0b00000 => Kind::LessThanZero, @@ -88,10 +91,10 @@ impl Inst { kind, }) } +} - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { #[rustfmt::skip] let (p, t) = match self.kind { Kind::Equal(reg) => (0x4, reg.idx()), diff --git a/dcb-exe/src/exe/inst/basic/iter.rs b/dcb-exe/src/exe/inst/basic/iter.rs deleted file mode 100644 index 9822b74..0000000 --- a/dcb-exe/src/exe/inst/basic/iter.rs +++ /dev/null @@ -1,86 +0,0 @@ -//! Iterator over instructions - -// Imports -use super::BasicInst; - -/// Iterator over instructions -#[derive(PartialEq, Eq, Debug)] -pub struct InstIter<'a, I: Iterator + Clone> { - /// Underlying iterator - iter: &'a mut I, -} - -impl<'a, I: Iterator + Clone> InstIter<'a, I> { - /// Creates a new instruction iterator - pub fn new(iter: &'a mut I) -> Self { - Self { iter } - } - - /// Reborrows this iterator with a smaller lifetime - pub fn reborrow<'b>(&'b mut self) -> InstIter<'b, I> - where - 'a: 'b, - { - InstIter { iter: self.iter } - } - - /// Peeks the next element - pub fn peeker<'b>(&mut self) -> InstPeeker<'b, I> - where - 'a: 'b, - { - InstPeeker::new(self) - } -} - -/// Instruction Peeker -/// -/// On drop, the peeker is applied. -#[derive(PartialEq, Eq, Debug)] -pub struct InstPeeker<'a, I: Iterator + Clone> { - /// Original iterator to update - iter: InstIter<'a, I>, - - /// Last iterator - last_iter: Option, - - /// Current iterator - cur_iter: I, -} - -impl<'a, I: Iterator + Clone> InstPeeker<'a, I> { - /// Creates a new peeker - pub(self) fn new(iter: InstIter<'a, I>) -> Self { - Self { - iter, - last_iter: None, - cur_iter: iter.iter.clone(), - } - } - - /// Reverts the last element peeked - pub fn undo(&mut self) { - match self.last_iter.take() { - Some(last_iter) => self.cur_iter = last_iter, - None => self.cur_iter = self.iter.clone(), - } - } - - /// Applies this peeker into the original iterator. - pub fn apply(self) { - // Apply changes to the original iter. - *self.iter.iter = self.cur_iter; - } -} - -impl<'a, I: Iterator + Clone> Iterator for InstPeeker<'a, I> { - type Item = Option; - - fn next(&mut self) -> Option { - // Backup our current iter - self.last_iter = self.cur_iter.clone(); - - // Then get the element from the current iterator. - self.cur_iter.next() - } -} diff --git a/dcb-exe/src/exe/inst/basic/jmp.rs b/dcb-exe/src/exe/inst/basic/jmp.rs index ba8f8d2..dd6bcb9 100644 --- a/dcb-exe/src/exe/inst/basic/jmp.rs +++ b/dcb-exe/src/exe/inst/basic/jmp.rs @@ -4,6 +4,9 @@ pub mod imm; pub mod reg; +// Imports +use crate::exe::inst::basic::{Decodable, Encodable}; + /// Raw representation #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[derive(derive_more::From)] @@ -26,19 +29,19 @@ pub enum Inst { Reg(reg::Inst), } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: impl Into) -> Option { - match raw.into() { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { + match raw { Raw::Imm(raw) => Some(Self::Imm(imm::Inst::decode(raw)?)), Raw::Reg(raw) => Some(Self::Reg(reg::Inst::decode(raw)?)), } } +} - /// Encodes this instruction - #[must_use] - pub const fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { match self { Self::Imm(inst) => Raw::Imm(inst.encode()), Self::Reg(inst) => Raw::Reg(inst.encode()), diff --git a/dcb-exe/src/exe/inst/basic/jmp/imm.rs b/dcb-exe/src/exe/inst/basic/jmp/imm.rs index 8e3d5f6..94b87b6 100644 --- a/dcb-exe/src/exe/inst/basic/jmp/imm.rs +++ b/dcb-exe/src/exe/inst/basic/jmp/imm.rs @@ -1,5 +1,8 @@ //! Jump immediate instructions +// Imports +use crate::exe::inst::basic::{Decodable, Encodable}; + /// Jmp immediate instruction kind #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Kind { @@ -43,10 +46,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub const fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let kind = match raw.p { 0 => Kind::Jump, 1 => Kind::JumpLink, @@ -55,10 +58,10 @@ impl Inst { Some(Self { target: raw.i, kind }) } +} - /// Encodes this instruction - #[must_use] - pub const fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { let p = match self.kind { Kind::Jump => 0, Kind::JumpLink => 1, diff --git a/dcb-exe/src/exe/inst/basic/jmp/reg.rs b/dcb-exe/src/exe/inst/basic/jmp/reg.rs index e7c3e8c..136776a 100644 --- a/dcb-exe/src/exe/inst/basic/jmp/reg.rs +++ b/dcb-exe/src/exe/inst/basic/jmp/reg.rs @@ -1,7 +1,10 @@ //! Jump register instructions // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use std::fmt; /// Jmp register instruction kind @@ -48,10 +51,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let kind = match raw.f { 0 => Kind::Jump, 1 => Kind::JumpLink(Register::new(raw.d)?), @@ -61,10 +64,10 @@ impl Inst { Some(Self { target, kind }) } +} - /// Encodes this instruction - #[must_use] - pub const fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { let (f, d) = match self.kind { Kind::Jump => (0, 0), Kind::JumpLink(reg) => (1, reg.idx()), diff --git a/dcb-exe/src/exe/inst/basic/load.rs b/dcb-exe/src/exe/inst/basic/load.rs index 7409c65..63a762e 100644 --- a/dcb-exe/src/exe/inst/basic/load.rs +++ b/dcb-exe/src/exe/inst/basic/load.rs @@ -1,7 +1,10 @@ //! Load instructions // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use dcb_util::SignedHex; use int_conv::{Signed, Truncated, ZeroExtended}; use std::convert::TryFrom; @@ -85,10 +88,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let op = Kind::try_from(raw.p.truncated::()).ok()?; Some(Self { @@ -98,10 +101,10 @@ impl Inst { kind: op, }) } +} - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { let t = self.src.idx(); let s = self.dst.idx(); let i = self.offset.as_unsigned().zero_extended::(); diff --git a/dcb-exe/src/exe/inst/basic/lui.rs b/dcb-exe/src/exe/inst/basic/lui.rs index 0485c1a..6d2f335 100644 --- a/dcb-exe/src/exe/inst/basic/lui.rs +++ b/dcb-exe/src/exe/inst/basic/lui.rs @@ -1,7 +1,10 @@ //! Lui instruction // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use int_conv::{Truncated, ZeroExtended}; /// Raw representation @@ -26,19 +29,18 @@ pub struct Inst { pub value: u16, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { Some(Self { dst: Register::new(raw.t)?, value: raw.i.truncated::(), }) } - - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +} +impl Encodable for Inst { + fn encode(&self) -> Raw { Raw { t: self.dst.idx(), i: self.value.zero_extended::(), diff --git a/dcb-exe/src/exe/inst/basic/mult.rs b/dcb-exe/src/exe/inst/basic/mult.rs index fff2697..8ad18a1 100644 --- a/dcb-exe/src/exe/inst/basic/mult.rs +++ b/dcb-exe/src/exe/inst/basic/mult.rs @@ -1,10 +1,13 @@ //! Multiplications // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use std::fmt; -/// Operation func +/// Operation kind #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum MultKind { /// Multiplication @@ -36,7 +39,7 @@ pub enum MultReg { /// Raw representation #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct MultRaw { +pub struct Raw { /// Rs pub s: u32, @@ -52,7 +55,7 @@ pub struct MultRaw { /// Multiplication instructions #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub enum MultInst { +pub enum Inst { /// Multiplication Mult { /// Kind @@ -87,11 +90,11 @@ pub enum MultInst { }, } -impl MultInst { - /// Decodes this instruction - #[must_use] +impl Decodable for Inst { + type Raw = Raw; + #[rustfmt::skip] - pub fn decode(raw: MultRaw) -> Option { + fn decode(raw: Self::Raw) -> Option { Some(match raw.f { 0x10 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Hi }, 0x12 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Lo }, @@ -107,12 +110,12 @@ impl MultInst { _ => return None, }) } +} - /// Encodes this instruction - #[must_use] - pub const fn encode(self) -> MultRaw { +impl Encodable for Inst { + fn encode(&self) -> Raw { match self { - Self::Mult { kind, mode, lhs, rhs } => MultRaw { + Self::Mult { kind, mode, lhs, rhs } => Raw { s: lhs.idx(), t: rhs.idx(), d: 0, @@ -123,7 +126,7 @@ impl MultInst { (MultKind::Div, MultMode::Unsigned) => 0x1b, }, }, - Self::MoveFrom { dst, src } => MultRaw { + Self::MoveFrom { dst, src } => Raw { s: 0, t: 0, d: dst.idx(), @@ -132,7 +135,7 @@ impl MultInst { MultReg::Lo => 0x12, }, }, - Self::MoveTo { dst: src, src: dst } => MultRaw { + Self::MoveTo { dst: src, src: dst } => Raw { s: src.idx(), t: 0, d: 0, @@ -145,7 +148,7 @@ impl MultInst { } } -impl fmt::Display for MultInst { +impl fmt::Display for Inst { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { #[rustfmt::skip] diff --git a/dcb-exe/src/exe/inst/basic/store.rs b/dcb-exe/src/exe/inst/basic/store.rs index 5c5d45b..9004a83 100644 --- a/dcb-exe/src/exe/inst/basic/store.rs +++ b/dcb-exe/src/exe/inst/basic/store.rs @@ -1,7 +1,10 @@ //! Store instructions // Imports -use crate::exe::inst::Register; +use crate::exe::inst::{ + basic::{Decodable, Encodable}, + Register, +}; use dcb_util::SignedHex; use int_conv::{Signed, Truncated, ZeroExtended}; use std::convert::TryFrom; @@ -77,10 +80,10 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub fn decode(raw: Raw) -> Option { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { let kind = Kind::try_from(raw.p.truncated::()).ok()?; Some(Self { @@ -90,10 +93,9 @@ impl Inst { kind, }) } - - /// Encodes this instruction - #[must_use] - pub fn encode(self) -> Raw { +} +impl Encodable for Inst { + fn encode(&self) -> Raw { let t = self.src.idx(); let s = self.dst.idx(); let i = self.offset.as_unsigned().zero_extended::(); diff --git a/dcb-exe/src/exe/inst/basic/sys.rs b/dcb-exe/src/exe/inst/basic/sys.rs index 8a6b834..3404e4d 100644 --- a/dcb-exe/src/exe/inst/basic/sys.rs +++ b/dcb-exe/src/exe/inst/basic/sys.rs @@ -1,5 +1,8 @@ //! System calls +// Imports +use crate::exe::inst::basic::{Decodable, Encodable}; + /// Sys instruction func #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Kind { @@ -43,23 +46,22 @@ pub struct Inst { pub kind: Kind, } -impl Inst { - /// Decodes this instruction - #[must_use] - pub const fn decode(Raw { c, f }: Raw) -> Option { - let kind = match f { +impl Decodable for Inst { + type Raw = Raw; + + fn decode(raw: Self::Raw) -> Option { + let kind = match raw.f { 0 => Kind::Sys, 1 => Kind::Break, _ => return None, }; - Some(Self { comment: c, kind }) + Some(Self { comment: raw.c, kind }) } +} - /// Encodes this instruction - #[must_use] - #[allow(clippy::many_single_char_names)] // `Raw` has single character names - pub const fn encode(self) -> Raw { +impl Encodable for Inst { + fn encode(&self) -> Raw { let c = self.comment; let f = match self.kind { Kind::Sys => 0,