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
 | ||||
| // See Notices.txt for copyright information
 | ||||
| use crate::{ | ||||
|     instruction::{MOpTrait, PRegNum, UnitNum, UnitOutRegNum, CONST_ZERO_UNIT_NUM}, | ||||
|     instruction::{MOpTrait, PRegNum, RenamedMOp, UnitNum, UnitOutRegNum, CONST_ZERO_UNIT_NUM}, | ||||
|     unit::{ | ||||
|         unit_base::{UnitForwardingInfo, UnitToRegAlloc}, | ||||
|         UnitCancelInput, UnitKind, UnitMOp, UnitOutputWrite, | ||||
|         UnitCancelInput, UnitKind, UnitOutputWrite, | ||||
|     }, | ||||
| }; | ||||
| use fayalite::prelude::*; | ||||
|  | @ -79,8 +79,8 @@ impl CpuConfig { | |||
|     pub fn p_reg_num_width(&self) -> usize { | ||||
|         self.unit_num_width() + self.out_reg_num_width | ||||
|     } | ||||
|     pub fn unit_mop_in_unit(&self) -> UnitMOp<UnitOutRegNum<DynSize>, DynSize> { | ||||
|         UnitMOp[self.unit_out_reg_num()][self.p_reg_num_width()] | ||||
|     pub fn renamed_mop_in_unit(&self) -> RenamedMOp<UnitOutRegNum<DynSize>, DynSize> { | ||||
|         RenamedMOp[self.unit_out_reg_num()][self.p_reg_num_width()] | ||||
|     } | ||||
|     pub fn unit_output_write(&self) -> UnitOutputWrite<DynSize> { | ||||
|         UnitOutputWrite[self.out_reg_num_width] | ||||
|  |  | |||
|  | @ -25,7 +25,10 @@ impl<T: MOpTrait> MOpInto<T> for T { | |||
| } | ||||
| 
 | ||||
| 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 SrcRegWidth: Size; | ||||
|     fn dest_reg_ty(self) -> Self::DestReg; | ||||
|  | @ -69,7 +72,12 @@ pub trait MOpTrait: Type { | |||
| pub trait CommonMOpTrait: MOpTrait { | ||||
|     type PrefixPad: 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 CommonMOpTraitSrcRegWidth: Size; | ||||
|     fn common_mop_ty( | ||||
|  | @ -418,9 +426,15 @@ macro_rules! common_mop_struct { | |||
| 
 | ||||
| macro_rules! mop_enum { | ||||
|     ( | ||||
|         #[impl_mop_into = $impl_mop_into:tt] | ||||
|         $(#[$enum_meta:meta])* | ||||
|         $vis:vis enum $MOp:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size> { | ||||
|             $(#[$first_variant_meta:meta])* | ||||
|         $vis:vis enum $MOp:ident< | ||||
|             $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), | ||||
|             $( | ||||
|                 $(#[$variant_meta:meta])* | ||||
|  | @ -429,7 +443,7 @@ macro_rules! mop_enum { | |||
|         } | ||||
|     ) => { | ||||
|         $(#[$enum_meta])* | ||||
|         $vis enum $MOp<$DestReg: Type, $SrcRegWidth: Size> { | ||||
|         $vis enum $MOp<$DestReg: Type, $SrcRegWidth: Size $(, $MOpTypes: Type)* $(, $Sizes: Size)*> { | ||||
|             $(#[$first_variant_meta])* | ||||
|             $FirstVariant($first_ty), | ||||
|             $( | ||||
|  | @ -438,32 +452,37 @@ macro_rules! mop_enum { | |||
|             )* | ||||
|         } | ||||
| 
 | ||||
|         impl<$DestReg: Type, $SrcRegWidth: Size, Target: MOpTrait> MOpInto<Target> for $first_ty | ||||
|         where | ||||
|             $MOp<$DestReg, $SrcRegWidth>: MOpInto<Target> | ||||
|         { | ||||
|             fn mop_into_ty(self) -> Target { | ||||
|                 MOpInto::mop_into_ty($MOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]) | ||||
|             } | ||||
|             fn mop_into(this: Expr<Self>) -> Expr<Target> { | ||||
|                 MOpInto::mop_into(MOpInto::<$MOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$FirstVariant(this)) | ||||
|         mop_enum! { | ||||
|             @impl_variants | ||||
|             #[impl_mop_into = $impl_mop_into] | ||||
|             enum $MOp [ | ||||
|                 $DestReg: Type, | ||||
|                 $SrcRegWidth: Size | ||||
|                 $(, #[MOp(get_ty = $mop_types_get_ty)] $MOpTypes: Type)* | ||||
|                 $(, #[Size(get_size = $sizes_get_size)] $Sizes: Size)* | ||||
|             ] { | ||||
|                 $FirstVariant($first_ty), | ||||
|                 $($Variant($ty),)* | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $(impl<$DestReg: Type, $SrcRegWidth: Size, Target: MOpTrait> MOpInto<Target> for $ty | ||||
|         where | ||||
|             $MOp<$DestReg, $SrcRegWidth>: MOpInto<Target> | ||||
|         { | ||||
|             fn mop_into_ty(self) -> Target { | ||||
|                 MOpInto::mop_into_ty($MOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)]) | ||||
|             } | ||||
|             fn mop_into(this: Expr<Self>) -> Expr<Target> { | ||||
|                 MOpInto::mop_into(MOpInto::<$MOp<$DestReg, $SrcRegWidth>>::mop_into_ty(Expr::ty(this)).$Variant(this)) | ||||
|             } | ||||
|         })* | ||||
| 
 | ||||
|         impl<$DestReg: Type, $SrcRegWidth: Size> MOpTrait for $MOp<$DestReg, $SrcRegWidth> { | ||||
|             type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp<NewDestReg, NewSrcRegWidth>; | ||||
|         impl< | ||||
|             $DestReg: Type, | ||||
|             $SrcRegWidth: Size, | ||||
|             $($MOpTypes: Type + MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,)* | ||||
|             $($Sizes: Size,)* | ||||
|         > MOpTrait for $MOp< | ||||
|             $DestReg, | ||||
|             $SrcRegWidth, | ||||
|             $($MOpTypes,)* | ||||
|             $($Sizes,)* | ||||
|         > { | ||||
|             type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp< | ||||
|                 NewDestReg, | ||||
|                 NewSrcRegWidth, | ||||
|                 $(<$MOpTypes as MOpTrait>::Mapped<NewDestReg, NewSrcRegWidth>,)* | ||||
|                 $($Sizes,)* | ||||
|             >; | ||||
|             type DestReg = $DestReg; | ||||
|             type SrcRegWidth = $SrcRegWidth; | ||||
|             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()); | ||||
|                 #[hdl] | ||||
|                 match input { | ||||
|                     $MOp::<_, _>::$FirstVariant(v) => connect(dest_reg, MOpTrait::dest_reg(v)), | ||||
|                     $($MOp::<_, _>::$Variant(v) => connect(dest_reg, MOpTrait::dest_reg(v)),)* | ||||
|                     Self::$FirstVariant(v) => connect(dest_reg, <$first_ty as MOpTrait>::dest_reg(v)), | ||||
|                     $(Self::$Variant(v) => connect(dest_reg, <$ty as MOpTrait>::dest_reg(v)),)* | ||||
|                 } | ||||
|                 dest_reg | ||||
|             } | ||||
|  | @ -491,8 +510,8 @@ macro_rules! mop_enum { | |||
|             ) { | ||||
|                 #[hdl] | ||||
|                 match input { | ||||
|                     $MOp::<_, _>::$FirstVariant(v) => MOpTrait::for_each_src_reg(v, f), | ||||
|                     $($MOp::<_, _>::$Variant(v) => MOpTrait::for_each_src_reg(v, f),)* | ||||
|                     Self::$FirstVariant(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>( | ||||
|  | @ -500,7 +519,7 @@ macro_rules! mop_enum { | |||
|                 new_dest_reg: NewDestReg, | ||||
|                 new_src_reg_width: NewSrcRegWidth::SizeType, | ||||
|             ) -> 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] | ||||
|             fn map_regs<NewDestReg: Type, NewSrcRegWidth: Size>( | ||||
|  | @ -519,13 +538,52 @@ macro_rules! mop_enum { | |||
|                 let mapped_regs = wire(mapped_ty); | ||||
|                 #[hdl] | ||||
|                 match input { | ||||
|                     $MOp::<_, _>::$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::$FirstVariant(v) => connect(mapped_regs, mapped_ty.$FirstVariant(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 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     ( | ||||
|         @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; | ||||
|  | @ -666,6 +724,7 @@ common_mop_struct! { | |||
| } | ||||
| 
 | ||||
| mop_enum! { | ||||
|     #[impl_mop_into = true] | ||||
|     #[hdl] | ||||
|     pub enum AluBranchMOp<DestReg: Type, SrcRegWidth: Size> { | ||||
|         AddSub(AddSubMOp<DestReg, SrcRegWidth, ConstUsize<3>>), | ||||
|  | @ -693,6 +752,7 @@ common_mop_struct! { | |||
| } | ||||
| 
 | ||||
| mop_enum! { | ||||
|     #[impl_mop_into = true] | ||||
|     #[hdl] | ||||
|     pub enum L2RegisterFileMOp<DestReg: Type, SrcRegWidth: Size> { | ||||
|         ReadL2Reg(ReadL2RegMOp<DestReg, SrcRegWidth>), | ||||
|  | @ -728,6 +788,7 @@ common_mop_struct! { | |||
| } | ||||
| 
 | ||||
| mop_enum! { | ||||
|     #[impl_mop_into = true] | ||||
|     #[hdl] | ||||
|     pub enum LoadStoreMOp<DestReg: Type, SrcRegWidth: Size> { | ||||
|         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)] | ||||
| /// 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
 | ||||
|  | @ -1014,4 +1084,12 @@ impl MOpDestReg { | |||
| } | ||||
| 
 | ||||
| #[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::{ | ||||
|     config::CpuConfig, | ||||
|     instruction::{ | ||||
|         MOp, MOpDestReg, MOpRegNum, MOpTrait, PRegNum, RenameTableName, UnitOutRegNum, | ||||
|         MOp, MOpDestReg, MOpRegNum, MOpTrait, MoveRegMOp, PRegNum, RenameTableName, UnitOutRegNum, | ||||
|         COMMON_MOP_SRC_LEN, | ||||
|     }, | ||||
|     unit::{ | ||||
|         unit_base::{UnitForwardingInfo, UnitInput}, | ||||
|         GlobalState, TrapData, UnitOutput, UnitOutputWrite, UnitResult, UnitResultCompleted, | ||||
|         UnitTrait, | ||||
|         GlobalState, TrapData, UnitMOp, UnitOutput, UnitOutputWrite, UnitResult, | ||||
|         UnitResultCompleted, UnitTrait, | ||||
|     }, | ||||
|     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()]); | ||||
|     #[hdl] | ||||
|     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] | ||||
|     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() { | ||||
|  | @ -358,12 +358,8 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|             #[hdl] | ||||
|             if let HdlSome(renamed_mop_out_reg) = renamed_mops_out_reg[fetch_index] { | ||||
|                 let dest_reg = MOpTrait::dest_reg(decoded_insn.mop); | ||||
|                 connect( | ||||
|                     renamed_mops[fetch_index], | ||||
|                     HdlSome( | ||||
|                         #[hdl] | ||||
|                         UnitInput::<_> { | ||||
|                             mop: MOpTrait::map_regs( | ||||
|                 let renamed_mop = UnitMOp::try_with_transformed_move_op( | ||||
|                     MOpTrait::map_regs( | ||||
|                         decoded_insn.mop, | ||||
|                         renamed_mop_out_reg.unit_out_reg, | ||||
|                         config.p_reg_num_width(), | ||||
|  | @ -376,9 +372,21 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|                             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) | ||||
|                     .into_iter() | ||||
|  |  | |||
|  | @ -4,7 +4,8 @@ | |||
| use crate::{ | ||||
|     config::CpuConfig, | ||||
|     instruction::{ | ||||
|         mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpInto, MOpTrait, UnitOutRegNum, | ||||
|         mop_enum, AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait, | ||||
|         RenamedMOp, UnitOutRegNum, | ||||
|     }, | ||||
|     register::{FlagsMode, PRegValue}, | ||||
|     unit::unit_base::UnitToRegAlloc, | ||||
|  | @ -24,8 +25,9 @@ macro_rules! all_units { | |||
|         #[unit_kind = $UnitKind:ident] | ||||
|         #[hdl] | ||||
|         $(#[$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] | ||||
|                 #[extract = $extract:ident] | ||||
|                 $(#[$variant_meta:meta])* | ||||
|  | @ -70,9 +72,10 @@ macro_rules! all_units { | |||
|         } | ||||
| 
 | ||||
|         mop_enum! { | ||||
|             #[impl_mop_into = false] | ||||
|             #[hdl] | ||||
|             $(#[$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])* | ||||
|                     $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] | ||||
|             $vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> { | ||||
|                 #[hdl] | ||||
|                 let unit_kind = wire(); | ||||
|                 #[hdl] | ||||
|                 match expr { | ||||
|                     $($UnitMOpEnum::<_, _>::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* | ||||
|                     $(Self::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* | ||||
|                 } | ||||
|                 unit_kind | ||||
|             } | ||||
|  | @ -100,12 +103,29 @@ macro_rules! all_units { | |||
|                     let $extract = wire(HdlOption[ty.$Unit]); | ||||
|                     connect($extract, HdlOption[ty.$Unit].HdlNone()); | ||||
|                     #[hdl] | ||||
|                     if let $UnitMOpEnum::<_, _>::$Unit(v) = expr { | ||||
|                     if let Self::$Unit(v) = expr { | ||||
|                         connect($extract, HdlSome(v)); | ||||
|                     } | ||||
|                     $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 { | ||||
|  | @ -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! { | ||||
|     #[hdl_unit_kind = HdlUnitKind] | ||||
|     #[unit_kind = UnitKind] | ||||
|     #[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()] | ||||
|         #[extract = alu_branch_mop] | ||||
|         AluBranch(AluBranchMOp<DestReg, SrcRegWidth>), | ||||
|         #[transformed_move] | ||||
|         #[create_dyn_unit_fn = |config, unit_index| todo!()] | ||||
|         #[extract = l2_register_file_mop] | ||||
|         L2RegisterFile(L2RegisterFileMOp<DestReg, SrcRegWidth>), | ||||
|         #[extract = transformed_move_mop] | ||||
|         TransformedMove(TransformedMoveOp), | ||||
|         #[create_dyn_unit_fn = |config, unit_index| todo!()] | ||||
|         #[extract = load_store_mop] | ||||
|         LoadStore(LoadStoreMOp<DestReg, SrcRegWidth>), | ||||
|  | @ -208,7 +314,7 @@ pub trait UnitTrait: | |||
| 
 | ||||
|     fn extract_mop( | ||||
|         &self, | ||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|     ) -> Expr<HdlOption<Self::MOp>>; | ||||
| 
 | ||||
|     fn module(&self) -> Interned<Module<Self::Type>>; | ||||
|  | @ -266,7 +372,7 @@ impl UnitTrait for DynUnit { | |||
| 
 | ||||
|     fn extract_mop( | ||||
|         &self, | ||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|     ) -> Expr<HdlOption<Self::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( | ||||
|         &self, | ||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|     ) -> Expr<HdlOption<Self::MOp>> { | ||||
|         Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop))) | ||||
|     } | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ use crate::{ | |||
|     config::CpuConfig, | ||||
|     instruction::{ | ||||
|         AddSubMOp, AluBranchMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOpTrait, OutputIntegerMode, | ||||
|         UnitOutRegNum, COMMON_MOP_SRC_LEN, | ||||
|         RenamedMOp, UnitOutRegNum, COMMON_MOP_SRC_LEN, | ||||
|     }, | ||||
|     register::{FlagsMode, PRegFlagsPowerISA, PRegFlagsX86, PRegValue}, | ||||
|     unit::{ | ||||
|  | @ -381,7 +381,7 @@ impl UnitTrait for AluBranch { | |||
| 
 | ||||
|     fn extract_mop( | ||||
|         &self, | ||||
|         mop: Expr<UnitMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|         mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, | ||||
|     ) -> Expr<HdlOption<Self::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