forked from libre-chip/cpu
		
	add helper functions for creating instructions
This commit is contained in:
		
							parent
							
								
									5b15f4a6b4
								
							
						
					
					
						commit
						4ff75313e7
					
				
					 3 changed files with 188 additions and 94 deletions
				
			
		|  | @ -10,6 +10,20 @@ use std::{fmt, marker::PhantomData, ops::Range}; | |||
| 
 | ||||
| pub mod power_isa; | ||||
| 
 | ||||
| pub trait MOpInto<Target: MOpTrait>: MOpTrait { | ||||
|     fn mop_into_ty(self) -> Target; | ||||
|     fn mop_into(this: Expr<Self>) -> Expr<Target>; | ||||
| } | ||||
| 
 | ||||
| impl<T: MOpTrait> MOpInto<T> for T { | ||||
|     fn mop_into_ty(self) -> T { | ||||
|         self | ||||
|     } | ||||
|     fn mop_into(this: Expr<Self>) -> Expr<T> { | ||||
|         this | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub trait MOpTrait: Type { | ||||
|     type Mapped<NewDestReg: Type, NewSrcRegWidth: Size>: MOpTrait; | ||||
|     type DestReg: Type; | ||||
|  | @ -424,6 +438,30 @@ 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)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $(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>; | ||||
|             type DestReg = $DestReg; | ||||
|  | @ -517,6 +555,70 @@ common_mop_struct! { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<DestReg: Type, SrcRegWidth: Size> AddSubMOp<DestReg, SrcRegWidth, ConstUsize<3>> { | ||||
|     #[hdl] | ||||
|     pub fn add_sub<Target: MOpTrait>( | ||||
|         dest: impl ToExpr<Type = DestReg>, | ||||
|         src: impl ToExpr<Type = Array<UIntType<SrcRegWidth>, 3>>, | ||||
|         imm: impl ToExpr<Type = SInt<{ COMMON_MOP_3_IMM_WIDTH }>>, | ||||
|         output_integer_mode: impl ToExpr<Type = OutputIntegerMode>, | ||||
|         invert_src0: impl ToExpr<Type = Bool>, | ||||
|         src1_is_carry_in: impl ToExpr<Type = Bool>, | ||||
|         invert_carry_in: impl ToExpr<Type = Bool>, | ||||
|         add_pc: impl ToExpr<Type = Bool>, | ||||
|     ) -> Expr<Target> | ||||
|     where | ||||
|         Self: MOpInto<Target>, | ||||
|     { | ||||
|         MOpInto::mop_into( | ||||
|             #[hdl] | ||||
|             AddSubMOp { | ||||
|                 alu_common: #[hdl] | ||||
|                 AluCommonMOp { | ||||
|                     common: CommonMOp::new(0_hdl_u0, dest, src, Expr::as_dyn_int(imm.to_expr())), | ||||
|                     output_integer_mode, | ||||
|                 }, | ||||
|                 invert_src0, | ||||
|                 src1_is_carry_in, | ||||
|                 invert_carry_in, | ||||
|                 add_pc, | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<DestReg: Type, SrcRegWidth: Size> AddSubMOp<DestReg, SrcRegWidth, ConstUsize<2>> { | ||||
|     #[hdl] | ||||
|     pub fn add_sub_i<Target: MOpTrait>( | ||||
|         dest: impl ToExpr<Type = DestReg>, | ||||
|         src: impl ToExpr<Type = Array<UIntType<SrcRegWidth>, 2>>, | ||||
|         imm: impl ToExpr<Type = SInt<{ COMMON_MOP_2_IMM_WIDTH }>>, | ||||
|         output_integer_mode: impl ToExpr<Type = OutputIntegerMode>, | ||||
|         invert_src0: impl ToExpr<Type = Bool>, | ||||
|         src1_is_carry_in: impl ToExpr<Type = Bool>, | ||||
|         invert_carry_in: impl ToExpr<Type = Bool>, | ||||
|         add_pc: impl ToExpr<Type = Bool>, | ||||
|     ) -> Expr<Target> | ||||
|     where | ||||
|         Self: MOpInto<Target>, | ||||
|     { | ||||
|         MOpInto::mop_into( | ||||
|             #[hdl] | ||||
|             AddSubMOp { | ||||
|                 alu_common: #[hdl] | ||||
|                 AluCommonMOp { | ||||
|                     common: CommonMOp::new(0_hdl_u0, dest, src, Expr::as_dyn_int(imm.to_expr())), | ||||
|                     output_integer_mode, | ||||
|                 }, | ||||
|                 invert_src0, | ||||
|                 src1_is_carry_in, | ||||
|                 invert_carry_in, | ||||
|                 add_pc, | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| common_mop_struct! { | ||||
|     #[mapped(<NewDestReg, NewSrcRegWidth> LogicalMOp<NewDestReg, NewSrcRegWidth>)] | ||||
|     #[hdl(cmp_eq)] | ||||
|  | @ -527,6 +629,32 @@ common_mop_struct! { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<DestReg: Type, SrcRegWidth: Size> LogicalMOp<DestReg, SrcRegWidth> { | ||||
|     #[hdl] | ||||
|     pub fn logical<Target: MOpTrait>( | ||||
|         dest: impl ToExpr<Type = DestReg>, | ||||
|         src: impl ToExpr<Type = Array<UIntType<SrcRegWidth>, 2>>, | ||||
|         imm: impl ToExpr<Type = SInt<{ COMMON_MOP_2_IMM_WIDTH }>>, | ||||
|         output_integer_mode: impl ToExpr<Type = OutputIntegerMode>, | ||||
|         lut: impl ToExpr<Type = UInt<4>>, | ||||
|     ) -> Expr<Target> | ||||
|     where | ||||
|         Self: MOpInto<Target>, | ||||
|     { | ||||
|         MOpInto::mop_into( | ||||
|             #[hdl] | ||||
|             LogicalMOp { | ||||
|                 alu_common: #[hdl] | ||||
|                 AluCommonMOp { | ||||
|                     common: CommonMOp::new(0_hdl_u0, dest, src, Expr::as_dyn_int(imm.to_expr())), | ||||
|                     output_integer_mode, | ||||
|                 }, | ||||
|                 lut, | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| common_mop_struct! { | ||||
|     #[mapped(<NewDestReg, NewSrcRegWidth> BranchMOp<NewDestReg, NewSrcRegWidth>)] | ||||
|     #[hdl(cmp_eq)] | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| use crate::{ | ||||
|     config::CpuConfig, | ||||
|     instruction::{ | ||||
|         mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpTrait, UnitOutRegNum, | ||||
|         mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpInto, MOpTrait, UnitOutRegNum, | ||||
|     }, | ||||
|     register::{FlagsMode, PRegValue}, | ||||
|     unit::unit_base::UnitToRegAlloc, | ||||
|  |  | |||
|  | @ -3,10 +3,7 @@ | |||
| 
 | ||||
| use cpu::{ | ||||
|     config::{CpuConfig, UnitConfig}, | ||||
|     instruction::{ | ||||
|         AddSubMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOp, MOpDestReg, MOpRegNum, | ||||
|         OutputIntegerMode, COMMON_MOP_2_IMM_WIDTH, COMMON_MOP_3_IMM_WIDTH, | ||||
|     }, | ||||
|     instruction::{AddSubMOp, LogicalMOp, MOp, MOpDestReg, MOpRegNum, OutputIntegerMode}, | ||||
|     reg_alloc::{reg_alloc, FetchedDecodedMOp}, | ||||
|     register::{FlagsMode, PRegFlagsPowerISA}, | ||||
|     unit::{GlobalState, UnitKind}, | ||||
|  | @ -47,97 +44,66 @@ fn test_reg_alloc() { | |||
|             ), | ||||
|         }, | ||||
|     ); | ||||
|     let insns = std::array::from_fn::<_, 4, _>(|i| { | ||||
|         MOp.AluBranch(MOp.AluBranch.AddSubI( | ||||
|     let insns_init: [Expr<MOp>; 4] = std::array::from_fn(|i| { | ||||
|         AddSubMOp::add_sub_i( | ||||
|             #[hdl] | ||||
|             AddSubMOp { | ||||
|                 alu_common: #[hdl] | ||||
|                 AluCommonMOp { | ||||
|                     common: CommonMOp::new( | ||||
|                         0_hdl_u0, | ||||
|                         #[hdl] | ||||
|                         MOpDestReg { | ||||
|                             normal_regs: #[hdl] | ||||
|                             [ | ||||
|                                 #[hdl] | ||||
|                                 MOpRegNum { value: i as u8 + 1 }, | ||||
|                                 MOpRegNum::const_zero(), | ||||
|                             ], | ||||
|                             flag_regs: #[hdl] | ||||
|                             [HdlSome(()), HdlNone()], | ||||
|                         }, | ||||
|                         [0u8; 2], | ||||
|                         0x12345678u32.cast_to(SInt[COMMON_MOP_2_IMM_WIDTH]), | ||||
|                     ), | ||||
|                     output_integer_mode: OutputIntegerMode.DupLow32(), | ||||
|                 }, | ||||
|                 invert_src0: false, | ||||
|                 src1_is_carry_in: false, | ||||
|                 invert_carry_in: false, | ||||
|                 add_pc: false, | ||||
|             MOpDestReg { | ||||
|                 normal_regs: #[hdl] | ||||
|                 [ | ||||
|                     #[hdl] | ||||
|                     MOpRegNum { value: i as u8 + 1 }, | ||||
|                     MOpRegNum::const_zero(), | ||||
|                 ], | ||||
|                 flag_regs: #[hdl] | ||||
|                 [HdlSome(()), HdlNone()], | ||||
|             }, | ||||
|         )) | ||||
|     }) | ||||
|     .into_iter() | ||||
|     .chain( | ||||
|         [ | ||||
|             MOp.AluBranch(MOp.AluBranch.AddSub( | ||||
|                 #[hdl] | ||||
|                 AddSubMOp { | ||||
|                     alu_common: #[hdl] | ||||
|                     AluCommonMOp { | ||||
|                         common: CommonMOp::new( | ||||
|                             0_hdl_u0, | ||||
|                             #[hdl] | ||||
|                             MOpDestReg { | ||||
|                                 normal_regs: #[hdl] | ||||
|                                 [ | ||||
|                                     #[hdl] | ||||
|                                     MOpRegNum { value: 1u8 }, | ||||
|                                     MOpRegNum::const_zero(), | ||||
|                                 ], | ||||
|                                 flag_regs: #[hdl] | ||||
|                                 [HdlSome(()), HdlNone()], | ||||
|                             }, | ||||
|                             [1u8, 0, 0], | ||||
|                             1.cast_to(SInt[COMMON_MOP_3_IMM_WIDTH]), | ||||
|                         ), | ||||
|                         output_integer_mode: OutputIntegerMode.Full64(), | ||||
|                     }, | ||||
|                     invert_src0: false, | ||||
|                     src1_is_carry_in: false, | ||||
|                     invert_carry_in: false, | ||||
|                     add_pc: false, | ||||
|                 }, | ||||
|             )), | ||||
|             MOp.AluBranch(MOp.AluBranch.Logical( | ||||
|                 #[hdl] | ||||
|                 LogicalMOp { | ||||
|                     alu_common: #[hdl] | ||||
|                     AluCommonMOp { | ||||
|                         common: CommonMOp::new( | ||||
|                             0_hdl_u0, | ||||
|                             #[hdl] | ||||
|                             MOpDestReg { | ||||
|                                 normal_regs: [ | ||||
|                                     #[hdl] | ||||
|                                     MOpRegNum { value: 2u8 }, | ||||
|                                     MOpRegNum::const_zero(), | ||||
|                                 ], | ||||
|                                 flag_regs: [HdlNone(), HdlSome(())], | ||||
|                             }, | ||||
|                             [2u8, 4u8], | ||||
|                             SInt[COMMON_MOP_2_IMM_WIDTH].zero(), | ||||
|                         ), | ||||
|                         output_integer_mode: OutputIntegerMode.Full64(), | ||||
|                     }, | ||||
|                     lut: 0b0110_hdl_u4, | ||||
|                 }, | ||||
|             )), | ||||
|         ] | ||||
|         .into_iter() | ||||
|         .cycle(), | ||||
|     ); | ||||
|             [0u8; 2], | ||||
|             0x12345678u32.cast_to_static(), | ||||
|             OutputIntegerMode.DupLow32(), | ||||
|             false, | ||||
|             false, | ||||
|             false, | ||||
|             false, | ||||
|         ) | ||||
|     }); | ||||
|     let insns_loop = [ | ||||
|         AddSubMOp::add_sub( | ||||
|             #[hdl] | ||||
|             MOpDestReg { | ||||
|                 normal_regs: #[hdl] | ||||
|                 [ | ||||
|                     #[hdl] | ||||
|                     MOpRegNum { value: 1u8 }, | ||||
|                     MOpRegNum::const_zero(), | ||||
|                 ], | ||||
|                 flag_regs: #[hdl] | ||||
|                 [HdlSome(()), HdlNone()], | ||||
|             }, | ||||
|             [1u8, 0, 0], | ||||
|             1.cast_to_static(), | ||||
|             OutputIntegerMode.Full64(), | ||||
|             false, | ||||
|             false, | ||||
|             false, | ||||
|             false, | ||||
|         ), | ||||
|         LogicalMOp::logical( | ||||
|             #[hdl] | ||||
|             MOpDestReg { | ||||
|                 normal_regs: [ | ||||
|                     #[hdl] | ||||
|                     MOpRegNum { value: 2u8 }, | ||||
|                     MOpRegNum::const_zero(), | ||||
|                 ], | ||||
|                 flag_regs: [HdlNone(), HdlSome(())], | ||||
|             }, | ||||
|             [2u8, 4u8], | ||||
|             0.cast_to_static(), | ||||
|             OutputIntegerMode.Full64(), | ||||
|             0b0110_hdl_u4, | ||||
|         ), | ||||
|     ]; | ||||
|     let insns = insns_init.into_iter().chain(insns_loop.into_iter().cycle()); | ||||
|     let mut insn_index = 0; | ||||
|     for cycle in 0..20 { | ||||
|         for fetch_index in 0..config.fetch_width.get() { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue