mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 03:40:23 +00:00
113 lines
2.0 KiB
Rust
113 lines
2.0 KiB
Rust
//! Shift register instructions
|
|
|
|
// Imports
|
|
use crate::exe::inst::{
|
|
basic::{Decodable, Encodable},
|
|
InstFmt, Register,
|
|
};
|
|
|
|
/// Shift register instruction kind
|
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
pub enum Kind {
|
|
/// Left logical
|
|
LeftLogical,
|
|
|
|
/// Right logical
|
|
RightLogical,
|
|
|
|
/// Right arithmetic
|
|
RightArithmetic,
|
|
}
|
|
|
|
impl Kind {
|
|
/// Returns this kind's mnemonic
|
|
#[must_use]
|
|
pub const fn mnemonic(self) -> &'static str {
|
|
match self {
|
|
Self::LeftLogical => "sllv",
|
|
Self::RightLogical => "srlv",
|
|
Self::RightArithmetic => "srav",
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Raw representation
|
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
pub struct Raw {
|
|
/// Rs
|
|
pub s: u32,
|
|
|
|
/// Rt
|
|
pub t: u32,
|
|
|
|
/// Rd
|
|
pub d: u32,
|
|
|
|
/// Func (lower 4 bits)
|
|
pub f: u32,
|
|
}
|
|
|
|
/// Shift register instructions
|
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
pub struct Inst {
|
|
/// Destination register
|
|
pub dst: Register,
|
|
|
|
/// Lhs argument
|
|
pub lhs: Register,
|
|
|
|
/// Rhs argument
|
|
pub rhs: Register,
|
|
|
|
/// Kind
|
|
pub kind: Kind,
|
|
}
|
|
|
|
impl Decodable for Inst {
|
|
type Raw = Raw;
|
|
|
|
fn decode(raw: Self::Raw) -> Option<Self> {
|
|
let kind = match raw.f {
|
|
0x0 => Kind::LeftLogical,
|
|
0x2 => Kind::RightLogical,
|
|
0x3 => Kind::RightArithmetic,
|
|
_ => return None,
|
|
};
|
|
|
|
Some(Self {
|
|
dst: Register::new(raw.d)?,
|
|
lhs: Register::new(raw.t)?,
|
|
rhs: Register::new(raw.s)?,
|
|
kind,
|
|
})
|
|
}
|
|
}
|
|
impl Encodable for Inst {
|
|
fn encode(&self) -> Self::Raw {
|
|
let f = match self.kind {
|
|
Kind::LeftLogical => 0x0,
|
|
Kind::RightLogical => 0x2,
|
|
Kind::RightArithmetic => 0x3,
|
|
};
|
|
|
|
let d = self.dst.idx();
|
|
let t = self.lhs.idx();
|
|
let s = self.rhs.idx();
|
|
|
|
Raw { s, t, d, f }
|
|
}
|
|
}
|
|
|
|
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}"),
|
|
}
|
|
}
|
|
}
|