improve debug formatting of MOpRegNum/MOpDestReg
This commit is contained in:
parent
5e6041a97c
commit
559e2967a2
3 changed files with 154713 additions and 106295 deletions
|
|
@ -3288,7 +3288,7 @@ impl<C: Type + PhantomConstGet<CpuConfig>> SimValueDebug for PRegNum<C> {
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq)]
|
||||
#[hdl(cmp_eq, custom_debug(sim))]
|
||||
/// µOp Register Number -- register in a micro-operation before register renaming
|
||||
#[doc(alias = "UOpRegNum")] // help you find it in the docs if you mis-spell it
|
||||
#[doc(alias = "\u{B5}OpRegNum")] // micro sign
|
||||
|
|
@ -3298,6 +3298,22 @@ pub struct MOpRegNum {
|
|||
pub value: UInt<{ MOpRegNum::WIDTH }>,
|
||||
}
|
||||
|
||||
impl SimValueDebug for MOpRegNum {
|
||||
#[hdl]
|
||||
fn sim_value_debug(
|
||||
value: &<Self as Type>::SimValue,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
#[hdl(sim)]
|
||||
let Self { value } = value;
|
||||
f.debug_struct("MOpRegNum").field("value", value).finish()
|
||||
} else {
|
||||
fmt::Debug::fmt(&Self::debug_fmt_num(Self::reg_num_sim(value)), f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MOpRegNum {
|
||||
pub const WIDTH: usize = 8;
|
||||
pub const CONST_ZERO_REG_NUM: u32 = 0;
|
||||
|
|
@ -3332,9 +3348,22 @@ impl MOpRegNum {
|
|||
pub const NORMAL_REG_NUMS: Range<u32> =
|
||||
Self::CONST_ZERO_REG_NUM + 1..Self::SPECIAL_REG_NUMS.start;
|
||||
|
||||
pub fn reg_num_sim(this: &SimValue<Self>) -> u32 {
|
||||
pub fn reg_num_sim(this: &<Self as Type>::SimValue) -> u32 {
|
||||
this.value.cast_to_static::<UInt<32>>().as_int()
|
||||
}
|
||||
pub fn debug_fmt_num(reg_num: u32) -> impl fmt::Debug {
|
||||
fmt::from_fn(move |f| {
|
||||
if reg_num == Self::CONST_ZERO_REG_NUM {
|
||||
f.write_str("rzero")?;
|
||||
} else {
|
||||
write!(f, "r{reg_num:#x}")?;
|
||||
}
|
||||
if let Some(power_isa_reg_name) = Self::POWER_ISA_REG_NAMES[reg_num as usize] {
|
||||
write!(f, "(pwr:{power_isa_reg_name})")?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq, custom_debug(sim))]
|
||||
|
|
@ -3369,7 +3398,8 @@ impl SimValueDebug for MOpDestReg {
|
|||
.entries(
|
||||
Self::regs_sim(value)
|
||||
.into_iter()
|
||||
.filter(|&v| v != MOpRegNum::CONST_ZERO_REG_NUM),
|
||||
.filter(|&v| v != MOpRegNum::CONST_ZERO_REG_NUM)
|
||||
.map(MOpRegNum::debug_fmt_num),
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,89 +25,206 @@ pub struct PowerIsaCrBitNum {
|
|||
pub bit_in_field: UInt<2>,
|
||||
}
|
||||
|
||||
impl MOpRegNum {
|
||||
pub const POWER_ISA_LR_REG_NUM: u32 = 1;
|
||||
#[hdl]
|
||||
pub fn power_isa_lr_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_LR_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
pub const POWER_ISA_CTR_REG_NUM: u32 = 2;
|
||||
#[hdl]
|
||||
pub fn power_isa_ctr_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_CTR_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
|
||||
#[hdl]
|
||||
pub fn power_isa_tar_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_TAR_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
macro_rules! suffix_str_with_0_to_31 {
|
||||
($str:literal) => {
|
||||
suffix_str_with_0_to_31!(
|
||||
$str,
|
||||
[
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
]
|
||||
)
|
||||
};
|
||||
($str:literal, [$($num:literal),* $(,)?]) => {
|
||||
[$(concat!($str, $num)),*]
|
||||
};
|
||||
}
|
||||
|
||||
const fn fill_names_range<'a>(dest: &mut [Option<&'a str>], range: Range<u32>, src: &[&'a str]) {
|
||||
assert!((range.end - range.start) as usize == src.len());
|
||||
let mut i = 0;
|
||||
while i < src.len() {
|
||||
dest[i + range.start as usize] = Some(src[i]);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! power_isa_regs {
|
||||
(
|
||||
$(
|
||||
#[name_str = $name_str:literal, expr_fn = $expr_fn:ident, sim_fn = $sim_fn:ident]
|
||||
$(#[doc = $($doc:tt)*])*
|
||||
pub const $REG_NUM:ident: u32 = $reg_num_expr:expr;
|
||||
)*
|
||||
$(
|
||||
#[names_fn = |$names_var:ident| $names_body:expr $(,
|
||||
reg_num_fn = $reg_num_fn_multi:ident,
|
||||
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
|
||||
expr_imm_fn = $expr_imm_fn_multi:ident,
|
||||
sim_fn = $sim_fn_multi:ident,)?
|
||||
]
|
||||
$(#[doc = $($doc_multi:tt)*])*
|
||||
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||
)*
|
||||
) => {
|
||||
impl MOpRegNum {
|
||||
pub const POWER_ISA_REG_NAMES: &[Option<&str>; 1 << Self::WIDTH] = &{
|
||||
let mut retval = [None; _];
|
||||
$(retval[Self::$REG_NUM as usize] = Some($name_str);)*
|
||||
$({
|
||||
let $names_var = &mut retval;
|
||||
$names_body
|
||||
})*
|
||||
retval
|
||||
};
|
||||
$(
|
||||
$(#[doc = $($doc)*])*
|
||||
pub const $REG_NUM: u32 = $reg_num_expr;
|
||||
$(#[doc = $($doc)*])*
|
||||
#[hdl]
|
||||
pub fn $expr_fn() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
$(#[doc = $($doc)*])*
|
||||
#[hdl]
|
||||
pub fn $sim_fn() -> SimValue<Self> {
|
||||
#[hdl(sim)]
|
||||
Self {
|
||||
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
)*
|
||||
$(
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
|
||||
power_isa_regs! {
|
||||
@helper_fns
|
||||
#[names_fn = |$names_var| $names_body $(,
|
||||
reg_num_fn = $reg_num_fn_multi,
|
||||
expr_fn = $expr_fn_multi($fn_multi_arg),
|
||||
expr_imm_fn = $expr_imm_fn_multi,
|
||||
sim_fn = $sim_fn_multi,)?
|
||||
]
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
(
|
||||
@helper_fns
|
||||
#[names_fn = |$names_var:ident| $names_body:expr]
|
||||
$(#[doc = $($doc_multi:tt)*])*
|
||||
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||
) => {};
|
||||
(
|
||||
@helper_fns
|
||||
#[
|
||||
names_fn = |$names_var:ident| $names_body:expr,
|
||||
reg_num_fn = $reg_num_fn_multi:ident,
|
||||
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
|
||||
expr_imm_fn = $expr_imm_fn_multi:ident,
|
||||
sim_fn = $sim_fn_multi:ident,
|
||||
]
|
||||
$(#[doc = $($doc_multi:tt)*])*
|
||||
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
|
||||
) => {
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
pub const fn $reg_num_fn_multi(index: usize) -> u32 {
|
||||
range_u32_nth_or_panic(&Self::$REG_NUM_MULTI, index)
|
||||
}
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
#[hdl]
|
||||
pub fn $expr_fn_multi(input: Expr<$fn_multi_arg>) -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: (Self::$REG_NUM_MULTI.start + input).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
#[hdl]
|
||||
pub fn $expr_imm_fn_multi(input: usize) -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::$reg_num_fn_multi(input).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
$(#[doc = $($doc_multi)*])*
|
||||
#[hdl]
|
||||
pub fn $sim_fn_multi(reg_num: &SimValue<$fn_multi_arg>) -> SimValue<Self> {
|
||||
#[hdl(sim)]
|
||||
Self {
|
||||
value: (Self::$REG_NUM_MULTI.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
power_isa_regs! {
|
||||
#[name_str = "lr", expr_fn = power_isa_lr_reg, sim_fn = power_isa_lr_reg_sim]
|
||||
pub const POWER_ISA_LR_REG_NUM: u32 = 1;
|
||||
#[name_str = "ctr", expr_fn = power_isa_ctr_reg, sim_fn = power_isa_ctr_reg_sim]
|
||||
pub const POWER_ISA_CTR_REG_NUM: u32 = 2;
|
||||
#[name_str = "tar", expr_fn = power_isa_tar_reg, sim_fn = power_isa_tar_reg_sim]
|
||||
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
|
||||
|
||||
#[name_str = "xer[so,ov,ov32]", expr_fn = power_isa_xer_so_ov_ov32_reg, sim_fn = power_isa_xer_so_ov_ov32_reg_sim]
|
||||
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
pub const POWER_ISA_XER_SO_OV_OV32_REG_NUM: u32 =
|
||||
range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 0);
|
||||
|
||||
#[name_str = "xer[ca,ca32]", expr_fn = power_isa_xer_ca_ca32_reg, sim_fn = power_isa_xer_ca_ca32_reg_sim]
|
||||
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
pub const POWER_ISA_XER_CA_CA32_REG_NUM: u32 = 4;
|
||||
|
||||
#[name_str = "xer[other]", expr_fn = power_isa_xer_other_reg, sim_fn = power_isa_xer_other_reg_sim]
|
||||
/// only the XER bits that don't exist in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
pub const POWER_ISA_XER_OTHER_REG_NUM: u32 = 5;
|
||||
|
||||
#[name_str = "temp", expr_fn = power_isa_temp_reg, sim_fn = power_isa_temp_reg_sim]
|
||||
/// used as a temporary for things like computing the effective address before loading/storing memory
|
||||
pub const POWER_ISA_TEMP_REG_NUM: u32 = 8;
|
||||
#[hdl]
|
||||
pub fn power_isa_temp_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_TEMP_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
#[hdl]
|
||||
pub fn power_isa_xer_so_ov_ov32_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_XER_SO_OV_OV32_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
#[hdl]
|
||||
pub fn power_isa_xer_ca_ca32_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_XER_CA_CA32_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
/// only the XER bits that don't exist in [`PRegValue.flags`]
|
||||
///
|
||||
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
|
||||
#[hdl]
|
||||
pub fn power_isa_xer_other_reg() -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::POWER_ISA_XER_OTHER_REG_NUM.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
#[name_str = "cr0", expr_fn = power_isa_cr_0_reg, sim_fn = power_isa_cr_0_reg_sim]
|
||||
pub const POWER_ISA_CR_0_REG_NUM: u32 = range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 1);
|
||||
#[names_fn = |names| {
|
||||
fill_names_range(names, Self::POWER_ISA_CR_1_THRU_7_REG_NUMS, &["cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7"]);
|
||||
}]
|
||||
pub const POWER_ISA_CR_1_THRU_7_REG_NUMS: Range<u32> = 9..16;
|
||||
|
||||
#[
|
||||
names_fn = |names| {
|
||||
fill_names_range(names, Self::POWER_ISA_GPR_REG_NUMS, &suffix_str_with_0_to_31!("r"));
|
||||
},
|
||||
reg_num_fn = power_isa_gpr_reg_num,
|
||||
expr_fn = power_isa_gpr_reg(UInt<5>),
|
||||
expr_imm_fn = power_isa_gpr_reg_imm,
|
||||
sim_fn = power_isa_gpr_reg_sim,
|
||||
]
|
||||
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
|
||||
|
||||
#[
|
||||
names_fn = |names| {
|
||||
fill_names_range(names, Self::POWER_ISA_FPR_REG_NUMS, &suffix_str_with_0_to_31!("f"));
|
||||
},
|
||||
reg_num_fn = power_isa_fpr_reg_num,
|
||||
expr_fn = power_isa_fpr_reg(UInt<5>),
|
||||
expr_imm_fn = power_isa_fpr_reg_imm,
|
||||
sim_fn = power_isa_fpr_reg_sim,
|
||||
]
|
||||
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
|
||||
}
|
||||
|
||||
impl MOpRegNum {
|
||||
pub const fn power_isa_cr_reg_num(index: usize) -> u32 {
|
||||
if index == 0 {
|
||||
Self::POWER_ISA_CR_0_REG_NUM
|
||||
|
|
@ -148,31 +265,6 @@ impl MOpRegNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
|
||||
pub const fn power_isa_gpr_reg_num(index: usize) -> u32 {
|
||||
range_u32_nth_or_panic(&Self::POWER_ISA_GPR_REG_NUMS, index)
|
||||
}
|
||||
#[hdl]
|
||||
pub fn power_isa_gpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
pub fn power_isa_gpr_reg_imm(index: usize) -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: Self::power_isa_gpr_reg_num(index).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
pub fn power_isa_gpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
||||
#[hdl(sim)]
|
||||
Self {
|
||||
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
pub const fn power_isa_gpr_or_zero_reg_num(index: usize) -> u32 {
|
||||
if index == 0 {
|
||||
Self::CONST_ZERO_REG_NUM
|
||||
|
|
@ -208,25 +300,6 @@ impl MOpRegNum {
|
|||
.cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
|
||||
pub const fn power_isa_fpr_reg_num(index: usize) -> u32 {
|
||||
range_u32_nth_or_panic(&Self::POWER_ISA_FPR_REG_NUMS, index)
|
||||
}
|
||||
#[hdl]
|
||||
pub fn power_isa_fpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
|
||||
#[hdl]
|
||||
Self {
|
||||
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
pub fn power_isa_fpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
|
||||
#[hdl(sim)]
|
||||
Self {
|
||||
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq)]
|
||||
|
|
|
|||
260685
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
260685
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue