From 83b3f7bac9d6e5c68dd03843b696fd3c6a3ee4b6 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Sun, 3 May 2026 23:28:37 -0700 Subject: [PATCH] use custom debug --- crates/cpu/src/instruction.rs | 324 +++++++++++----------- crates/cpu/src/rename_execute_retire.rs | 72 ++--- crates/cpu/src/unit.rs | 7 +- crates/cpu/tests/rename_execute_retire.rs | 10 +- 4 files changed, 202 insertions(+), 211 deletions(-) diff --git a/crates/cpu/src/instruction.rs b/crates/cpu/src/instruction.rs index c6c0082..969b1ee 100644 --- a/crates/cpu/src/instruction.rs +++ b/crates/cpu/src/instruction.rs @@ -86,14 +86,6 @@ pub trait MOpVisitVariants: MOpTrait { VisitOps::Target: MOpTrait; } -pub trait MOpDebug: MOpTrait { - fn mop_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result; -} - -pub trait MOpImmDebug: Type { - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result; -} - pub trait MOpTrait: Type { type Mapped: MOpTrait; type DestReg: Type; @@ -465,13 +457,7 @@ impl SimValueDebug for CommonMOpDefaultImm { value: &::SimValue, f: &mut fmt::Formatter<'_>, ) -> fmt::Result { - fmt::Debug::fmt(value, f) - } -} - -impl MOpImmDebug for CommonMOpDefaultImm { - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ::fmt(this, f) + ::fmt(value, f) } } @@ -600,7 +586,7 @@ impl HdlPartialEqImpl for CommonMOpDefaultImm + SimValueDebug for CommonMOp +{ + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Display::fmt(&Self::mop_debug(value, true), f) + } +} + impl CommonMOp { @@ -627,32 +624,11 @@ impl= MOP_MIN_REG_WIDTH, "{self:#?}"); } - fn debug_dest(this: &SimValue) -> impl fmt::Debug { - use std::any::Any; - fmt::from_fn(move |f| { - if let Some(dest) = ::downcast_ref::>(&this.dest) { - f.debug_set() - .entries( - MOpDestReg::regs_sim(dest) - .into_iter() - .filter(|&v| v != MOpRegNum::CONST_ZERO_REG_NUM), - ) - .finish() - } else if let Some(dest) = - ::downcast_ref::>>>(&this.dest) - { - fmt::Debug::fmt(&PRegNum::debug_sim(dest), f) - } else if let Some(dest) = ::downcast_ref::< - SimValue>>, - >(&this.dest) - { - fmt::Debug::fmt(&UnitOutRegNum::debug_sim(dest), f) - } else { - fmt::Debug::fmt(&this.dest, f) - } - }) - } - fn debug_sources(this: &SimValue, is_first: bool, is_last: bool) -> impl fmt::Display { + fn debug_sources( + this: &::SimValue, + is_first: bool, + is_last: bool, + ) -> impl fmt::Display { fmt::from_fn(move |f| { let mut need_comma = !is_first; for src in &this.src { @@ -669,15 +645,12 @@ impl, debug_imm: bool) -> impl fmt::Display - where - Imm: MOpImmDebug, - { + fn mop_debug(this: &::SimValue, debug_imm: bool) -> impl fmt::Display { fmt::from_fn(move |f| { - fmt::Debug::fmt(&Self::debug_dest(this), f)?; + write!(f, "{:?}", this.dest)?; fmt::Display::fmt(&Self::debug_sources(this, false, !debug_imm), f)?; if debug_imm { - MOpImmDebug::mop_imm_debug(&this.imm, f)?; + fmt::Debug::fmt(&this.imm, f)?; } Ok(()) }) @@ -789,7 +762,7 @@ pub const COMMON_MOP_3_IMM_WIDTH: usize = common_mop_max_imm_size(3); macro_rules! common_mop_struct { ( - #[debug($(#[$hdl:ident])? |$debug_this:ident, $debug_f:ident| $debug_block:block $(where $($debug_where:tt)*)?)] + #[debug($(#[$debug_hdl:ident])? |$debug_value:ident, $debug_f:ident| $debug_block:block $(where $($debug_where:tt)*)?)] #[mapped(<$NewDestReg:ident, $SrcRegWidth:ident> $mapped_ty:ty)] $(#[$struct_meta:meta])* $vis:vis struct $MOp:ident<$($Generic:ident: $GenericBound:ident),* $(,)?> { @@ -816,11 +789,11 @@ macro_rules! common_mop_struct { } } - impl<$($Generic: $GenericBound),*> MOpDebug for $MOp<$($Generic),*> + impl<$($Generic: $GenericBound),*> SimValueDebug for $MOp<$($Generic),*> $(where $($debug_where)*)? { - $(#[$hdl])? - fn mop_debug($debug_this: &SimValue, $debug_f: &mut fmt::Formatter<'_>) -> fmt::Result $debug_block + $(#[$debug_hdl])? + fn sim_value_debug($debug_value: &::SimValue, $debug_f: &mut fmt::Formatter<'_>) -> fmt::Result $debug_block } }; ( @@ -934,7 +907,6 @@ macro_rules! common_mop_struct { macro_rules! mop_enum { ( - $(#[debug(where $($debug_where:tt)*)])? #[impl_mop_into = $impl_mop_into:tt] $(#[$enum_meta:meta])* $vis:vis enum $MOp:ident< @@ -1003,23 +975,21 @@ macro_rules! mop_enum { impl< $DestReg: Type, $SrcRegWidth: Size, - $($MOpTypes: Type + MOpTrait,)* + $($MOpTypes: Type,)* $($Sizes: Size,)* - > crate::instruction::MOpDebug for $MOp< + > fayalite::ty::SimValueDebug for $MOp< $DestReg, $SrcRegWidth, $($MOpTypes,)* $($Sizes,)* - > - $(where $($debug_where)*)? - { + > { #[hdl] - fn mop_debug(this: &SimValue, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn sim_value_debug(this: &::SimValue, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { #![allow(unreachable_patterns)] #[hdl(sim)] match this { - Self::$FirstVariant(v) => <$first_ty as crate::instruction::MOpDebug>::mop_debug(v, f), - $(Self::$Variant(v) => <$ty as crate::instruction::MOpDebug>::mop_debug(v, f),)* + Self::$FirstVariant(v) => std::fmt::Debug::fmt(v, f), + $(Self::$Variant(v) => std::fmt::Debug::fmt(v, f),)* _ => std::fmt::Debug::fmt(this, f), } } @@ -1358,7 +1328,7 @@ common_mop_struct! { } } -impl +impl AluCommonMOp { #[hdl] @@ -1416,7 +1386,7 @@ common_mop_struct! { maybe_write_comma_flag!(f, add_pc, **add_pc) })] #[mapped( AddSubMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct AddSubMOp { #[common] pub alu_common: AluCommonMOp>, @@ -1577,7 +1547,7 @@ impl Lut4 { } /// immediate values for [`LogicalFlagsMOp`]. See [`LogicalFlagsMOp`] for a description of the operation. -#[hdl(cmp_eq)] +#[hdl(cmp_eq, custom_debug(sim))] pub struct LogicalFlagsMOpImm { pub src0_start: UIntInRange<0, { PRegFlags::FLAG_COUNT }>, pub src1_start: UIntInRange<0, { PRegFlags::FLAG_COUNT }>, @@ -1586,17 +1556,20 @@ pub struct LogicalFlagsMOpImm { pub dest_count: UIntInRangeInclusive<0, { PRegFlags::FLAG_COUNT }>, } -impl MOpImmDebug for LogicalFlagsMOpImm { +impl SimValueDebug for LogicalFlagsMOpImm { #[hdl] - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[hdl(sim)] - let Self { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + type SimValueT = ::SimValue; + let SimValueT:: { src0_start, src1_start, src2_start, dest_start, dest_count, - } = this; + } = value; write!( f, "{{[{dest_start}..][..{dest_count}] <= [{src0_start}..], [{src1_start}..], [{src2_start}..]}}" @@ -1818,7 +1791,7 @@ impl LogicalFlagsMOpImm { src2_start, dest_start, dest_count, - } = this; + } = this.into_sim_value(); Self::flags_operation_impl( src0_start, src1_start, @@ -1993,7 +1966,7 @@ common_mop_struct! { write!(f, "LogicalFlags {common}, {:?}", lut.lut) })] #[mapped( LogicalFlagsMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] /// Operation: /// ``` /// # // set up a bunch of mock types and variables -- they don't necessarily match the real types @@ -2157,7 +2130,7 @@ common_mop_struct! { write!(f, "Logical {alu_common}, {:?}", lut.lut) })] #[mapped( LogicalMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct LogicalMOp { #[common] pub alu_common: AluCommonMOp>, @@ -2348,7 +2321,7 @@ impl ShiftRotateDestLogicOp { } /// immediate values for [`ShiftRotateMOp`]. -#[hdl(cmp_eq)] +#[hdl(cmp_eq, custom_debug(sim))] pub struct ShiftRotateMOpImm { /// taken from `src2` if this is [`HdlNone`] pub shift_rotate_amount: HdlOption>, @@ -2357,15 +2330,18 @@ pub struct ShiftRotateMOpImm { pub dest_logic_op: HdlOption, } -impl MOpImmDebug for ShiftRotateMOpImm { +impl SimValueDebug for ShiftRotateMOpImm { #[hdl] - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[hdl(sim)] - let Self { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + type SimValueT = ::SimValue; + let SimValueT:: { shift_rotate_amount, shift_rotate_right, dest_logic_op, - } = this; + } = value; let shift_op = if **shift_rotate_right { ">>" } else { "<<" }; #[hdl(sim)] match shift_rotate_amount { @@ -2406,7 +2382,7 @@ common_mop_struct! { write!(f, "ShiftRotate {alu_common}, {:?}", ShiftRotateMode::debug_str(mode)) })] #[mapped( ShiftRotateMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct ShiftRotateMOp { #[common] pub alu_common: AluCommonMOp, ShiftRotateMOpImm>, @@ -2496,7 +2472,7 @@ common_mop_struct! { write!(f, "Compare {common}, {}", CompareMode::debug_str(compare_mode)) })] #[mapped( CompareMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct CompareMOp { #[common] pub common: CommonMOp, DestReg, SrcRegWidth, SrcCount, CommonMOpDefaultImm>, @@ -2609,7 +2585,7 @@ common_mop_struct! { maybe_write_comma_flag!(f, is_ret, **is_ret) })] #[mapped( BranchMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] /// `src0` is the value used for reading flags from. /// `src1 + imm + if pc_relative { pc } else { 0 }` is the target address. /// `src2` (if present) is the counter to compare against zero. @@ -2771,23 +2747,6 @@ pub enum ReadSpecialMOpImm { PowerIsaTimeBaseU, } -impl MOpImmDebug for ReadSpecialMOpImm { - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(Self::debug_str(this)) - } -} - -impl ReadSpecialMOpImm { - #[hdl] - fn debug_str(this: &SimValue) -> &'static str { - #[hdl(sim)] - match this { - Self::PowerIsaTimeBase => "PowerIsaTimeBase", - Self::PowerIsaTimeBaseU => "PowerIsaTimeBaseU", - } - } -} - common_mop_struct! { #[debug(#[hdl] |this, f| { #[hdl(sim)] @@ -2798,7 +2757,7 @@ common_mop_struct! { write!(f, "ReadSpecial {common}") })] #[mapped( ReadSpecialMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct ReadSpecialMOp { #[common] pub common: CommonMOp, DestReg, SrcRegWidth, ConstUsize<0>, ReadSpecialMOpImm>, @@ -2832,7 +2791,7 @@ impl ReadSpecialMOp { mop_enum! { #[impl_mop_into = true] - #[hdl] + #[hdl(custom_debug(sim))] pub enum AluBranchMOp { AddSub(AddSubMOp>), AddSubI(AddSubMOp>), @@ -2848,7 +2807,7 @@ mop_enum! { } } -#[hdl] +#[hdl(custom_debug(sim))] pub struct L2RegNum { pub value: UInt<{ MOpRegNum::WIDTH }>, } @@ -2867,14 +2826,14 @@ impl L2RegNum { value: u8::try_from(value).expect("value must fit"), } } - pub fn debug_sim(this: &SimValue) -> impl fmt::Debug { - fmt::from_fn(move |f| write!(f, "l2r{:#x}", Self::value_sim(this))) - } } -impl MOpImmDebug for L2RegNum { - fn mop_imm_debug(this: &SimValue, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&Self::debug_sim(this), f) +impl SimValueDebug for L2RegNum { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + write!(f, "l2r{:#x}", value.value.as_int()) } } @@ -2888,7 +2847,7 @@ common_mop_struct! { write!(f, "ReadL2Reg {common}") })] #[mapped( ReadL2RegMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct ReadL2RegMOp { #[common] pub common: CommonMOp, DestReg, SrcRegWidth, ConstUsize<0>, L2RegNum>, @@ -2930,7 +2889,7 @@ common_mop_struct! { write!(f, "WriteL2Reg {common}") })] #[mapped( WriteL2RegMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct WriteL2RegMOp { #[common] pub common: CommonMOp, DestReg, SrcRegWidth, ConstUsize<1>, L2RegNum>, @@ -2964,7 +2923,7 @@ impl WriteL2RegMOp { mop_enum! { #[impl_mop_into = true] - #[hdl] + #[hdl(custom_debug(sim))] pub enum L2RegisterFileMOp { ReadL2Reg(ReadL2RegMOp), WriteL2Reg(WriteL2RegMOp), @@ -3080,7 +3039,7 @@ common_mop_struct! { write!(f, "Load {load_store_common}") })] #[mapped( LoadMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct LoadMOp { #[common] pub load_store_common: LoadStoreCommonMOp>, @@ -3128,7 +3087,7 @@ common_mop_struct! { write!(f, "Store {load_store_common}") })] #[mapped( StoreMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] /// does `*src0 = convert(src1)` pub struct StoreMOp { #[common] @@ -3169,7 +3128,7 @@ impl StoreMOp { mop_enum! { #[impl_mop_into = true] - #[hdl] + #[hdl(custom_debug(sim))] pub enum LoadStoreMOp { Load(LoadMOp), Store(StoreMOp), @@ -3186,7 +3145,7 @@ common_mop_struct! { write!(f, "MoveReg {common}") })] #[mapped( MoveRegMOp)] - #[hdl(cmp_eq)] + #[hdl(cmp_eq, custom_debug(sim))] pub struct MoveRegMOp { #[common] pub common: CommonMOp, DestReg, SrcRegWidth, ConstUsize<1>, CommonMOpDefaultImm>>, @@ -3236,7 +3195,7 @@ impl MoveRegMOp { } } -#[hdl(cmp_eq, no_static)] +#[hdl(cmp_eq, no_static, custom_debug(sim))] /// there may be more than one unit of a given kind, so UnitNum is not the same as UnitKind. /// zero is used for built-in constants, such as the zero register pub struct UnitNum> { @@ -3244,6 +3203,30 @@ pub struct UnitNum> { pub config: C, } +impl> SimValueDebug for UnitNum { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + if let Some(index) = Self::index_sim(value) { + write!(f, "u{index}") + } else { + f.write_str("uz") + } + } +} + +impl> UnitNum { + pub fn index_sim(expr: &::SimValue) -> Option { + let adj_value = expr.adj_value.cast_to_static::>().as_int(); + if adj_value == 0 { + None + } else { + Some(adj_value as usize - 1) + } + } +} + impl UnitNum { pub fn const_zero(self) -> Expr { self.const_zero_sim().to_expr() @@ -3271,14 +3254,6 @@ impl UnitNum { let expr = expr.to_expr(); expr.ty().from_index(index).adj_value.cmp_eq(expr.adj_value) } - pub fn index_sim(expr: &SimValue) -> Option { - let adj_value = expr.adj_value.cast_to_static::>().as_int(); - if adj_value == 0 { - None - } else { - Some(adj_value as usize - 1) - } - } #[hdl] pub fn as_index( expr: impl ToExpr, @@ -3296,25 +3271,32 @@ impl UnitNum { } unit_index } - pub fn debug_sim(this: &SimValue) -> impl fmt::Debug { - fmt::from_fn(move |f| { - if let Some(index) = Self::index_sim(this) { - write!(f, "u{index}") - } else { - f.write_str("uz") - } - }) - } } pub const CONST_ZERO_UNIT_NUM: usize = 0; -#[hdl(cmp_eq, no_static)] +#[hdl(cmp_eq, no_static, custom_debug(sim))] pub struct UnitOutRegNum> { pub value: UIntType>, pub config: C, } +impl> SimValueDebug for UnitOutRegNum { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + let value = Self::value_sim(value); + write!(f, "or{value:#x}") + } +} + +impl> UnitOutRegNum { + pub fn value_sim(this: &::SimValue) -> usize { + this.value.cast_to_static::>().as_int() as usize + } +} + impl UnitOutRegNum { #[hdl] pub fn new_sim(self, value: usize) -> SimValue { @@ -3324,16 +3306,9 @@ impl UnitOutRegNum { config: self.config, } } - pub fn value_sim(this: &SimValue) -> usize { - this.value.cast_to_static::>().as_int() as usize - } - pub fn debug_sim(this: &SimValue) -> impl fmt::Debug { - let value = Self::value_sim(this); - fmt::from_fn(move |f| write!(f, "or{value:#x}")) - } } -#[hdl(cmp_eq, no_static)] +#[hdl(cmp_eq, no_static, custom_debug(sim))] /// Physical Register Number -- registers in the CPU's backend pub struct PRegNum> { pub unit_num: UnitNum, @@ -3353,27 +3328,20 @@ impl PRegNum { }, } } - #[hdl] - pub fn debug_sim(this: &SimValue) -> impl fmt::Debug { - fmt::from_fn(move |f| { - #[hdl(sim)] - let Self { - unit_num, - unit_out_reg, - } = this; - if let (None, 0) = ( - UnitNum::index_sim(unit_num), - UnitOutRegNum::value_sim(unit_out_reg), - ) { - return f.write_str("pzero"); - } - write!( - f, - "p{:?}_{:?}", - UnitNum::debug_sim(unit_num), - UnitOutRegNum::debug_sim(unit_out_reg), - ) - }) +} + +impl> SimValueDebug for PRegNum { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + if let (None, 0) = ( + UnitNum::index_sim(&value.unit_num), + UnitOutRegNum::value_sim(&value.unit_out_reg), + ) { + return f.write_str("pzero"); + } + write!(f, "p{:?}_{:?}", &value.unit_num, &value.unit_out_reg) } } @@ -3415,7 +3383,7 @@ impl MOpRegNum { Self::CONST_ZERO_REG_NUM + 1..Self::SPECIAL_REG_NUMS.start; } -#[hdl(cmp_eq)] +#[hdl(cmp_eq, custom_debug(sim))] /// all the registers this instruction will write to, they are all renamed to the same physical register. pub struct MOpDestReg { /// some instructions have multiple destination registers, e.g. x86 div @@ -3427,6 +3395,33 @@ pub struct MOpDestReg { pub flag_regs: Array, { range_u32_len(&MOpRegNum::FLAG_REG_NUMS) }>, } +impl SimValueDebug for MOpDestReg { + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + if f.alternate() { + type SimValueT = ::SimValue; + let SimValueT:: { + normal_regs, + flag_regs, + } = value; + f.debug_struct("MOpDestReg") + .field("normal_regs", normal_regs) + .field("flag_regs", flag_regs) + .finish() + } else { + f.debug_set() + .entries( + Self::regs_sim(value) + .into_iter() + .filter(|&v| v != MOpRegNum::CONST_ZERO_REG_NUM), + ) + .finish() + } + } +} + impl MOpDestReg { #[hdl] #[track_caller] @@ -3661,8 +3656,7 @@ impl MOpDestReg { }) } #[hdl] - pub fn regs_sim(this: &SimValue) -> [u32; Self::REG_COUNT] { - let this = this.into_sim_value(); + pub fn regs_sim(this: &::SimValue) -> [u32; Self::REG_COUNT] { std::array::from_fn(|index| match Self::REG_KINDS[index] { MOpDestRegKind::NormalReg { dest_reg_index } => this.normal_regs[dest_reg_index] .value diff --git a/crates/cpu/src/rename_execute_retire.rs b/crates/cpu/src/rename_execute_retire.rs index bc0aefd..fe7b7db 100644 --- a/crates/cpu/src/rename_execute_retire.rs +++ b/crates/cpu/src/rename_execute_retire.rs @@ -10,8 +10,8 @@ use crate::{ CpuConfigRobSize, CpuConfigUnitCount, PhantomConstCpuConfig, TwiceCpuConfigFetchWidth, }, instruction::{ - COMMON_MOP_SRC_LEN, L2RegNum, L2RegisterFileMOp, MOp, MOpDebug, MOpDestReg, MOpRegNum, - MOpTrait, PRegNum, ReadL2RegMOp, UnitNum, UnitOutRegNum, + COMMON_MOP_SRC_LEN, L2RegNum, L2RegisterFileMOp, MOp, MOpDestReg, MOpRegNum, MOpTrait, + PRegNum, ReadL2RegMOp, UnitNum, UnitOutRegNum, }, next_pc::{CallStackOp, SimValueDefault}, register::PRegValue, @@ -22,7 +22,7 @@ use crate::{ use fayalite::{ int::UIntInRangeInclusiveType, prelude::*, - ty::{OpaqueSimValue, StaticType}, + ty::{OpaqueSimValue, SimValueDebug, StaticType}, util::ready_valid::ReadyValid, }; use std::{collections::VecDeque, fmt, mem, num::NonZero}; @@ -33,7 +33,7 @@ pub const MOP_ID_WIDTH: usize = 16; #[hdl] pub type MOpId = UInt<{ MOP_ID_WIDTH }>; -#[hdl] +#[hdl(custom_debug(sim))] /// A µOp along with the state needed for this instance of the µOp. pub struct MOpInstance { pub fetch_block_id: UInt<8>, @@ -50,6 +50,29 @@ pub struct MOpInstance { pub mop: MOp, } +impl SimValueDebug for MOpInstance { + #[hdl] + fn sim_value_debug( + value: &::SimValue, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + #[hdl(sim)] + let Self { + fetch_block_id, + id, + pc, + predicted_next_pc, + size_in_bytes, + is_first_mop_in_insn, + mop, + } = value; + write!( + f, + "fid={fetch_block_id:?} id={id:?} pc={pc:?} pn_pc={predicted_next_pc:?} sz={size_in_bytes:?} first={is_first_mop_in_insn}: {mop:?}" + ) + } +} + #[hdl(no_static)] /// TODO: merge with [`crate::next_pc::PostDecodeOutputInterface`] pub struct PostDecodeOutputInterface> { @@ -233,16 +256,6 @@ impl RenameTableEntry { #[hdl(sim)] self.L1(self.L1.const_zero()) } - #[hdl] - fn debug_sim(this: &SimValue) -> impl fmt::Debug { - fmt::from_fn(move |f| { - #[hdl(sim)] - match this { - Self::L1(v) => write!(f, "L1({:?})", PRegNum::debug_sim(v)), - Self::L2(v) => write!(f, "L2({:?})", L2RegNum::debug_sim(v)), - } - }) - } } /// make arrays dynamically-sized to avoid putting large types on the stack @@ -320,10 +333,7 @@ impl RenameTable { // writing to const zero reg does nothing return; } - println!( - "{rename_table_name}: Write: {unrenamed_reg_num:#x} <- {:?}", - RenameTableEntry::debug_sim(new), - ); + println!("{rename_table_name}: Write: {unrenamed_reg_num:#x} <- {new:?}"); self.entries[*unrenamed_reg_num as usize] = new.clone(); } RenameTableUpdate::UpdateForReadL2Reg { dest, src } => { @@ -336,9 +346,8 @@ impl RenameTable { RenameTableEntry::<_>::L2(l2) => { if L2RegNum::value_sim(l2) == L2RegNum::value_sim(src) { println!( - "{rename_table_name}: UpdateForReadL2Reg: {unrenamed_reg_num:#x} updating from {:?} to {:?}", - RenameTableEntry::debug_sim(&entry), - RenameTableEntry::debug_sim(&new), + "{rename_table_name}: UpdateForReadL2Reg: {unrenamed_reg_num:#x} \ + updating from {entry:?} to {new:?}", ); *entry = new.clone(); } @@ -355,9 +364,8 @@ impl RenameTable { RenameTableEntry::<_>::L1(l1) => { if l1 == src { println!( - "{rename_table_name}: UpdateForWriteL2Reg: {unrenamed_reg_num:#x} updating from {:?} to {:?}", - RenameTableEntry::debug_sim(&entry), - RenameTableEntry::debug_sim(&new), + "{rename_table_name}: UpdateForWriteL2Reg: {unrenamed_reg_num:#x} \ + updating from {entry:?} to {new:?}", ); *entry = new.clone(); } @@ -1018,15 +1026,15 @@ impl RenameExecuteRetireState { } write!( f, - ": {:#x}{}: ", + ": {:#x}{}: {:?}", rob.mop.pc.as_int(), if *rob.mop.is_first_mop_in_insn { "" } else { ".." }, - )?; - MOpDebug::mop_debug(&rob.mop.mop, f) + rob.mop.mop, + ) }) .to_string(); // TODO @@ -1220,10 +1228,7 @@ impl RenameExecuteRetireState { }); let [src_reg] = src_regs; let renamed_reg = self.rename_table.entries[src_reg as usize].clone(); - println!( - "moving from {src_reg:#x} renamed: {:?}", - RenameTableEntry::debug_sim(&renamed_reg), - ); + println!("moving from {src_reg:#x} renamed: {renamed_reg:?}"); let unrenamed_dest_regs = MOpDestReg::regs_sim(MOpTrait::dest_reg_sim_ref(move_reg_mop)); assert!(self.rob.incomplete_back_entry.is_none()); @@ -1321,10 +1326,7 @@ impl RenameExecuteRetireState { CpuConfigPRegNumWidth[self.config], &mut |src_reg, index| { let renamed = &self.rename_table.entries[src_reg.as_int() as usize]; - println!( - "renaming src[{index}] from {src_reg:?} to {:?}", - RenameTableEntry::debug_sim(renamed), - ); + println!("renaming src[{index}] from {src_reg:?} to {renamed:?}"); #[hdl(sim)] match renamed { RenameTableEntry::<_>::L1(v) => v.cast_to_bits(), diff --git a/crates/cpu/src/unit.rs b/crates/cpu/src/unit.rs index e249b38..79f03bf 100644 --- a/crates/cpu/src/unit.rs +++ b/crates/cpu/src/unit.rs @@ -26,7 +26,7 @@ macro_rules! all_units { ( #[hdl_unit_kind = $HdlUnitKind:ident] #[unit_kind = $UnitKind:ident] - #[hdl] + #[hdl(custom_debug(sim))] $(#[$enum_meta:meta])* $vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, #[MOp(get_ty = $transformed_move_op_get_ty:expr)] $TransformedMoveOp:ident: Type> { $( @@ -82,9 +82,8 @@ macro_rules! all_units { } mop_enum! { - #[debug(where $TransformedMoveOp: crate::instruction::MOpDebug)] #[impl_mop_into = false] - #[hdl] + #[hdl(custom_debug(sim))] $(#[$enum_meta])* $vis enum $UnitMOpEnum< $DestReg: Type, @@ -322,7 +321,7 @@ macro_rules! all_units { all_units! { #[hdl_unit_kind = HdlUnitKind] #[unit_kind = UnitKind] - #[hdl] + #[hdl(custom_debug(sim))] pub enum UnitMOp< DestReg: Type, SrcRegWidth: Size, diff --git a/crates/cpu/tests/rename_execute_retire.rs b/crates/cpu/tests/rename_execute_retire.rs index ac21b10..3a02f22 100644 --- a/crates/cpu/tests/rename_execute_retire.rs +++ b/crates/cpu/tests/rename_execute_retire.rs @@ -9,8 +9,8 @@ use cpu::{ instruction::{ AddSubMOp, AluBranchMOp, AluCommonMOp, BranchMOp, COMMON_MOP_SRC_LEN, CommonMOp, CompareMOp, CompareMode, ConditionMode, L2RegisterFileMOp, LoadMOp, LoadStoreCommonMOp, - LoadStoreConversion, LoadStoreMOp, LoadStoreWidth, MOp, MOpDebug, MOpDestReg, MOpRegNum, - MOpTrait, MoveRegMOp, OutputIntegerMode, PRegNum, StoreMOp, UnitNum, + LoadStoreConversion, LoadStoreMOp, LoadStoreWidth, MOp, MOpDestReg, MOpRegNum, MOpTrait, + MoveRegMOp, OutputIntegerMode, PRegNum, StoreMOp, UnitNum, }, next_pc::CallStackOp, register::{PRegFlags, PRegFlagsPowerISA, PRegValue}, @@ -1830,11 +1830,7 @@ impl MockUnitOp { let (output, caused_cancel) = execution_state.run_mop(&self.mop, &self.src_values, self.config); assert!(output.is_some() || caused_cancel.is_some()); - println!( - "try_run: {:#x}: {}", - self.mop.pc.as_int(), - fmt::from_fn(|f| MOpDebug::mop_debug(&self.mop.mop, f)), - ); + println!("try_run: {:#x}: {:?}", self.mop.pc.as_int(), self.mop.mop); println!( "<- {:?}", self.src_values