diff --git a/dcb-exe/src/exe/inst/pseudo.rs b/dcb-exe/src/exe/inst/pseudo.rs index b4af60b..da012b8 100644 --- a/dcb-exe/src/exe/inst/pseudo.rs +++ b/dcb-exe/src/exe/inst/pseudo.rs @@ -10,7 +10,7 @@ pub mod load_imm; //pub mod jmp; //pub mod load; //pub mod move_reg; -//pub mod nop; +pub mod nop; //pub mod store; // Imports @@ -25,6 +25,9 @@ pub enum Inst { /// Load immediate LoadImm(load_imm::Inst), + + /// No-op + Nop(nop::Inst), /* /// Load Load(LoadPseudoInst), @@ -38,9 +41,6 @@ pub enum Inst { /// Load immediate LoadImm(LoadImmInst), - /// No-op - Nop(NopInst), - */ /* /// Subtract immediate @@ -70,7 +70,8 @@ impl Decodable for Inst { // Note: Order is important load_imm::Inst::decode(insts.clone()) .map(Self::LoadImm) - .or_else(|| alu_assign::Inst::decode(insts).map(Self::AluAssign)) + .or_else(|| alu_assign::Inst::decode(insts.clone()).map(Self::AluAssign)) + .or_else(move || nop::Inst::decode(insts).map(Self::Nop)) } } @@ -79,6 +80,7 @@ impl InstSize for Inst { match self { Self::AluAssign(inst) => inst.size(), Self::LoadImm(inst) => inst.size(), + Self::Nop(inst) => inst.size(), } } } @@ -88,6 +90,7 @@ impl InstFmt for Inst { match self { Self::AluAssign(inst) => inst.mnemonic(), Self::LoadImm(inst) => inst.mnemonic(), + Self::Nop(inst) => inst.mnemonic(), } } @@ -95,6 +98,7 @@ impl InstFmt for Inst { match self { Self::AluAssign(inst) => inst.fmt(pos, f), Self::LoadImm(inst) => inst.fmt(pos, f), + Self::Nop(inst) => inst.fmt(pos, f), } } } diff --git a/dcb-exe/src/exe/inst/pseudo/nop.rs b/dcb-exe/src/exe/inst/pseudo/nop.rs index bd2d4d9..7cb8cc6 100644 --- a/dcb-exe/src/exe/inst/pseudo/nop.rs +++ b/dcb-exe/src/exe/inst/pseudo/nop.rs @@ -1,42 +1,60 @@ //! Nop // Imports -use crate::exe::inst::{ - basic::{ - special::{ - shift::{reg::ShiftRegFunc, ShiftImmInst}, - ShiftInst, - }, - InstIter, SpecialInst, - }, - BasicInst, Register, -}; +use crate::exe::inst::{basic, InstFmt, InstSize, Register}; + +use super::Decodable; /// No-op /// -/// Alias for `sll $zr, $zr, 0`. +/// Alias for any number of `sll $zr, $zr, 0`. #[derive(PartialEq, Eq, Clone, Copy, Debug)] -#[derive(derive_more::Display)] -#[display(fmt = "nop ")] -pub struct NopInst {} +pub struct Inst { + /// Length of this nop, in instructions + len: usize, +} -impl NopInst { - /// Decodes this pseudo instruction - #[must_use] - pub fn decode(iter: InstIter<'_, impl Iterator + Clone>) -> Option { - let peeker = iter.peeker(); - let inst = match peeker.next()?? { - BasicInst::AluImm(SpecialInst::Shift(ShiftInst::Imm(ShiftImmInst { - dst: Register::Zr, - lhs: Register::Zr, - rhs: 0, - func: ShiftRegFunc::LeftLogical, - }))) => Self, +impl Decodable for Inst { + fn decode(insts: impl Iterator + Clone) -> Option { + // Get how many nops there are, in a row + let len = insts + .take_while(|inst| { + matches!( + inst, + basic::Inst::Shift(basic::shift::Inst::Imm(basic::shift::imm::Inst { + dst: Register::Zr, + lhs: Register::Zr, + rhs: 0, + kind: basic::shift::imm::Kind::LeftLogical, + })) + ) + }) + .count(); - _ => return None, - }; - - peeker.apply(); - return inst; + match len { + 0 => None, + _ => Some(Self { len }), + } + } +} + +impl InstSize for Inst { + fn size(&self) -> usize { + 4 * self.len + } +} + +impl InstFmt for Inst { + fn mnemonic(&self) -> &'static str { + "nop" + } + + fn fmt(&self, _pos: crate::Pos, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let mnemonic = self.mnemonic(); + + match self.len { + 1 => write!(f, "{mnemonic}"), + len => write!(f, "{mnemonic} {}", len), + } } }