mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 03:40:23 +00:00
Added dcb_exe::exe::inst::basic::{Decodable, Encodable}.
This commit is contained in:
@@ -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};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<Self> {
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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<Self>;
|
||||
|
||||
/// Decodes this instruction from any type that can be converted into the raw form
|
||||
#[must_use]
|
||||
fn decode_from(raw: impl Into<Self::Raw>) -> Option<Self> {
|
||||
Self::decode(raw.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// An encodable basic instruction
|
||||
pub trait Encodable: Decodable {
|
||||
/// Encodes this instruction
|
||||
#[must_use]
|
||||
fn encode(&self) -> Self::Raw;
|
||||
}
|
||||
|
||||
@@ -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<Raw>) -> Option<Self> {
|
||||
match raw.into() {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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()),
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
#[rustfmt::skip]
|
||||
let kind = match raw.p {
|
||||
0x0 => Kind::Add (raw.i.truncated::<u16>().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::<u32>()),
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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,
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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()),
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
//! Iterator over instructions
|
||||
|
||||
// Imports
|
||||
use super::BasicInst;
|
||||
|
||||
/// Iterator over instructions
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct InstIter<'a, I: Iterator<Item = u32> + Clone> {
|
||||
/// Underlying iterator
|
||||
iter: &'a mut I,
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = u32> + 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<Item = u32> + Clone> {
|
||||
/// Original iterator to update
|
||||
iter: InstIter<'a, I>,
|
||||
|
||||
/// Last iterator
|
||||
last_iter: Option<I>,
|
||||
|
||||
/// Current iterator
|
||||
cur_iter: I,
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = u32> + 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<Item = u32> + Clone> Iterator for InstPeeker<'a, I> {
|
||||
type Item = Option<BasicInst>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Backup our current iter
|
||||
self.last_iter = self.cur_iter.clone();
|
||||
|
||||
// Then get the element from the current iterator.
|
||||
self.cur_iter.next()
|
||||
}
|
||||
}
|
||||
@@ -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<Raw>) -> Option<Self> {
|
||||
match raw.into() {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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()),
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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,
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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()),
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
let op = Kind::try_from(raw.p.truncated::<u8>()).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::<u32>();
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
Some(Self {
|
||||
dst: Register::new(raw.t)?,
|
||||
value: raw.i.truncated::<u16>(),
|
||||
})
|
||||
}
|
||||
|
||||
/// 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::<u32>(),
|
||||
|
||||
@@ -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<Self> {
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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]
|
||||
|
||||
@@ -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<Self> {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
let kind = Kind::try_from(raw.p.truncated::<u8>()).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::<u32>();
|
||||
|
||||
@@ -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<Self> {
|
||||
let kind = match f {
|
||||
impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user