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