add helper functions for creating instructions
All checks were successful
/ deps (push) Successful in 15s
/ test (push) Successful in 26m13s

This commit is contained in:
Jacob Lifshay 2025-02-23 20:51:44 -08:00
parent 5b15f4a6b4
commit 4ff75313e7
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 188 additions and 94 deletions

View file

@ -10,6 +10,20 @@ use std::{fmt, marker::PhantomData, ops::Range};
pub mod power_isa; 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 { pub trait MOpTrait: Type {
type Mapped<NewDestReg: Type, NewSrcRegWidth: Size>: MOpTrait; type Mapped<NewDestReg: Type, NewSrcRegWidth: Size>: MOpTrait;
type DestReg: Type; 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> { impl<$DestReg: Type, $SrcRegWidth: Size> MOpTrait for $MOp<$DestReg, $SrcRegWidth> {
type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp<NewDestReg, NewSrcRegWidth>; type Mapped<NewDestReg: Type, NewSrcRegWidth: Size> = $MOp<NewDestReg, NewSrcRegWidth>;
type DestReg = $DestReg; 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! { common_mop_struct! {
#[mapped(<NewDestReg, NewSrcRegWidth> LogicalMOp<NewDestReg, NewSrcRegWidth>)] #[mapped(<NewDestReg, NewSrcRegWidth> LogicalMOp<NewDestReg, NewSrcRegWidth>)]
#[hdl(cmp_eq)] #[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! { common_mop_struct! {
#[mapped(<NewDestReg, NewSrcRegWidth> BranchMOp<NewDestReg, NewSrcRegWidth>)] #[mapped(<NewDestReg, NewSrcRegWidth> BranchMOp<NewDestReg, NewSrcRegWidth>)]
#[hdl(cmp_eq)] #[hdl(cmp_eq)]

View file

@ -4,7 +4,7 @@
use crate::{ use crate::{
config::CpuConfig, config::CpuConfig,
instruction::{ instruction::{
mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpTrait, UnitOutRegNum, mop_enum, AluBranchMOp, L2RegisterFileMOp, LoadStoreMOp, MOpInto, MOpTrait, UnitOutRegNum,
}, },
register::{FlagsMode, PRegValue}, register::{FlagsMode, PRegValue},
unit::unit_base::UnitToRegAlloc, unit::unit_base::UnitToRegAlloc,

View file

@ -3,10 +3,7 @@
use cpu::{ use cpu::{
config::{CpuConfig, UnitConfig}, config::{CpuConfig, UnitConfig},
instruction::{ instruction::{AddSubMOp, LogicalMOp, MOp, MOpDestReg, MOpRegNum, OutputIntegerMode},
AddSubMOp, AluCommonMOp, CommonMOp, LogicalMOp, MOp, MOpDestReg, MOpRegNum,
OutputIntegerMode, COMMON_MOP_2_IMM_WIDTH, COMMON_MOP_3_IMM_WIDTH,
},
reg_alloc::{reg_alloc, FetchedDecodedMOp}, reg_alloc::{reg_alloc, FetchedDecodedMOp},
register::{FlagsMode, PRegFlagsPowerISA}, register::{FlagsMode, PRegFlagsPowerISA},
unit::{GlobalState, UnitKind}, unit::{GlobalState, UnitKind},
@ -47,14 +44,8 @@ fn test_reg_alloc() {
), ),
}, },
); );
let insns = std::array::from_fn::<_, 4, _>(|i| { let insns_init: [Expr<MOp>; 4] = std::array::from_fn(|i| {
MOp.AluBranch(MOp.AluBranch.AddSubI( AddSubMOp::add_sub_i(
#[hdl]
AddSubMOp {
alu_common: #[hdl]
AluCommonMOp {
common: CommonMOp::new(
0_hdl_u0,
#[hdl] #[hdl]
MOpDestReg { MOpDestReg {
normal_regs: #[hdl] normal_regs: #[hdl]
@ -67,27 +58,16 @@ fn test_reg_alloc() {
[HdlSome(()), HdlNone()], [HdlSome(()), HdlNone()],
}, },
[0u8; 2], [0u8; 2],
0x12345678u32.cast_to(SInt[COMMON_MOP_2_IMM_WIDTH]), 0x12345678u32.cast_to_static(),
), OutputIntegerMode.DupLow32(),
output_integer_mode: OutputIntegerMode.DupLow32(), false,
}, false,
invert_src0: false, false,
src1_is_carry_in: false, false,
invert_carry_in: false, )
add_pc: false, });
}, let insns_loop = [
)) AddSubMOp::add_sub(
})
.into_iter()
.chain(
[
MOp.AluBranch(MOp.AluBranch.AddSub(
#[hdl]
AddSubMOp {
alu_common: #[hdl]
AluCommonMOp {
common: CommonMOp::new(
0_hdl_u0,
#[hdl] #[hdl]
MOpDestReg { MOpDestReg {
normal_regs: #[hdl] normal_regs: #[hdl]
@ -100,23 +80,14 @@ fn test_reg_alloc() {
[HdlSome(()), HdlNone()], [HdlSome(()), HdlNone()],
}, },
[1u8, 0, 0], [1u8, 0, 0],
1.cast_to(SInt[COMMON_MOP_3_IMM_WIDTH]), 1.cast_to_static(),
OutputIntegerMode.Full64(),
false,
false,
false,
false,
), ),
output_integer_mode: OutputIntegerMode.Full64(), LogicalMOp::logical(
},
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] #[hdl]
MOpDestReg { MOpDestReg {
normal_regs: [ normal_regs: [
@ -127,17 +98,12 @@ fn test_reg_alloc() {
flag_regs: [HdlNone(), HdlSome(())], flag_regs: [HdlNone(), HdlSome(())],
}, },
[2u8, 4u8], [2u8, 4u8],
SInt[COMMON_MOP_2_IMM_WIDTH].zero(), 0.cast_to_static(),
OutputIntegerMode.Full64(),
0b0110_hdl_u4,
), ),
output_integer_mode: OutputIntegerMode.Full64(), ];
}, let insns = insns_init.into_iter().chain(insns_loop.into_iter().cycle());
lut: 0b0110_hdl_u4,
},
)),
]
.into_iter()
.cycle(),
);
let mut insn_index = 0; let mut insn_index = 0;
for cycle in 0..20 { for cycle in 0..20 {
for fetch_index in 0..config.fetch_width.get() { for fetch_index in 0..config.fetch_width.get() {