UnitMOp now has L2RegisterFileMOp after renaming and instead has MoveRegMOp before renaming
This commit is contained in:
		
							parent
							
								
									6c91d1b0b0
								
							
						
					
					
						commit
						518284685f
					
				
					 6 changed files with 33960 additions and 32521 deletions
				
			
		|  | @ -1,10 +1,10 @@ | ||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later
 | // SPDX-License-Identifier: LGPL-3.0-or-later
 | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     instruction::{MOpTrait, PRegNum, UnitNum, UnitOutRegNum, CONST_ZERO_UNIT_NUM}, |     instruction::{MOpTrait, PRegNum, RenamedMOp, UnitNum, UnitOutRegNum, CONST_ZERO_UNIT_NUM}, | ||||||
|     unit::{ |     unit::{ | ||||||
|         unit_base::{UnitForwardingInfo, UnitToRegAlloc}, |         unit_base::{UnitForwardingInfo, UnitToRegAlloc}, | ||||||
|         UnitCancelInput, UnitKind, UnitMOp, UnitOutputWrite, |         UnitCancelInput, UnitKind, UnitOutputWrite, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| use fayalite::prelude::*; | use fayalite::prelude::*; | ||||||
|  | @ -79,8 +79,8 @@ impl CpuConfig { | ||||||
|     pub fn p_reg_num_width(&self) -> usize { |     pub fn p_reg_num_width(&self) -> usize { | ||||||
|         self.unit_num_width() + self.out_reg_num_width |         self.unit_num_width() + self.out_reg_num_width | ||||||
|     } |     } | ||||||
|     pub fn unit_mop_in_unit(&self) -> UnitMOp<UnitOutRegNum<DynSize>, DynSize> { |     pub fn renamed_mop_in_unit(&self) -> RenamedMOp<UnitOutRegNum<DynSize>, DynSize> { | ||||||
|         UnitMOp[self.unit_out_reg_num()][self.p_reg_num_width()] |         RenamedMOp[self.unit_out_reg_num()][self.p_reg_num_width()] | ||||||
|     } |     } | ||||||
|     pub fn unit_output_write(&self) -> UnitOutputWrite<DynSize> { |     pub fn unit_output_write(&self) -> UnitOutputWrite<DynSize> { | ||||||
|         UnitOutputWrite[self.out_reg_num_width] |         UnitOutputWrite[self.out_reg_num_width] | ||||||
|  |  | ||||||
|  | @ -25,7 +25,10 @@ impl<T: MOpTrait> MOpInto<T> for T { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub trait MOpTrait: Type { | pub trait MOpTrait: Type { | ||||||
|     type Mapped<NewDestReg: Type, NewSrcRegWidth: Size>: MOpTrait; |     type Mapped<NewDestReg: Type, NewSrcRegWidth: Size>: MOpTrait< | ||||||
|  |         DestReg = NewDestReg, | ||||||
|  |         SrcRegWidth = NewSrcRegWidth, | ||||||
|  |     >; | ||||||
|     type DestReg: Type; |     type DestReg: Type; | ||||||
|     type SrcRegWidth: Size; |     type SrcRegWidth: Size; | ||||||
|     fn dest_reg_ty(self) -> Self::DestReg; |     fn dest_reg_ty(self) -> Self::DestReg; | ||||||
|  | @ -69,7 +72,12 @@ pub trait MOpTrait: Type { | ||||||
| pub trait CommonMOpTrait: MOpTrait { | pub trait CommonMOpTrait: MOpTrait { | ||||||
|     type PrefixPad: KnownSize; |     type PrefixPad: KnownSize; | ||||||
|     type SrcCount: KnownSize; |     type SrcCount: KnownSize; | ||||||
|     type CommonMOpTraitMapped<NewDestReg: Type, NewSrcRegWidth: Size>: CommonMOpTrait; |     type CommonMOpTraitMapped<NewDestReg: Type, NewSrcRegWidth: Size>: CommonMOpTrait< | ||||||
|  |         DestReg = NewDestReg, | ||||||
|  |         SrcRegWidth = NewSrcRegWidth, | ||||||
|  |         PrefixPad = Self::PrefixPad, | ||||||
|  |         SrcCount = Self::SrcCount, | ||||||
|  |     >; | ||||||
|     type CommonMOpTraitDestReg: Type; |     type CommonMOpTraitDestReg: Type; | ||||||
|     type CommonMOpTraitSrcRegWidth: Size; |     type CommonMOpTraitSrcRegWidth: Size; | ||||||
|     fn common_mop_ty( |     fn common_mop_ty( | ||||||
|  | @ -418,9 +426,15 @@ macro_rules! common_mop_struct { | ||||||
| 
 | 
 | ||||||
| macro_rules! mop_enum { | macro_rules! mop_enum { | ||||||
|     ( |     ( | ||||||
|  |         #[impl_mop_into = $impl_mop_into:tt] | ||||||
|         $(#[$enum_meta:meta])* |         $(#[$enum_meta:meta])* | ||||||
|         $vis:vis enum $MOp:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size> { |         $vis:vis enum $MOp:ident< | ||||||
|             $(#[$first_variant_meta:meta])* |             $DestReg:ident: Type, | ||||||
|  |             $SrcRegWidth:ident: Size | ||||||
|  |             $(, #[MOp(get_ty = $mop_types_get_ty:expr)] $MOpTypes:ident: Type)* | ||||||
|  |             $(, #[Size(get_size = $sizes_get_size:expr)] $Sizes:ident: Size)* | ||||||
|  |         > { | ||||||
|  |             $(#[$($first_variant_meta:tt)*])* | ||||||
|             $FirstVariant:ident($first_ty:ty), |             $FirstVariant:ident($first_ty:ty), | ||||||
|             $( |             $( | ||||||
|                 $(#[$variant_meta:meta])* |                 $(#[$variant_meta:meta])* | ||||||
|  | @ -429,7 +443,7 @@ macro_rules! mop_enum { | ||||||
|         } |         } | ||||||
|     ) => { |     ) => { | ||||||
|         $(#[$enum_meta])* |         $(#[$enum_meta])* | ||||||
|         $vis enum $MOp<$DestReg: Type, $SrcRegWidth: Size> { |         $vis enum $MOp<$DestReg: Type, $SrcRegWidth: Size $(, $MOpTypes: Type)* $(, $Sizes: Size)*> { | ||||||
|             $(#[$first_variant_meta])* |             $(#[$first_variant_meta])* | ||||||
|             $FirstVariant($first_ty), |             $FirstVariant($first_ty), | ||||||
|             $( |             $( | ||||||
|  | @ -438,32 +452,37 @@ macro_rules! mop_enum { | ||||||
|             )* |             )* | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         impl<$DestReg: Type, $SrcRegWidth: Size, Target: MOpTrait> MOpInto<Target> for $first_ty |         mop_enum! { | ||||||
|         where |             @impl_variants | ||||||
|             $MOp<$DestReg, $SrcRegWidth>: MOpInto<Target> |             #[impl_mop_into = $impl_mop_into] | ||||||
|         { |             enum $MOp [ | ||||||
|             fn mop_into_ty(self) -> Target { |                 $DestReg: Type, | ||||||
|                 MOpInto::mop_into_ty($MOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]) |                 $SrcRegWidth: Size | ||||||
|             } |                 $(, #[MOp(get_ty = $mop_types_get_ty)] $MOpTypes: Type)* | ||||||
|             fn mop_into(this: Expr<Self>) -> Expr<Target> { |                 $(, #[Size(get_size = $sizes_get_size)] $Sizes: Size)* | ||||||
|                 MOpInto::mop_into(MOpInto::<$MOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$FirstVariant(this)) |             ] { | ||||||
|  |                 $FirstVariant($first_ty), | ||||||
|  |                 $($Variant($ty),)* | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $(impl<$DestReg: Type, $SrcRegWidth: Size, Target: MOpTrait> MOpInto<Target> for $ty |         impl< | ||||||
|         where |             $DestReg: Type, | ||||||
|             $MOp<$DestReg, $SrcRegWidth>: MOpInto<Target> |             $SrcRegWidth: Size, | ||||||
|         { |             $($MOpTypes: Type + MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,)* | ||||||
|             fn mop_into_ty(self) -> Target { |             $($Sizes: Size,)* | ||||||
|                 MOpInto::mop_into_ty($MOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]) |         > MOpTrait for $MOp< | ||||||
|             } |             $DestReg, | ||||||
|             fn mop_into(this: Expr<Self>) -> Expr<Target> { |             $SrcRegWidth, | ||||||
|                 MOpInto::mop_into(MOpInto::<$MOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$Variant(this)) |             $($MOpTypes,)* | ||||||
|             } |             $($Sizes,)* | ||||||
|         })* |         > { | ||||||
| 
 |             type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp< | ||||||
|         impl<$DestReg: Type, $SrcRegWidth: Size> MOpTrait for $MOp<$DestReg, $SrcRegWidth> { |                 NewDestReg, | ||||||
|             type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp<NewDestReg, NewSrcRegWidth>; |                 NewSrcRegWidth, | ||||||
|  |                 $(<$MOpTypes as MOpTrait>::Mapped<NewDestReg, NewSrcRegWidth>,)* | ||||||
|  |                 $($Sizes,)* | ||||||
|  |             >; | ||||||
|             type DestReg = $DestReg; |             type DestReg = $DestReg; | ||||||
|             type SrcRegWidth = $SrcRegWidth; |             type SrcRegWidth = $SrcRegWidth; | ||||||
|             fn dest_reg_ty(self) -> Self::DestReg { |             fn dest_reg_ty(self) -> Self::DestReg { | ||||||
|  | @ -476,8 +495,8 @@ macro_rules! mop_enum { | ||||||
|                 let dest_reg = wire(Expr::ty(input).dest_reg_ty()); |                 let dest_reg = wire(Expr::ty(input).dest_reg_ty()); | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 match input { |                 match input { | ||||||
|                     $MOp::<_, _>::$FirstVariant(v) => connect(dest_reg, MOpTrait::dest_reg(v)), |                     Self::$FirstVariant(v) => connect(dest_reg, <$first_ty as MOpTrait>::dest_reg(v)), | ||||||
|                     $($MOp::<_, _>::$Variant(v) => connect(dest_reg, MOpTrait::dest_reg(v)),)* |                     $(Self::$Variant(v) => connect(dest_reg, <$ty as MOpTrait>::dest_reg(v)),)* | ||||||
|                 } |                 } | ||||||
|                 dest_reg |                 dest_reg | ||||||
|             } |             } | ||||||
|  | @ -491,8 +510,8 @@ macro_rules! mop_enum { | ||||||
|             ) { |             ) { | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 match input { |                 match input { | ||||||
|                     $MOp::<_, _>::$FirstVariant(v) => MOpTrait::for_each_src_reg(v, f), |                     Self::$FirstVariant(v) => MOpTrait::for_each_src_reg(v, f), | ||||||
|                     $($MOp::<_, _>::$Variant(v) => MOpTrait::for_each_src_reg(v, f),)* |                     $(Self::$Variant(v) => MOpTrait::for_each_src_reg(v, f),)* | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             fn mapped_ty<NewDestReg: Type, NewSrcRegWidth: Size>( |             fn mapped_ty<NewDestReg: Type, NewSrcRegWidth: Size>( | ||||||
|  | @ -500,7 +519,7 @@ macro_rules! mop_enum { | ||||||
|                 new_dest_reg: NewDestReg, |                 new_dest_reg: NewDestReg, | ||||||
|                 new_src_reg_width: NewSrcRegWidth::SizeType, |                 new_src_reg_width: NewSrcRegWidth::SizeType, | ||||||
|             ) -> Self::Mapped<NewDestReg, NewSrcRegWidth> { |             ) -> Self::Mapped<NewDestReg, NewSrcRegWidth> { | ||||||
|                 $MOp[new_dest_reg][new_src_reg_width] |                 $MOp[new_dest_reg][new_src_reg_width]$([$mop_types_get_ty(self, new_dest_reg, new_src_reg_width)])*$([$sizes_get_size(self)])* | ||||||
|             } |             } | ||||||
|             #[hdl] |             #[hdl] | ||||||
|             fn map_regs<NewDestReg: Type, NewSrcRegWidth: Size>( |             fn map_regs<NewDestReg: Type, NewSrcRegWidth: Size>( | ||||||
|  | @ -519,13 +538,52 @@ macro_rules! mop_enum { | ||||||
|                 let mapped_regs = wire(mapped_ty); |                 let mapped_regs = wire(mapped_ty); | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 match input { |                 match input { | ||||||
|                     $MOp::<_, _>::$FirstVariant(v) => connect(mapped_regs, mapped_ty.$FirstVariant(MOpTrait::map_regs(v, new_dest, new_src_reg_width, map_src))), |                     Self::$FirstVariant(v) => connect(mapped_regs, mapped_ty.$FirstVariant(MOpTrait::map_regs(v, new_dest, new_src_reg_width, map_src))), | ||||||
|                     $($MOp::<_, _>::$Variant(v) => connect(mapped_regs, mapped_ty.$Variant(MOpTrait::map_regs(v, new_dest, new_src_reg_width, map_src))),)* |                     $(Self::$Variant(v) => connect(mapped_regs, mapped_ty.$Variant(MOpTrait::map_regs(v, new_dest, new_src_reg_width, map_src))),)* | ||||||
|                 } |                 } | ||||||
|                 mapped_regs |                 mapped_regs | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |     ( | ||||||
|  |         @impl_variants | ||||||
|  |         #[impl_mop_into = true] | ||||||
|  |         enum $MOp:ident $generics:tt { | ||||||
|  |             $($Variant:ident($ty:ty),)+ | ||||||
|  |         } | ||||||
|  |     ) => { | ||||||
|  |         $(mop_enum! { | ||||||
|  |             @impl_variant | ||||||
|  |             enum $MOp $generics { | ||||||
|  |                 $Variant($ty), | ||||||
|  |             } | ||||||
|  |         })+ | ||||||
|  |     }; | ||||||
|  |     ( | ||||||
|  |         @impl_variants | ||||||
|  |         #[impl_mop_into = false] | ||||||
|  |         enum $MOp:ident $generics:tt { | ||||||
|  |             $($Variant:ident($ty:ty),)+ | ||||||
|  |         } | ||||||
|  |     ) => {}; | ||||||
|  |     ( | ||||||
|  |         @impl_variant | ||||||
|  |         enum $MOp:ident[$DestReg:ident: Type, $SrcRegWidth:ident: Size $(, #[Size(get_size = $sizes_get_size:expr)] $Sizes:ident: Size)*] { | ||||||
|  |             $Variant:ident($ty:ty), | ||||||
|  |         } | ||||||
|  |     ) => { | ||||||
|  |         impl<$DestReg: Type, $SrcRegWidth: Size, Target: MOpTrait, $($Sizes: Size,)*> MOpInto<Target> for $ty | ||||||
|  |         where | ||||||
|  |             $MOp<$DestReg, $SrcRegWidth, $($Sizes,)*>: MOpInto<Target> | ||||||
|  |         { | ||||||
|  |             fn mop_into_ty(self) -> Target { | ||||||
|  |                 MOpInto::mop_into_ty($MOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]$([$sizes_get_size(self)])*) | ||||||
|  |             } | ||||||
|  |             fn mop_into(this: Expr<Self>) -> Expr<Target> { | ||||||
|  |                 MOpInto::mop_into(MOpInto::<$MOp<$DestReg, $SrcRegWidth, $($Sizes,)*>>::mop_into_ty(Expr::ty(this)).$Variant(this)) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(crate) use mop_enum; | pub(crate) use mop_enum; | ||||||
|  | @ -666,6 +724,7 @@ common_mop_struct! { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mop_enum! { | mop_enum! { | ||||||
|  |     #[impl_mop_into = true] | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     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>>), | ||||||
|  | @ -693,6 +752,7 @@ common_mop_struct! { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mop_enum! { | mop_enum! { | ||||||
|  |     #[impl_mop_into = true] | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     pub enum L2RegisterFileMOp<DestReg: Type, SrcRegWidth: Size> { |     pub enum L2RegisterFileMOp<DestReg: Type, SrcRegWidth: Size> { | ||||||
|         ReadL2Reg(ReadL2RegMOp<DestReg, SrcRegWidth>), |         ReadL2Reg(ReadL2RegMOp<DestReg, SrcRegWidth>), | ||||||
|  | @ -728,6 +788,7 @@ common_mop_struct! { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| mop_enum! { | mop_enum! { | ||||||
|  |     #[impl_mop_into = true] | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     pub enum LoadStoreMOp<DestReg: Type, SrcRegWidth: Size> { |     pub enum LoadStoreMOp<DestReg: Type, SrcRegWidth: Size> { | ||||||
|         Load(CommonMOp<ConstUsize<1>, DestReg, SrcRegWidth, ConstUsize<0>>), |         Load(CommonMOp<ConstUsize<1>, DestReg, SrcRegWidth, ConstUsize<0>>), | ||||||
|  | @ -735,6 +796,15 @@ mop_enum! { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | common_mop_struct! { | ||||||
|  |     #[mapped(<NewDestReg, NewSrcRegWidth> MoveRegMOp<NewDestReg, NewSrcRegWidth>)] | ||||||
|  |     #[hdl(cmp_eq)] | ||||||
|  |     pub struct MoveRegMOp<DestReg: Type, SrcRegWidth: Size> { | ||||||
|  |         #[common] | ||||||
|  |         pub common: CommonMOp<ConstUsize<2>, DestReg, SrcRegWidth, ConstUsize<1>>, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[hdl(cmp_eq)] | #[hdl(cmp_eq)] | ||||||
| /// 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
 | ||||||
|  | @ -1014,4 +1084,12 @@ impl MOpDestReg { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[hdl] | #[hdl] | ||||||
| pub type MOp = UnitMOp<MOpDestReg, ConstUsize<{ MOpRegNum::WIDTH }>>; | pub type MOp = UnitMOp< | ||||||
|  |     MOpDestReg, | ||||||
|  |     ConstUsize<{ MOpRegNum::WIDTH }>, | ||||||
|  |     MoveRegMOp<MOpDestReg, ConstUsize<{ MOpRegNum::WIDTH }>>, | ||||||
|  | >; | ||||||
|  | 
 | ||||||
|  | #[hdl] | ||||||
|  | pub type RenamedMOp<DestReg: Type, SrcRegWidth: Size> = | ||||||
|  |     UnitMOp<DestReg, SrcRegWidth, L2RegisterFileMOp<DestReg, SrcRegWidth>>; | ||||||
|  |  | ||||||
|  | @ -3,13 +3,13 @@ | ||||||
| use crate::{ | use crate::{ | ||||||
|     config::CpuConfig, |     config::CpuConfig, | ||||||
|     instruction::{ |     instruction::{ | ||||||
|         MOp, MOpDestReg, MOpRegNum, MOpTrait, PRegNum, RenameTableName, UnitOutRegNum, |         MOp, MOpDestReg, MOpRegNum, MOpTrait, MoveRegMOp, PRegNum, RenameTableName, UnitOutRegNum, | ||||||
|         COMMON_MOP_SRC_LEN, |         COMMON_MOP_SRC_LEN, | ||||||
|     }, |     }, | ||||||
|     unit::{ |     unit::{ | ||||||
|         unit_base::{UnitForwardingInfo, UnitInput}, |         unit_base::{UnitForwardingInfo, UnitInput}, | ||||||
|         GlobalState, TrapData, UnitOutput, UnitOutputWrite, UnitResult, UnitResultCompleted, |         GlobalState, TrapData, UnitMOp, UnitOutput, UnitOutputWrite, UnitResult, | ||||||
|         UnitTrait, |         UnitResultCompleted, UnitTrait, | ||||||
|     }, |     }, | ||||||
|     util::tree_reduce::tree_reduce_with_state, |     util::tree_reduce::tree_reduce_with_state, | ||||||
| }; | }; | ||||||
|  | @ -234,7 +234,7 @@ pub fn reg_alloc(config: &CpuConfig) { | ||||||
|         wire(Array[HdlOption[UInt[config.unit_num_width()]]][config.fetch_width.get()]); |         wire(Array[HdlOption[UInt[config.unit_num_width()]]][config.fetch_width.get()]); | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     let renamed_mops = |     let renamed_mops = | ||||||
|         wire(Array[HdlOption[UnitInput[config.unit_mop_in_unit()]]][config.fetch_width.get()]); |         wire(Array[HdlOption[UnitInput[config.renamed_mop_in_unit()]]][config.fetch_width.get()]); | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     let renamed_mops_out_reg = wire(Array[HdlOption[config.p_reg_num()]][config.fetch_width.get()]); |     let renamed_mops_out_reg = wire(Array[HdlOption[config.p_reg_num()]][config.fetch_width.get()]); | ||||||
|     for fetch_index in 0..config.fetch_width.get() { |     for fetch_index in 0..config.fetch_width.get() { | ||||||
|  | @ -358,27 +358,35 @@ pub fn reg_alloc(config: &CpuConfig) { | ||||||
|             #[hdl] |             #[hdl] | ||||||
|             if let HdlSome(renamed_mop_out_reg) = renamed_mops_out_reg[fetch_index] { |             if let HdlSome(renamed_mop_out_reg) = renamed_mops_out_reg[fetch_index] { | ||||||
|                 let dest_reg = MOpTrait::dest_reg(decoded_insn.mop); |                 let dest_reg = MOpTrait::dest_reg(decoded_insn.mop); | ||||||
|                 connect( |                 let renamed_mop = UnitMOp::try_with_transformed_move_op( | ||||||
|                     renamed_mops[fetch_index], |                     MOpTrait::map_regs( | ||||||
|                     HdlSome( |                         decoded_insn.mop, | ||||||
|                         #[hdl] |                         renamed_mop_out_reg.unit_out_reg, | ||||||
|                         UnitInput::<_> { |                         config.p_reg_num_width(), | ||||||
|                             mop: MOpTrait::map_regs( |                         &mut |src_reg, src_index| { | ||||||
|                                 decoded_insn.mop, |                             connect( | ||||||
|                                 renamed_mop_out_reg.unit_out_reg, |                                 rename_table_read_ports[src_index].addr, | ||||||
|                                 config.p_reg_num_width(), |                                 #[hdl] | ||||||
|                                 &mut |src_reg, src_index| { |                                 MOpRegNum { value: src_reg }, | ||||||
|                                     connect( |                             ); | ||||||
|                                         rename_table_read_ports[src_index].addr, |                             rename_table_read_ports[src_index].data.cast_to_bits() | ||||||
|                                         #[hdl] |  | ||||||
|                                         MOpRegNum { value: src_reg }, |  | ||||||
|                                     ); |  | ||||||
|                                     rename_table_read_ports[src_index].data.cast_to_bits() |  | ||||||
|                                 }, |  | ||||||
|                             ), |  | ||||||
|                             pc: decoded_insn.pc, |  | ||||||
|                         }, |                         }, | ||||||
|                     ), |                     ), | ||||||
|  |                     config.renamed_mop_in_unit().TransformedMove, | ||||||
|  |                     |renamed_mop, renamed_move_op: Expr<MoveRegMOp<_, _>>| { | ||||||
|  |                         // TODO: finish handling MoveRegMOp
 | ||||||
|  |                         connect(renamed_mop, Expr::ty(renamed_mop).HdlNone()); | ||||||
|  |                     }, | ||||||
|  |                 ); | ||||||
|  |                 connect( | ||||||
|  |                     renamed_mops[fetch_index], | ||||||
|  |                     HdlOption::map(renamed_mop, |mop| { | ||||||
|  |                         #[hdl] | ||||||
|  |                         UnitInput::<_> { | ||||||
|  |                             mop, | ||||||
|  |                             pc: decoded_insn.pc, | ||||||
|  |                         } | ||||||
|  |                     }), | ||||||
|                 ); |                 ); | ||||||
|                 for (reg, reg_kind) in MOpDestReg::regs(dest_reg) |                 for (reg, reg_kind) in MOpDestReg::regs(dest_reg) | ||||||
|                     .into_iter() |                     .into_iter() | ||||||
|  |  | ||||||
|  | @ -4,7 +4,8 @@ | ||||||
| use crate::{ | use crate::{ | ||||||
|     config::CpuConfig, |     config::CpuConfig, | ||||||
|     instruction::{ |     instruction::{ | ||||||
|         mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpInto, MOpTrait, UnitOutRegNum, |         mop_enum, AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait, | ||||||
|  |         RenamedMOp, UnitOutRegNum, | ||||||
|     }, |     }, | ||||||
|     register::{FlagsMode, PRegValue}, |     register::{FlagsMode, PRegValue}, | ||||||
|     unit::unit_base::UnitToRegAlloc, |     unit::unit_base::UnitToRegAlloc, | ||||||
|  | @ -24,8 +25,9 @@ macro_rules! all_units { | ||||||
|         #[unit_kind = $UnitKind:ident] |         #[unit_kind = $UnitKind:ident] | ||||||
|         #[hdl] |         #[hdl] | ||||||
|         $(#[$enum_meta:meta])* |         $(#[$enum_meta:meta])* | ||||||
|         $vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size> { |         $vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, #[MOp(get_ty = $transformed_move_op_get_ty:expr)] $TransformedMoveOp:ident: Type> { | ||||||
|             $( |             $( | ||||||
|  |                 $(#[transformed_move $($transformed_move:tt)*])? | ||||||
|                 #[create_dyn_unit_fn = $create_dyn_unit_fn:expr] |                 #[create_dyn_unit_fn = $create_dyn_unit_fn:expr] | ||||||
|                 #[extract = $extract:ident] |                 #[extract = $extract:ident] | ||||||
|                 $(#[$variant_meta:meta])* |                 $(#[$variant_meta:meta])* | ||||||
|  | @ -70,9 +72,10 @@ macro_rules! all_units { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         mop_enum! { |         mop_enum! { | ||||||
|  |             #[impl_mop_into = false] | ||||||
|             #[hdl] |             #[hdl] | ||||||
|             $(#[$enum_meta])* |             $(#[$enum_meta])* | ||||||
|             $vis enum $UnitMOpEnum<$DestReg: Type, $SrcRegWidth: Size> { |             $vis enum $UnitMOpEnum<$DestReg: Type, $SrcRegWidth: Size, #[MOp(get_ty = $transformed_move_op_get_ty)] $TransformedMoveOp: Type> { | ||||||
|                 $( |                 $( | ||||||
|                     $(#[$variant_meta])* |                     $(#[$variant_meta])* | ||||||
|                     $Unit($Op), |                     $Unit($Op), | ||||||
|  | @ -80,14 +83,14 @@ macro_rules! all_units { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         impl<$DestReg: Type, $SrcRegWidth: Size> $UnitMOpEnum<$DestReg, $SrcRegWidth> { |         impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> { | ||||||
|             #[hdl] |             #[hdl] | ||||||
|             $vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> { |             $vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> { | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 let unit_kind = wire(); |                 let unit_kind = wire(); | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 match expr { |                 match expr { | ||||||
|                     $($UnitMOpEnum::<_, _>::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* |                     $(Self::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* | ||||||
|                 } |                 } | ||||||
|                 unit_kind |                 unit_kind | ||||||
|             } |             } | ||||||
|  | @ -100,12 +103,29 @@ macro_rules! all_units { | ||||||
|                     let $extract = wire(HdlOption[ty.$Unit]); |                     let $extract = wire(HdlOption[ty.$Unit]); | ||||||
|                     connect($extract, HdlOption[ty.$Unit].HdlNone()); |                     connect($extract, HdlOption[ty.$Unit].HdlNone()); | ||||||
|                     #[hdl] |                     #[hdl] | ||||||
|                     if let $UnitMOpEnum::<_, _>::$Unit(v) = expr { |                     if let Self::$Unit(v) = expr { | ||||||
|                         connect($extract, HdlSome(v)); |                         connect($extract, HdlSome(v)); | ||||||
|                     } |                     } | ||||||
|                     $extract |                     $extract | ||||||
|                 } |                 } | ||||||
|             )* |             )* | ||||||
|  |             $vis fn with_transformed_move_op_ty<T>(self, new_transformed_move_op_ty: T) -> $UnitMOpEnum<$DestReg, $SrcRegWidth, T> | ||||||
|  |             where | ||||||
|  |                 T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, | ||||||
|  |                 $TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, | ||||||
|  |             { | ||||||
|  |                 $UnitMOpEnum[self.dest_reg_ty()][self.src_reg_width()][new_transformed_move_op_ty] | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         all_units! { | ||||||
|  |             @split_by_transformed_move | ||||||
|  |             $vis enum $UnitMOpEnum<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> { | ||||||
|  |                 $( | ||||||
|  |                     $(#[transformed_move $($transformed_move)*])? | ||||||
|  |                     $Unit($Op), | ||||||
|  |                 )* | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         impl CpuConfig { |         impl CpuConfig { | ||||||
|  | @ -123,19 +143,105 @@ macro_rules! all_units { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |     ( | ||||||
|  |         @split_by_transformed_move | ||||||
|  |         $vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, $TransformedMoveOp:ident: Type> { | ||||||
|  |             $($BeforeUnit:ident($BeforeOp:ty),)* | ||||||
|  |             #[transformed_move] | ||||||
|  |             $TransformedMove:ident($TransformedMoveOp2:ty), | ||||||
|  |             $($AfterUnit:ident($AfterOp:ty),)* | ||||||
|  |         } | ||||||
|  |     ) => { | ||||||
|  |         impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> { | ||||||
|  |             #[hdl] | ||||||
|  |             $vis fn try_with_transformed_move_op<T>( | ||||||
|  |                 this: impl ToExpr<Type = Self>, | ||||||
|  |                 new_transformed_move_op_ty: T, | ||||||
|  |                 connect_transformed_move_op: impl FnOnce(Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>>, Expr<$TransformedMoveOp>), | ||||||
|  |             ) -> Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>> | ||||||
|  |             where | ||||||
|  |                 T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, | ||||||
|  |                 $TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, | ||||||
|  |             { | ||||||
|  |                 let this = this.to_expr(); | ||||||
|  |                 let new_ty = Expr::ty(this).with_transformed_move_op_ty(new_transformed_move_op_ty); | ||||||
|  |                 #[hdl] | ||||||
|  |                 let with_transformed_move_op = wire(HdlOption[new_ty]); | ||||||
|  |                 connect(with_transformed_move_op, Expr::ty(with_transformed_move_op).HdlNone()); | ||||||
|  |                 // workaround #[hdl] match expanding to a loop, so you can't move variables in it
 | ||||||
|  |                 let mut connect_transformed_move_op = Some(connect_transformed_move_op); | ||||||
|  |                 #[hdl] | ||||||
|  |                 match this { | ||||||
|  |                     $(Self::$BeforeUnit(unit) => connect(with_transformed_move_op, HdlSome(new_ty.$BeforeUnit(unit))),)* | ||||||
|  |                     Self::$TransformedMove(unit) => connect_transformed_move_op.take().expect("only reached once")(with_transformed_move_op, unit), | ||||||
|  |                     $(Self::$AfterUnit(unit) => connect(with_transformed_move_op, HdlSome(new_ty.$AfterUnit(unit))),)* | ||||||
|  |                 } | ||||||
|  |                 with_transformed_move_op | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const _: () = { | ||||||
|  |             #[hdl] | ||||||
|  |             type $DestReg = MOpDestReg; | ||||||
|  |             type $SrcRegWidth = ConstUsize<{ MOpRegNum::WIDTH }>; | ||||||
|  | 
 | ||||||
|  |             $(impl MOpInto<MOp> for $BeforeOp { | ||||||
|  |                 fn mop_into_ty(self) -> MOp { | ||||||
|  |                     MOp | ||||||
|  |                 } | ||||||
|  |                 fn mop_into(this: Expr<Self>) -> Expr<MOp> { | ||||||
|  |                     MOp.$BeforeUnit(this) | ||||||
|  |                 } | ||||||
|  |             })* | ||||||
|  | 
 | ||||||
|  |             $(impl MOpInto<MOp> for $AfterOp { | ||||||
|  |                 fn mop_into_ty(self) -> MOp { | ||||||
|  |                     MOp | ||||||
|  |                 } | ||||||
|  |                 fn mop_into(this: Expr<Self>) -> Expr<MOp> { | ||||||
|  |                     MOp.$AfterUnit(this) | ||||||
|  |                 } | ||||||
|  |             })* | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         $(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $BeforeOp { | ||||||
|  |             fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> { | ||||||
|  |                 RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)] | ||||||
|  |             } | ||||||
|  |             fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> { | ||||||
|  |                 MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$BeforeUnit(this) | ||||||
|  |             } | ||||||
|  |         })* | ||||||
|  | 
 | ||||||
|  |         $(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $AfterOp { | ||||||
|  |             fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> { | ||||||
|  |                 RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)] | ||||||
|  |             } | ||||||
|  |             fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> { | ||||||
|  |                 MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$AfterUnit(this) | ||||||
|  |             } | ||||||
|  |         })* | ||||||
|  |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| all_units! { | all_units! { | ||||||
|     #[hdl_unit_kind = HdlUnitKind] |     #[hdl_unit_kind = HdlUnitKind] | ||||||
|     #[unit_kind = UnitKind] |     #[unit_kind = UnitKind] | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     pub enum UnitMOp<DestReg: Type, SrcRegWidth: Size> { |     pub enum UnitMOp< | ||||||
|  |         DestReg: Type, | ||||||
|  |         SrcRegWidth: Size, | ||||||
|  |         #[MOp(get_ty = |this: UnitMOp<DestReg, SrcRegWidth, TransformedMoveOp>, new_dest_reg, new_src_reg_width| {
 | ||||||
|  |             this.TransformedMove.mapped_ty(new_dest_reg, new_src_reg_width) | ||||||
|  |         })] TransformedMoveOp: Type | ||||||
|  |     > { | ||||||
|         #[create_dyn_unit_fn = |config, unit_index| alu_branch::AluBranch::new(config, unit_index).to_dyn()] |         #[create_dyn_unit_fn = |config, unit_index| alu_branch::AluBranch::new(config, unit_index).to_dyn()] | ||||||
|         #[extract = alu_branch_mop] |         #[extract = alu_branch_mop] | ||||||
|         AluBranch(AluBranchMOp<DestReg, SrcRegWidth>), |         AluBranch(AluBranchMOp<DestReg, SrcRegWidth>), | ||||||
|  |         #[transformed_move] | ||||||
|         #[create_dyn_unit_fn = |config, unit_index| todo!()] |         #[create_dyn_unit_fn = |config, unit_index| todo!()] | ||||||
|         #[extract = l2_register_file_mop] |         #[extract = transformed_move_mop] | ||||||
|         L2RegisterFile(L2RegisterFileMOp<DestReg, SrcRegWidth>), |         TransformedMove(TransformedMoveOp), | ||||||
|         #[create_dyn_unit_fn = |config, unit_index| todo!()] |         #[create_dyn_unit_fn = |config, unit_index| todo!()] | ||||||
|         #[extract = load_store_mop] |         #[extract = load_store_mop] | ||||||
|         LoadStore(LoadStoreMOp<DestReg, SrcRegWidth>), |         LoadStore(LoadStoreMOp<DestReg, SrcRegWidth>), | ||||||
|  | @ -208,7 +314,7 @@ pub trait UnitTrait: | ||||||
| 
 | 
 | ||||||
|     fn extract_mop( |     fn extract_mop( | ||||||
|         &self, |         &self, | ||||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, |         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||||
|     ) -> Expr<HdlOption<Self::MOp>>; |     ) -> Expr<HdlOption<Self::MOp>>; | ||||||
| 
 | 
 | ||||||
|     fn module(&self) -> Interned<Module<Self::Type>>; |     fn module(&self) -> Interned<Module<Self::Type>>; | ||||||
|  | @ -266,7 +372,7 @@ impl UnitTrait for DynUnit { | ||||||
| 
 | 
 | ||||||
|     fn extract_mop( |     fn extract_mop( | ||||||
|         &self, |         &self, | ||||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, |         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||||
|     ) -> Expr<HdlOption<Self::MOp>> { |     ) -> Expr<HdlOption<Self::MOp>> { | ||||||
|         self.unit.extract_mop(mop) |         self.unit.extract_mop(mop) | ||||||
|     } |     } | ||||||
|  | @ -321,7 +427,7 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T | ||||||
| 
 | 
 | ||||||
|     fn extract_mop( |     fn extract_mop( | ||||||
|         &self, |         &self, | ||||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, |         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||||
|     ) -> Expr<HdlOption<Self::MOp>> { |     ) -> Expr<HdlOption<Self::MOp>> { | ||||||
|         Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop))) |         Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop))) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ use crate::{ | ||||||
|     config::CpuConfig, |     config::CpuConfig, | ||||||
|     instruction::{ |     instruction::{ | ||||||
|         AddSubMOp, AluBranchMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOpTrait, OutputIntegerMode, |         AddSubMOp, AluBranchMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOpTrait, OutputIntegerMode, | ||||||
|         UnitOutRegNum, COMMON_MOP_SRC_LEN, |         RenamedMOp, UnitOutRegNum, COMMON_MOP_SRC_LEN, | ||||||
|     }, |     }, | ||||||
|     register::{FlagsMode, PRegFlagsPowerISA, PRegFlagsX86, PRegValue}, |     register::{FlagsMode, PRegFlagsPowerISA, PRegFlagsX86, PRegValue}, | ||||||
|     unit::{ |     unit::{ | ||||||
|  | @ -381,7 +381,7 @@ impl UnitTrait for AluBranch { | ||||||
| 
 | 
 | ||||||
|     fn extract_mop( |     fn extract_mop( | ||||||
|         &self, |         &self, | ||||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, |         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||||
|     ) -> Expr<HdlOption<Self::MOp>> { |     ) -> Expr<HdlOption<Self::MOp>> { | ||||||
|         UnitMOp::alu_branch_mop(mop) |         UnitMOp::alu_branch_mop(mop) | ||||||
|     } |     } | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue