mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 19:34:27 +00:00
Added pseudo::shift_assign instructions.
Fixed `pseudo::store` instruction being implemented wrong.
This commit is contained in:
parent
a00fd15d49
commit
9cc7d81e8e
@ -11,6 +11,7 @@ pub mod load;
|
||||
pub mod load_imm;
|
||||
pub mod move_reg;
|
||||
pub mod nop;
|
||||
pub mod shift_assign;
|
||||
pub mod store;
|
||||
|
||||
// Imports
|
||||
@ -23,6 +24,9 @@ pub enum Inst {
|
||||
/// Alu self-assign
|
||||
AluAssign(alu_assign::Inst),
|
||||
|
||||
/// Shift self-assign
|
||||
ShiftAssign(shift_assign::Inst),
|
||||
|
||||
/// Load immediate
|
||||
LoadImm(load_imm::Inst),
|
||||
|
||||
@ -45,14 +49,14 @@ pub enum Inst {
|
||||
impl Decodable for Inst {
|
||||
#[rustfmt::skip]
|
||||
fn decode(insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self> {
|
||||
// Note: Order is important
|
||||
load_imm ::Inst::decode(insts.clone()).map(Self::LoadImm )
|
||||
.or_else( || alu_assign::Inst::decode(insts.clone()).map(Self::AluAssign))
|
||||
.or_else( || nop ::Inst::decode(insts.clone()).map(Self::Nop ))
|
||||
.or_else( || jmp ::Inst::decode(insts.clone()).map(Self::Jmp ))
|
||||
.or_else( || load ::Inst::decode(insts.clone()).map(Self::Load ))
|
||||
.or_else( || store ::Inst::decode(insts.clone()).map(Self::Store ))
|
||||
.or_else(move || move_reg ::Inst::decode( insts ).map(Self::MoveReg ))
|
||||
load_imm ::Inst::decode(insts.clone()).map(Self::LoadImm )
|
||||
.or_else( || nop ::Inst::decode(insts.clone()).map(Self::Nop )) // Note: Nop must come before `shift_assign`
|
||||
.or_else( || alu_assign ::Inst::decode(insts.clone()).map(Self::AluAssign ))
|
||||
.or_else( || shift_assign::Inst::decode(insts.clone()).map(Self::ShiftAssign))
|
||||
.or_else( || jmp ::Inst::decode(insts.clone()).map(Self::Jmp ))
|
||||
.or_else( || load ::Inst::decode(insts.clone()).map(Self::Load ))
|
||||
.or_else( || store ::Inst::decode(insts.clone()).map(Self::Store ))
|
||||
.or_else(move || move_reg ::Inst::decode( insts ).map(Self::MoveReg ))
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,6 +64,7 @@ impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
match self {
|
||||
Self::AluAssign(inst) => inst.size(),
|
||||
Self::ShiftAssign(inst) => inst.size(),
|
||||
Self::LoadImm(inst) => inst.size(),
|
||||
Self::Nop(inst) => inst.size(),
|
||||
Self::MoveReg(inst) => inst.size(),
|
||||
@ -74,6 +79,7 @@ impl InstFmt for Inst {
|
||||
fn mnemonic(&self) -> &'static str {
|
||||
match self {
|
||||
Self::AluAssign(inst) => inst.mnemonic(),
|
||||
Self::ShiftAssign(inst) => inst.mnemonic(),
|
||||
Self::LoadImm(inst) => inst.mnemonic(),
|
||||
Self::Nop(inst) => inst.mnemonic(),
|
||||
Self::MoveReg(inst) => inst.mnemonic(),
|
||||
@ -86,6 +92,7 @@ impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::AluAssign(inst) => inst.fmt(pos, f),
|
||||
Self::ShiftAssign(inst) => inst.fmt(pos, f),
|
||||
Self::LoadImm(inst) => inst.fmt(pos, f),
|
||||
Self::Nop(inst) => inst.fmt(pos, f),
|
||||
Self::MoveReg(inst) => inst.fmt(pos, f),
|
||||
|
||||
102
dcb-exe/src/exe/inst/pseudo/shift_assign.rs
Normal file
102
dcb-exe/src/exe/inst/pseudo/shift_assign.rs
Normal file
@ -0,0 +1,102 @@
|
||||
//! Shift self-assign instructions
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use crate::exe::inst::{
|
||||
basic::{self, shift},
|
||||
InstFmt, InstSize, Register,
|
||||
};
|
||||
use std::{convert::TryInto, fmt};
|
||||
|
||||
/// Shift assign kind
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub enum Kind {
|
||||
/// Immediate
|
||||
Imm {
|
||||
/// Kind
|
||||
kind: shift::imm::Kind,
|
||||
|
||||
/// Argument
|
||||
rhs: u8,
|
||||
},
|
||||
|
||||
/// Register
|
||||
Reg {
|
||||
/// Kind
|
||||
kind: shift::reg::Kind,
|
||||
|
||||
/// Argument
|
||||
rhs: Register,
|
||||
},
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
/// Returns this kind's mnemonic
|
||||
#[must_use]
|
||||
pub const fn mnemonic(self) -> &'static str {
|
||||
match self {
|
||||
Self::Imm { kind, .. } => kind.mnemonic(),
|
||||
Self::Reg { kind, .. } => kind.mnemonic(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a displayable with the value of this kind
|
||||
#[must_use]
|
||||
pub fn value_fmt(self) -> impl fmt::Display {
|
||||
dcb_util::DisplayWrapper::new(move |f| match self {
|
||||
Self::Imm { rhs, .. } => write!(f, "{:#x}", rhs),
|
||||
Self::Reg { rhs, .. } => write!(f, "{}", rhs),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Shift self-assign instructions
|
||||
///
|
||||
/// Alias for
|
||||
/// ```mips
|
||||
/// [shift] $dst, $dst, ...
|
||||
/// ```
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct Inst {
|
||||
/// Destination and source register
|
||||
pub dst: Register,
|
||||
|
||||
/// Kind
|
||||
pub kind: Kind,
|
||||
}
|
||||
|
||||
impl Decodable for Inst {
|
||||
fn decode(mut insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self> {
|
||||
match insts.next()?.try_into().ok()? {
|
||||
shift::Inst::Imm(shift::imm::Inst { dst, lhs, rhs, kind }) if dst == lhs => Some(Self {
|
||||
dst,
|
||||
kind: Kind::Imm { kind, rhs },
|
||||
}),
|
||||
shift::Inst::Reg(shift::reg::Inst { dst, lhs, rhs, kind }) if dst == lhs => Some(Self {
|
||||
dst,
|
||||
kind: Kind::Reg { kind, rhs },
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn mnemonic(&self) -> &'static str {
|
||||
self.kind.mnemonic()
|
||||
}
|
||||
|
||||
fn fmt(&self, _pos: crate::Pos, 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}")
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@ use super::Decodable;
|
||||
///
|
||||
/// Alias for
|
||||
/// ```mips
|
||||
/// lui $dst, {hi}
|
||||
/// lui $at, {hi}
|
||||
/// s* $dst, {lo}($at)
|
||||
/// ```
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
@ -31,8 +31,8 @@ pub struct Inst {
|
||||
impl Decodable for Inst {
|
||||
fn decode(mut insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self> {
|
||||
let inst = match insts.next()? {
|
||||
basic::Inst::Lui(lui) => match insts.next()? {
|
||||
basic::Inst::Store(store) if store.dst == lui.dst && store.src == Register::At => Self {
|
||||
basic::Inst::Lui(lui) if lui.dst == Register::At => match insts.next()? {
|
||||
basic::Inst::Store(store) if store.src == Register::At => Self {
|
||||
dst: lui.dst,
|
||||
target: Pos((u32::join(0, lui.value).as_signed() + store.offset.sign_extended::<i32>()).as_unsigned()),
|
||||
kind: store.kind,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user