mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 19:34:27 +00:00
Removed pseudo::jmp and made basic::{cond, jmp::reg} write the pseudo instrutions.
This commit is contained in:
@@ -55,23 +55,6 @@ pub enum Kind {
|
||||
GreaterOrEqualZeroLink,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
/// Returns this instruction kind's mnemonic
|
||||
#[must_use]
|
||||
pub const fn mnemonic(self) -> &'static str {
|
||||
match self {
|
||||
Self::Equal(_) => "beq",
|
||||
Self::NotEqual(_) => "bne",
|
||||
Self::LessOrEqualZero => "blez",
|
||||
Self::GreaterThanZero => "bgtz",
|
||||
Self::LessThanZero => "bltz",
|
||||
Self::GreaterOrEqualZero => "bgez",
|
||||
Self::LessThanZeroLink => "bltzal",
|
||||
Self::GreaterOrEqualZeroLink => "bgezal",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Condition instructions
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct Inst {
|
||||
@@ -158,15 +141,24 @@ impl Inst {
|
||||
pub fn fmt_target<'a>(self, target: impl fmt::Display + 'a) -> impl fmt::Display + 'a {
|
||||
dcb_util::DisplayWrapper::new(move |f| {
|
||||
let Self { kind, arg, .. } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
// `beq $zr, $zr, offset` => `b offset`
|
||||
// `beq $zr, $arg, offset` => `beqz $arg, offset`
|
||||
// `beq $zr, $arg, offset` => `bnez $arg, offset`
|
||||
match kind {
|
||||
Kind::Equal(reg) | Kind::NotEqual(reg) => write!(f, "{mnemonic} {arg}, {reg}, {target}"),
|
||||
Kind::LessOrEqualZero |
|
||||
Kind::GreaterThanZero |
|
||||
Kind::LessThanZero |
|
||||
Kind::GreaterOrEqualZero |
|
||||
Kind::LessThanZeroLink |
|
||||
Kind::GreaterOrEqualZeroLink => write!(f, "{mnemonic} {arg}, {target}"),
|
||||
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}"),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -84,7 +84,11 @@ impl InstFmt for Inst {
|
||||
|
||||
match kind {
|
||||
Kind::Jump => write!(f, "{mnemonic} {target}"),
|
||||
Kind::JumpLink(reg) => write!(f, "{mnemonic} {target}, {reg}"),
|
||||
Kind::JumpLink(reg) => match reg {
|
||||
// If using `$ra`, don't output it.
|
||||
Register::Ra => write!(f, "{mnemonic} {target}"),
|
||||
reg => write!(f, "{mnemonic} {target}, {reg}"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
// Modules
|
||||
pub mod alu_assign;
|
||||
pub mod jmp;
|
||||
pub mod load;
|
||||
pub mod load_imm;
|
||||
pub mod move_reg;
|
||||
@@ -36,9 +35,6 @@ pub enum Inst {
|
||||
/// Move register
|
||||
MoveReg(move_reg::Inst),
|
||||
|
||||
/// Jump
|
||||
Jmp(jmp::Inst),
|
||||
|
||||
/// Load
|
||||
Load(load::Inst),
|
||||
|
||||
@@ -53,7 +49,6 @@ impl Decodable for Inst {
|
||||
.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 ))
|
||||
@@ -68,7 +63,6 @@ impl InstSize for Inst {
|
||||
Self::LoadImm(inst) => inst.size(),
|
||||
Self::Nop(inst) => inst.size(),
|
||||
Self::MoveReg(inst) => inst.size(),
|
||||
Self::Jmp(inst) => inst.size(),
|
||||
Self::Load(inst) => inst.size(),
|
||||
Self::Store(inst) => inst.size(),
|
||||
}
|
||||
@@ -83,7 +77,6 @@ impl InstFmt for Inst {
|
||||
Self::LoadImm(inst) => inst.fmt(pos, f),
|
||||
Self::Nop(inst) => inst.fmt(pos, f),
|
||||
Self::MoveReg(inst) => inst.fmt(pos, f),
|
||||
Self::Jmp(inst) => inst.fmt(pos, f),
|
||||
Self::Load(inst) => inst.fmt(pos, f),
|
||||
Self::Store(inst) => inst.fmt(pos, f),
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
//! Jump pseudo instructions
|
||||
|
||||
// Imports
|
||||
use crate::exe::inst::{basic, InstFmt, InstSize, Register};
|
||||
|
||||
use super::Decodable;
|
||||
|
||||
/// Jump / Branch instructions
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub enum Inst {
|
||||
/// Jump and link with return address
|
||||
/// Alias for `jalr $target, $ra`
|
||||
JalrRa {
|
||||
/// Target for the jump
|
||||
target: Register,
|
||||
},
|
||||
|
||||
/// Branch if equal to zero
|
||||
/// Alias for `beq $arg, $zr, offset`
|
||||
Beqz {
|
||||
/// Argument to compare
|
||||
arg: Register,
|
||||
|
||||
/// Jump offset
|
||||
offset: i16,
|
||||
},
|
||||
|
||||
/// Branch if different from zero
|
||||
/// Alias for `bne $arg, $zr, offset`
|
||||
Bnez {
|
||||
/// Argument to compare
|
||||
arg: Register,
|
||||
|
||||
/// Jump offset
|
||||
offset: i16,
|
||||
},
|
||||
|
||||
/// Jump relative
|
||||
/// Alias for `beq $zr, $zr, offset`
|
||||
B {
|
||||
/// Jump offset
|
||||
offset: i16,
|
||||
},
|
||||
}
|
||||
|
||||
impl Decodable for Inst {
|
||||
fn decode(mut insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self> {
|
||||
let inst = match insts.next()? {
|
||||
basic::Inst::Cond(basic::cond::Inst { arg, offset, kind }) => match kind {
|
||||
basic::cond::Kind::Equal(Register::Zr) => match arg {
|
||||
// `beq $zr, $zr, offset`
|
||||
Register::Zr => Self::B { offset },
|
||||
// `beq $zr, $arg, offset`
|
||||
_ => Self::Beqz { arg, offset },
|
||||
},
|
||||
// `bnq $zr, $arg, offset`
|
||||
basic::cond::Kind::NotEqual(Register::Zr) => Self::Bnez { arg, offset },
|
||||
_ => return None,
|
||||
},
|
||||
// `jalr $ra, $target`
|
||||
basic::Inst::Jmp(basic::jmp::Inst::Reg(basic::jmp::reg::Inst {
|
||||
target,
|
||||
kind: basic::jmp::reg::Kind::JumpLink(Register::Ra),
|
||||
})) => Self::JalrRa { target },
|
||||
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(inst)
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match *self {
|
||||
Self::JalrRa { target } => write!(f, "jalr {target}"),
|
||||
Self::Beqz { arg, offset } => write!(f, "beqz {arg}, {}", basic::cond::Inst::target_of(offset, pos)),
|
||||
Self::Bnez { arg, offset } => write!(f, "bnez {arg}, {}", basic::cond::Inst::target_of(offset, pos)),
|
||||
Self::B { offset } => write!(f, "b {}", basic::cond::Inst::target_of(offset, pos)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,6 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
Inst::Basic (basic ::Inst::Load (inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
Inst::Basic (basic ::Inst::Store (inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
Inst::Pseudo(pseudo::Inst::LoadImm(inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
Inst::Pseudo(pseudo::Inst::Jmp (inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
Inst::Pseudo(pseudo::Inst::Load (inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
Inst::Pseudo(pseudo::Inst::Store (inst)) => print!("{}", inst.fmt_value(pos)),
|
||||
inst => print!("{}", inst.fmt_value(pos)),
|
||||
|
||||
Reference in New Issue
Block a user