add a procedural implementation of rename_execute_retire #12

Merged
programmerjake merged 24 commits from programmerjake/cpu:rename-execute-retire into master 2026-05-22 06:58:09 +00:00
38 changed files with 615322 additions and 36446 deletions

8
Cargo.lock generated
View file

@ -388,7 +388,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]] [[package]]
name = "fayalite" name = "fayalite"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
dependencies = [ dependencies = [
"base64", "base64",
"bitvec", "bitvec",
@ -417,7 +417,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-proc-macros" name = "fayalite-proc-macros"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
dependencies = [ dependencies = [
"fayalite-proc-macros-impl", "fayalite-proc-macros-impl",
] ]
@ -425,7 +425,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-proc-macros-impl" name = "fayalite-proc-macros-impl"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
dependencies = [ dependencies = [
"base16ct 0.2.0", "base16ct 0.2.0",
"num-bigint", "num-bigint",
@ -440,7 +440,7 @@ dependencies = [
[[package]] [[package]]
name = "fayalite-visit-gen" name = "fayalite-visit-gen"
version = "0.3.0" version = "0.3.0"
source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#80b92c7dd3adcad8487a3f8224846e381219bfa6" source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#cf3e6cfc6bc33eebf2d2862c7a1948b9cf40ecac"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"prettyplease", "prettyplease",

View file

@ -33,3 +33,6 @@ hex-literal.workspace = true
regex = "1.12.2" regex = "1.12.2"
sha2.workspace = true sha2.workspace = true
which.workspace = true which.workspace = true
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(todo)'] }

View file

@ -1,13 +1,7 @@
// 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::CONST_ZERO_UNIT_NUM, unit::UnitKind};
instruction::{CONST_ZERO_UNIT_NUM, MOpTrait, PRegNum, RenamedMOp, UnitNum, UnitOutRegNum}, use fayalite::{expr::HdlPartialOrdImpl, prelude::*};
unit::{
UnitCancelInput, UnitKind, UnitOutputWrite,
unit_base::{UnitForwardingInfo, UnitToRegAlloc},
},
};
use fayalite::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -101,54 +95,20 @@ impl CpuConfig {
pub fn unit_num_width(&self) -> usize { pub fn unit_num_width(&self) -> usize {
UInt::range(CONST_ZERO_UNIT_NUM..self.non_const_unit_nums().end).width() UInt::range(CONST_ZERO_UNIT_NUM..self.non_const_unit_nums().end).width()
} }
pub fn unit_num(&self) -> UnitNum<DynSize> {
UnitNum[self.unit_num_width()]
}
pub fn unit_out_reg_num(&self) -> UnitOutRegNum<DynSize> {
UnitOutRegNum[self.out_reg_num_width]
}
pub fn p_reg_num(&self) -> PRegNum<DynSize, DynSize> {
PRegNum[self.unit_num_width()][self.out_reg_num_width]
}
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 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]
}
pub fn unit_output_writes(&self) -> Array<HdlOption<UnitOutputWrite<DynSize>>> {
Array[HdlOption[self.unit_output_write()]][self.non_const_unit_nums().len()]
}
pub fn unit_cancel_input(&self) -> UnitCancelInput<DynSize> {
UnitCancelInput[self.out_reg_num_width]
}
pub fn unit_forwarding_info(&self) -> UnitForwardingInfo<DynSize, DynSize, DynSize> {
UnitForwardingInfo[self.unit_num_width()][self.out_reg_num_width]
[self.non_const_unit_nums().len()]
}
pub fn unit_max_in_flight(&self, unit_index: usize) -> NonZeroUsize { pub fn unit_max_in_flight(&self, unit_index: usize) -> NonZeroUsize {
self.units[unit_index] self.units[unit_index]
.max_in_flight .max_in_flight
.unwrap_or(self.default_unit_max_in_flight) .unwrap_or(self.default_unit_max_in_flight)
} }
pub fn unit_to_reg_alloc< /// the maximum of all [`unit_max_in_flight()`][Self::unit_max_in_flight()]
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>, pub fn max_unit_max_in_flight(&self) -> NonZeroUsize {
ExtraOut: Type, (0..self.units.len())
>( .map(|unit_index| self.unit_max_in_flight(unit_index))
&self, .max()
mop_ty: MOp, .unwrap_or(self.default_unit_max_in_flight)
extra_out_ty: ExtraOut,
) -> UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> {
assert_eq!(
mop_ty.dest_reg_ty(),
self.unit_out_reg_num(),
"inconsistent types",
);
UnitToRegAlloc[mop_ty][extra_out_ty][self.unit_num_width()][self.out_reg_num_width]
[self.non_const_unit_nums().len()]
} }
pub fn fetch_width_in_bytes(&self) -> usize { pub fn fetch_width_in_bytes(&self) -> usize {
1usize 1usize
@ -188,6 +148,21 @@ impl CpuConfig {
} }
} }
#[hdl(get(|c| c.out_reg_num_width))]
pub type CpuConfigOutRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.unit_num_width()))]
pub type CpuConfigUnitNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.p_reg_num_width()))]
pub type CpuConfigPRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| 1 << c.out_reg_num_width))]
pub type CpuConfig2PowOutRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.units.len()))]
pub type CpuConfigUnitCount<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(get(|c| c.fetch_width.get()))] #[hdl(get(|c| c.fetch_width.get()))]
pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize; pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
@ -236,6 +211,10 @@ pub type CpuConfigL1ICacheMaxMissesInFlight<C: PhantomConstGet<CpuConfig>> = Dyn
#[hdl(get(|c| c.rob_size.get()))] #[hdl(get(|c| c.rob_size.get()))]
pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize; pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize;
/// the maximum of all [`unit_max_in_flight()`][CpuConfig::unit_max_in_flight()]
#[hdl(get(|c| c.max_unit_max_in_flight().get()))]
pub type CpuConfigMaxUnitMaxInFlight<C: PhantomConstGet<CpuConfig>> = DynSize;
pub trait PhantomConstCpuConfig: pub trait PhantomConstCpuConfig:
PhantomConstGet<CpuConfig> PhantomConstGet<CpuConfig>
+ Into<PhantomConst<CpuConfig>> + Into<PhantomConst<CpuConfig>>
@ -243,6 +222,7 @@ pub trait PhantomConstCpuConfig:
+ Type + Type
+ ToSimValue<Type = Self> + ToSimValue<Type = Self>
+ ToExpr<Type = Self> + ToExpr<Type = Self>
+ HdlPartialOrdImpl<Self>
{ {
} }

View file

@ -7,8 +7,8 @@ use crate::{
AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion, AddSubMOp, BranchMOp, CompareMOp, CompareMode, ConditionMode, LoadMOp, LoadStoreConversion,
LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg, LoadStoreWidth, LogicalFlagsMOp, LogicalFlagsMOpImm, LogicalMOp, Lut4, MOp, MOpDestReg,
MOpRegNum, MoveRegMOp, OutputIntegerMode, ReadSpecialMOp, ReadSpecialMOpImm, MOpRegNum, MoveRegMOp, OutputIntegerMode, ReadSpecialMOp, ReadSpecialMOpImm,
ShiftRotateDestLogicOp, ShiftRotateMOp, ShiftRotateMOpImm, ShiftRotateMode, StoreMOp, ShiftAmountOverflowBehavior, ShiftRotateDestLogicOp, ShiftRotateMOp, ShiftRotateMOpImm,
power_isa::PowerIsaSprEnum, ShiftRotateMode, StoreMOp, power_isa::PowerIsaSprEnum,
}, },
powerisa_instructions_xml::{ powerisa_instructions_xml::{
InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem, InstructionBitFieldName, InstructionBitFieldsInner, Instructions, TextLineItem,
@ -604,7 +604,7 @@ impl DecodeState<'_> {
}], }],
[], [],
), ),
MOpRegNum::const_zero().value, [MOpRegNum::const_zero(); 2],
(li << 2).cast_to_static(), (li << 2).cast_to_static(),
!aa, !aa,
lk, lk,
@ -646,7 +646,7 @@ impl DecodeState<'_> {
#[hdl] #[hdl]
let branch_ctr_reg: MOpRegNum = wire(); let branch_ctr_reg: MOpRegNum = wire();
let dest = MOpDestReg::new([branch_lr_dest_reg], []); let dest = MOpDestReg::new([branch_lr_dest_reg], []);
let src1 = addr_reg.unwrap_or_else(|| MOpRegNum::const_zero()).value; let src1 = addr_reg.unwrap_or_else(|| MOpRegNum::const_zero());
let imm: Expr<SInt<_>> = (bd.unwrap_or(0_hdl_i14) << 2).cast_to_static(); let imm: Expr<SInt<_>> = (bd.unwrap_or(0_hdl_i14) << 2).cast_to_static();
let invert_src2_eq_zero = !use_eq_for_ctr_compare; let invert_src2_eq_zero = !use_eq_for_ctr_compare;
let pc_relative = match aa { let pc_relative = match aa {
@ -659,7 +659,7 @@ impl DecodeState<'_> {
branch_mop, branch_mop,
BranchMOp::branch_i( BranchMOp::branch_i(
dest, dest,
src1, [MOpRegNum::const_zero(), src1],
imm.cast_to_static::<SInt<_>>(), imm.cast_to_static::<SInt<_>>(),
pc_relative, pc_relative,
lk, lk,
@ -671,8 +671,7 @@ impl DecodeState<'_> {
branch_mop, branch_mop,
BranchMOp::branch_ctr( BranchMOp::branch_ctr(
dest, dest,
src1, [MOpRegNum::const_zero(), src1, branch_ctr_reg],
branch_ctr_reg.value,
imm, imm,
invert_src2_eq_zero, invert_src2_eq_zero,
pc_relative, pc_relative,
@ -685,7 +684,7 @@ impl DecodeState<'_> {
branch_mop, branch_mop,
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
dest, dest,
[cr_field.value, src1, branch_ctr_reg.value], [cr_field, src1, branch_ctr_reg],
imm, imm,
!expected_cr_bit_value, !expected_cr_bit_value,
condition_mode, condition_mode,
@ -713,10 +712,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []), MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
[ [MOpRegNum::power_isa_ctr_reg(), MOpRegNum::const_zero()],
MOpRegNum::power_isa_ctr_reg().value,
MOpRegNum::const_zero().value,
],
(-1).cast_to_static::<SInt<_>>(), (-1).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -789,7 +785,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new([bt_reg], []), MOpDestReg::new([bt_reg], []),
[ba_reg.value, bb_reg.value, bt_reg.value], [ba_reg, bb_reg, bt_reg],
#[hdl] #[hdl]
LogicalFlagsMOpImm { LogicalFlagsMOpImm {
src0_start: src0_start.cast_to(LogicalFlagsMOpImm.src0_start), src0_start: src0_start.cast_to(LogicalFlagsMOpImm.src0_start),
@ -815,7 +811,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[crf(bfa).value], [crf(bfa)],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
), ),
); );
@ -892,7 +888,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[MOpRegNum::const_zero().value; 2], [MOpRegNum::const_zero(); 2],
d, d,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -906,7 +902,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
d, d,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -918,12 +914,7 @@ impl DecodeState<'_> {
} }
connect( connect(
this.output[1], this.output[1],
LoadMOp::load( LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
MOpDestReg::new([gpr(rt)], []),
[ea_reg.value],
width,
conversion,
),
); );
}, },
); );
@ -939,7 +930,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, gpr(rb).value], [gpr_or_zero(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -950,12 +941,7 @@ impl DecodeState<'_> {
); );
connect( connect(
this.output[1], this.output[1],
LoadMOp::load( LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
MOpDestReg::new([gpr(rt)], []),
[ea_reg.value],
width,
conversion,
),
); );
}); });
} else if self.arguments == Some("RT,disp(RA)") { } else if self.arguments == Some("RT,disp(RA)") {
@ -969,7 +955,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
(ds << 2).cast_to_static::<SInt<_>>(), (ds << 2).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -980,12 +966,7 @@ impl DecodeState<'_> {
); );
connect( connect(
this.output[1], this.output[1],
LoadMOp::load( LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
MOpDestReg::new([gpr(rt)], []),
[ea_reg.value],
width,
conversion,
),
); );
}); });
} else { } else {
@ -1005,7 +986,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
d.cast_to_static::<SInt<_>>(), d.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1016,12 +997,7 @@ impl DecodeState<'_> {
); );
connect( connect(
this.output[1], this.output[1],
LoadMOp::load( LoadMOp::load(MOpDestReg::new([gpr(rt)], []), [ea_reg], width, conversion),
MOpDestReg::new([gpr(rt)], []),
[ea_reg.value],
width,
conversion,
),
); );
}); });
} }
@ -1092,7 +1068,7 @@ impl DecodeState<'_> {
this.output[1], this.output[1],
StoreMOp::store( StoreMOp::store(
MOpDestReg::new([], []), MOpDestReg::new([], []),
[ea_reg.value, gpr(rs).value], [ea_reg, gpr(rs)],
width, width,
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
), ),
@ -1107,7 +1083,7 @@ impl DecodeState<'_> {
this.output[2], this.output[2],
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new([gpr(ra)], []), MOpDestReg::new([gpr(ra)], []),
[ea_reg.value], [ea_reg],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
); );
@ -1126,7 +1102,7 @@ impl DecodeState<'_> {
insn, insn,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[MOpRegNum::const_zero().value; 2], [MOpRegNum::const_zero(); 2],
d, d,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1140,7 +1116,7 @@ impl DecodeState<'_> {
insn, insn,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
d, d,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1161,7 +1137,7 @@ impl DecodeState<'_> {
insn, insn,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, gpr(rb).value], [gpr_or_zero(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1179,7 +1155,7 @@ impl DecodeState<'_> {
insn, insn,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
(ds << 2).cast_to_static::<SInt<_>>(), (ds << 2).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1203,7 +1179,7 @@ impl DecodeState<'_> {
insn, insn,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([ea_reg], []), MOpDestReg::new([ea_reg], []),
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
d.cast_to_static::<SInt<_>>(), d.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1230,7 +1206,7 @@ impl DecodeState<'_> {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([gpr(rt)], []), MOpDestReg::new([gpr(rt)], []),
#[hdl] #[hdl]
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
si.cast_to_static(), si.cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1253,7 +1229,7 @@ impl DecodeState<'_> {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([gpr(rt)], []), MOpDestReg::new([gpr(rt)], []),
#[hdl] #[hdl]
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
((si0 << 16) + si1.cast_to(SInt[34])).cast_to_static(), ((si0 << 16) + si1.cast_to(SInt[34])).cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1280,7 +1256,7 @@ impl DecodeState<'_> {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([gpr(rt)], []), MOpDestReg::new([gpr(rt)], []),
#[hdl] #[hdl]
[gpr_or_zero(ra).value, MOpRegNum::const_zero().value], [gpr_or_zero(ra), MOpRegNum::const_zero()],
(si << 16).cast_to_static(), (si << 16).cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1307,7 +1283,7 @@ impl DecodeState<'_> {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new([gpr(rt)], []), MOpDestReg::new([gpr(rt)], []),
#[hdl] #[hdl]
[MOpRegNum::const_zero().value; 2], [MOpRegNum::const_zero(); 2],
(4i8 + (d << 16)).cast_to_static(), (4i8 + (d << 16)).cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1340,7 +1316,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value], [gpr(ra), gpr(rb), MOpRegNum::const_zero()],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1371,7 +1347,7 @@ impl DecodeState<'_> {
)], )],
), ),
#[hdl] #[hdl]
[gpr(ra).value, MOpRegNum::const_zero().value], [gpr(ra), MOpRegNum::const_zero()],
si.cast_to_static(), si.cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1410,7 +1386,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value], [gpr(ra), gpr(rb), MOpRegNum::const_zero()],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
true, true,
@ -1440,7 +1416,7 @@ impl DecodeState<'_> {
)], )],
), ),
#[hdl] #[hdl]
[gpr(ra).value, MOpRegNum::const_zero().value], [gpr(ra), MOpRegNum::const_zero()],
si.cast_to_static(), si.cast_to_static(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
true, true,
@ -1472,7 +1448,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[gpr(ra).value, gpr(rb).value, MOpRegNum::const_zero().value], [gpr(ra), gpr(rb), MOpRegNum::const_zero()],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1505,11 +1481,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[ [gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg(), gpr(rb)],
gpr(ra).value,
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
gpr(rb).value,
],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -1542,11 +1514,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[ [gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg(), gpr(rb)],
gpr(ra).value,
MOpRegNum::power_isa_xer_ca_ca32_reg().value,
gpr(rb).value,
],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
true, true,
@ -1580,9 +1548,9 @@ impl DecodeState<'_> {
), ),
#[hdl] #[hdl]
[ [
gpr(ra).value, gpr(ra),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
if this.mnemonic.contains('m') { -1i8 } else { 0 } if this.mnemonic.contains('m') { -1i8 } else { 0 }
.cast_to_static::<SInt<_>>(), .cast_to_static::<SInt<_>>(),
@ -1617,11 +1585,7 @@ impl DecodeState<'_> {
], ],
), ),
#[hdl] #[hdl]
[ [gpr(ra), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
gpr(ra).value,
MOpRegNum::const_zero().value,
MOpRegNum::const_zero().value,
],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
true, true,
@ -1654,9 +1618,8 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value], [gpr(ra)],
si.cast_to_static::<SInt<_>>(), si.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
compare_mode, compare_mode,
), ),
); );
@ -1683,9 +1646,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value, gpr(rb).value], [gpr(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
compare_mode, compare_mode,
), ),
); );
@ -1712,9 +1673,8 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value], [gpr(ra)],
ui.cast_to_static::<SInt<_>>(), ui.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
compare_mode, compare_mode,
), ),
); );
@ -1741,9 +1701,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value, gpr(rb).value], [gpr(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
compare_mode, compare_mode,
), ),
); );
@ -1770,9 +1728,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value, gpr(rb).value], [gpr(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
compare_mode, compare_mode,
), ),
); );
@ -1791,9 +1747,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[gpr(ra).value, gpr(rb).value], [gpr(ra), gpr(rb)],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.CmpEqB(), CompareMode.CmpEqB(),
), ),
); );
@ -1825,7 +1779,7 @@ impl DecodeState<'_> {
this.mnemonic.contains('.').to_expr(), this.mnemonic.contains('.').to_expr(),
)], )],
), ),
[gpr(rs).value], [gpr(rs)],
if this.mnemonic.contains('s') { if this.mnemonic.contains('s') {
(ui << 16).cast_to_static::<SInt<_>>() (ui << 16).cast_to_static::<SInt<_>>()
} else { } else {
@ -1873,7 +1827,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
LogicalMOp::logical( LogicalMOp::logical(
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]), MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
[gpr(rs).value, gpr(rb).value], [gpr(rs), gpr(rb)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
lut, lut,
@ -1887,7 +1841,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new([gpr(ra)], []), MOpDestReg::new([gpr(ra)], []),
[gpr(rs).value], [gpr(rs)],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
), ),
); );
@ -1916,7 +1870,7 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
LogicalMOp::logical_i( LogicalMOp::logical_i(
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]), MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
[gpr(rs).value], [gpr(rs)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
output_integer_mode, output_integer_mode,
Lut4::from_fn(|a, b| a | b), Lut4::from_fn(|a, b| a | b),
@ -1994,11 +1948,12 @@ impl DecodeState<'_> {
self.output[0], self.output[0],
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]), MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
[gpr(rs.0).value, gpr(rs.0).value, gpr(rb.0).value], [gpr(rs.0), gpr(rs.0), gpr(rb.0)],
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlNone(), shift_rotate_amount: HdlNone(),
shift_rotate_right: false, shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op, dest_logic_op,
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2031,24 +1986,25 @@ impl DecodeState<'_> {
self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, fallback_is_src2); self.rotate_dest_logic_op(msb0_mask_begin, msb0_mask_end, fallback_is_src2);
#[hdl] #[hdl]
let rotate_imm_src2 = wire(); let rotate_imm_src2 = wire();
connect(rotate_imm_src2, MOpRegNum::const_zero().value); connect(rotate_imm_src2, MOpRegNum::const_zero());
// if dest_logic_op is HdlNone, we don't need to read from src2 // if dest_logic_op is HdlNone, we don't need to read from src2
#[hdl] #[hdl]
if let HdlSome(dest_logic_op) = dest_logic_op { if let HdlSome(dest_logic_op) = dest_logic_op {
#[hdl] #[hdl]
if dest_logic_op.fallback_is_src2 { if dest_logic_op.fallback_is_src2 {
connect(rotate_imm_src2, gpr(ra.0).value); connect(rotate_imm_src2, gpr(ra.0));
} }
} }
connect( connect(
self.output[0], self.output[0],
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]), MOpDestReg::new([gpr(ra.0)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc.0)]),
[gpr(rs.0).value, gpr(rs.0).value, rotate_imm_src2], [gpr(rs.0), gpr(rs.0), rotate_imm_src2],
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(rotate_amount), shift_rotate_amount: HdlSome(rotate_amount),
shift_rotate_right: false, shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op, dest_logic_op,
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2194,15 +2150,13 @@ impl DecodeState<'_> {
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()], [gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
), ),
[ [gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
gpr(rs).value,
MOpRegNum::const_zero().value,
MOpRegNum::const_zero().value,
],
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(sh.cast_to_static::<UInt<_>>()), shift_rotate_amount: HdlSome(sh.cast_to_static::<UInt<_>>()),
shift_rotate_right: true, shift_rotate_right: true,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToWidth(),
dest_logic_op: HdlNone(), dest_logic_op: HdlNone(),
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2226,15 +2180,13 @@ impl DecodeState<'_> {
[gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()], [gpr(ra), MOpRegNum::power_isa_xer_ca_ca32_reg()],
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
), ),
[ [gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
gpr(rs).value,
MOpRegNum::const_zero().value,
MOpRegNum::const_zero().value,
],
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(sh.rotate_right(1)), shift_rotate_amount: HdlSome(sh.rotate_right(1)),
shift_rotate_right: true, shift_rotate_right: true,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToWidth(),
dest_logic_op: HdlNone(), dest_logic_op: HdlNone(),
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2268,14 +2220,16 @@ impl DecodeState<'_> {
[(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)],
), ),
if !is_signed && is_right_shift { if !is_signed && is_right_shift {
[MOpRegNum::const_zero().value, gpr(rs).value, gpr(rb).value] [MOpRegNum::const_zero(), gpr(rs), gpr(rb)]
} else { } else {
[gpr(rs).value, MOpRegNum::const_zero().value, gpr(rb).value] [gpr(rs), MOpRegNum::const_zero(), gpr(rb)]
}, },
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlNone(), shift_rotate_amount: HdlNone(),
shift_rotate_right: is_right_shift, shift_rotate_right: is_right_shift,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToTwiceWidth(),
dest_logic_op: HdlNone(), dest_logic_op: HdlNone(),
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2306,15 +2260,13 @@ impl DecodeState<'_> {
this.output[0], this.output[0],
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]), MOpDestReg::new([gpr(ra)], [(MOpRegNum::POWER_ISA_CR_0_REG_NUM, rc)]),
[ [gpr(rs), MOpRegNum::const_zero(), MOpRegNum::const_zero()],
gpr(rs).value,
MOpRegNum::const_zero().value,
MOpRegNum::const_zero().value,
],
#[hdl] #[hdl]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: HdlSome(sh.rotate_right(1)), shift_rotate_amount: HdlSome(sh.rotate_right(1)),
shift_rotate_right: false, shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior
.WrapToWidth(),
dest_logic_op: HdlNone(), dest_logic_op: HdlNone(),
}, },
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -2340,7 +2292,7 @@ impl DecodeState<'_> {
self.output[0], self.output[0],
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new([spr], []), MOpDestReg::new([spr], []),
[gpr(reg).value], [gpr(reg)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
); );
@ -2349,7 +2301,7 @@ impl DecodeState<'_> {
self.output[0], self.output[0],
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new([gpr(reg)], []), MOpDestReg::new([gpr(reg)], []),
[spr.value], [spr],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
); );
@ -2365,7 +2317,7 @@ impl DecodeState<'_> {
self.output[0], self.output[0],
ReadSpecialMOp::read_special( ReadSpecialMOp::read_special(
MOpDestReg::new([gpr(reg)], []), MOpDestReg::new([gpr(reg)], []),
[MOpRegNum::const_zero().value; 0], [MOpRegNum::const_zero(); 0],
imm, imm,
), ),
); );
@ -2441,9 +2393,9 @@ impl DecodeState<'_> {
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new([crf(bf)], []), MOpDestReg::new([crf(bf)], []),
[ [
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_xer_so_ov_ov32_reg().value, MOpRegNum::power_isa_xer_so_ov_ov32_reg(),
], ],
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| { LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
let mut dest = PRegFlagsPowerISAView::splat(None); let mut dest = PRegFlagsPowerISAView::splat(None);

View file

@ -523,7 +523,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
kind, kind,
read_data, read_data,
config: _, config: _,
} = memory_operation_finish; } = memory_operation_finish.into_sim_value();
#[hdl(sim)] #[hdl(sim)]
match kind { match kind {
MemoryOperationFinishKind::Success(success) => MemoryOperationFinishKind::Success(success) =>
@ -746,7 +746,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
let NextPcToFetchInterfaceInner { let NextPcToFetchInterfaceInner {
start_pc, start_pc,
fetch_block_id, fetch_block_id,
} = fetch; } = fetch.into_sim_value();
let entry_ty = FetchQueueEntry[config]; let entry_ty = FetchQueueEntry[config];
self.queue.push_back( self.queue.push_back(
#[hdl(sim)] #[hdl(sim)]
@ -895,7 +895,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
let CacheReadData::<_> { let CacheReadData::<_> {
cache_line_index: read_cache_line_index, cache_line_index: read_cache_line_index,
cache_line, cache_line,
} = cache_read_data; } = cache_read_data.into_sim_value();
let config = self.config(); let config = self.config();
for entry in &mut self.queue { for entry in &mut self.queue {
#[hdl(sim)] #[hdl(sim)]
@ -1151,8 +1151,6 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
sim.wait_for_clock_edge(cd.clk).await; sim.wait_for_clock_edge(cd.clk).await;
} }
sim.write(from_next_pc.cancel.ready, true).await; sim.write(from_next_pc.cancel.ready, true).await;
let memory_interface_start_data_ty = memory_interface.start.data.ty();
let to_decode_fetched_data_ty = to_decode_fetched.data.ty();
let cache_read_data_ty = CacheReadData[config]; let cache_read_data_ty = CacheReadData[config];
let mut state = L1ICacheStateSim::new(state_expr); let mut state = L1ICacheStateSim::new(state_expr);
loop { loop {
@ -1168,26 +1166,11 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
.await; .await;
sim.write( sim.write(
memory_interface.start.data, memory_interface.start.data,
if let Some(v) = state.clone().try_start_memory_operation() { state.clone().try_start_memory_operation(),
#[hdl(sim)]
memory_interface_start_data_ty.HdlSome(v)
} else {
#[hdl(sim)]
memory_interface_start_data_ty.HdlNone()
},
)
.await;
sim.write(
to_decode_fetched.data,
if let Some(v) = state.clone().to_decode_fetched() {
#[hdl(sim)]
to_decode_fetched_data_ty.HdlSome(v)
} else {
#[hdl(sim)]
to_decode_fetched_data_ty.HdlNone()
},
) )
.await; .await;
sim.write(to_decode_fetched.data, state.clone().to_decode_fetched())
.await;
state.write_debug_state(&mut sim).await; state.write_debug_state(&mut sim).await;
sim.write(max_cancel_in_fetch, state.queue.len()).await; sim.write(max_cancel_in_fetch, state.queue.len()).await;
state state

File diff suppressed because it is too large Load diff

View file

@ -25,89 +25,206 @@ pub struct PowerIsaCrBitNum {
pub bit_in_field: UInt<2>, pub bit_in_field: UInt<2>,
} }
impl MOpRegNum { macro_rules! suffix_str_with_0_to_31 {
pub const POWER_ISA_LR_REG_NUM: u32 = 1; ($str:literal) => {
#[hdl] suffix_str_with_0_to_31!(
pub fn power_isa_lr_reg() -> Expr<Self> { $str,
#[hdl] [
Self { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
value: Self::POWER_ISA_LR_REG_NUM.cast_to_static::<UInt<_>>(), 23, 24, 25, 26, 27, 28, 29, 30, 31,
} ]
} )
pub const POWER_ISA_CTR_REG_NUM: u32 = 2; };
#[hdl] ($str:literal, [$($num:literal),* $(,)?]) => {
pub fn power_isa_ctr_reg() -> Expr<Self> { [$(concat!($str, $num)),*]
#[hdl] };
Self { }
value: Self::POWER_ISA_CTR_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
#[hdl]
pub fn power_isa_tar_reg() -> Expr<Self> {
#[hdl]
Self {
value: Self::POWER_ISA_TAR_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
const fn fill_names_range<'a>(dest: &mut [Option<&'a str>], range: Range<u32>, src: &[&'a str]) {
assert!((range.end - range.start) as usize == src.len());
let mut i = 0;
while i < src.len() {
dest[i + range.start as usize] = Some(src[i]);
i += 1;
}
}
macro_rules! power_isa_regs {
(
$(
#[name_str = $name_str:literal, expr_fn = $expr_fn:ident, sim_fn = $sim_fn:ident]
$(#[doc = $($doc:tt)*])*
pub const $REG_NUM:ident: u32 = $reg_num_expr:expr;
)*
$(
#[names_fn = |$names_var:ident| $names_body:expr $(,
reg_num_fn = $reg_num_fn_multi:ident,
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
expr_imm_fn = $expr_imm_fn_multi:ident,
sim_fn = $sim_fn_multi:ident,)?
]
$(#[doc = $($doc_multi:tt)*])*
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
)*
) => {
impl MOpRegNum {
pub const POWER_ISA_REG_NAMES: &[Option<&str>; 1 << Self::WIDTH] = &{
let mut retval = [None; _];
$(retval[Self::$REG_NUM as usize] = Some($name_str);)*
$({
let $names_var = &mut retval;
$names_body
})*
retval
};
$(
$(#[doc = $($doc)*])*
pub const $REG_NUM: u32 = $reg_num_expr;
$(#[doc = $($doc)*])*
#[hdl]
pub fn $expr_fn() -> Expr<Self> {
#[hdl]
Self {
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
}
}
$(#[doc = $($doc)*])*
#[hdl]
pub fn $sim_fn() -> SimValue<Self> {
#[hdl(sim)]
Self {
value: Self::$REG_NUM.cast_to_static::<UInt<_>>(),
}
}
)*
$(
$(#[doc = $($doc_multi)*])*
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
power_isa_regs! {
@helper_fns
#[names_fn = |$names_var| $names_body $(,
reg_num_fn = $reg_num_fn_multi,
expr_fn = $expr_fn_multi($fn_multi_arg),
expr_imm_fn = $expr_imm_fn_multi,
sim_fn = $sim_fn_multi,)?
]
$(#[doc = $($doc_multi)*])*
pub const $REG_NUM_MULTI: Range<u32> = $reg_num_multi_expr;
}
)*
}
};
(
@helper_fns
#[names_fn = |$names_var:ident| $names_body:expr]
$(#[doc = $($doc_multi:tt)*])*
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
) => {};
(
@helper_fns
#[
names_fn = |$names_var:ident| $names_body:expr,
reg_num_fn = $reg_num_fn_multi:ident,
expr_fn = $expr_fn_multi:ident($fn_multi_arg:ty),
expr_imm_fn = $expr_imm_fn_multi:ident,
sim_fn = $sim_fn_multi:ident,
]
$(#[doc = $($doc_multi:tt)*])*
pub const $REG_NUM_MULTI:ident: Range<u32> = $reg_num_multi_expr:expr;
) => {
$(#[doc = $($doc_multi)*])*
pub const fn $reg_num_fn_multi(index: usize) -> u32 {
range_u32_nth_or_panic(&Self::$REG_NUM_MULTI, index)
}
$(#[doc = $($doc_multi)*])*
#[hdl]
pub fn $expr_fn_multi(input: Expr<$fn_multi_arg>) -> Expr<Self> {
#[hdl]
Self {
value: (Self::$REG_NUM_MULTI.start + input).cast_to_static::<UInt<_>>(),
}
}
$(#[doc = $($doc_multi)*])*
#[hdl]
pub fn $expr_imm_fn_multi(input: usize) -> Expr<Self> {
#[hdl]
Self {
value: Self::$reg_num_fn_multi(input).cast_to_static::<UInt<_>>(),
}
}
$(#[doc = $($doc_multi)*])*
#[hdl]
pub fn $sim_fn_multi(reg_num: &SimValue<$fn_multi_arg>) -> SimValue<Self> {
#[hdl(sim)]
Self {
value: (Self::$REG_NUM_MULTI.start + reg_num).cast_to_static::<UInt<_>>(),
}
}
};
}
power_isa_regs! {
#[name_str = "lr", expr_fn = power_isa_lr_reg, sim_fn = power_isa_lr_reg_sim]
pub const POWER_ISA_LR_REG_NUM: u32 = 1;
#[name_str = "ctr", expr_fn = power_isa_ctr_reg, sim_fn = power_isa_ctr_reg_sim]
pub const POWER_ISA_CTR_REG_NUM: u32 = 2;
#[name_str = "tar", expr_fn = power_isa_tar_reg, sim_fn = power_isa_tar_reg_sim]
pub const POWER_ISA_TAR_REG_NUM: u32 = 3;
#[name_str = "xer[so,ov,ov32]", expr_fn = power_isa_xer_so_ov_ov32_reg, sim_fn = power_isa_xer_so_ov_ov32_reg_sim]
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`] /// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
/// ///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue /// [`PRegValue.flags`]: struct@crate::register::PRegValue
pub const POWER_ISA_XER_SO_OV_OV32_REG_NUM: u32 = pub const POWER_ISA_XER_SO_OV_OV32_REG_NUM: u32 =
range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 0); range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 0);
#[name_str = "xer[ca,ca32]", expr_fn = power_isa_xer_ca_ca32_reg, sim_fn = power_isa_xer_ca_ca32_reg_sim]
/// CA and CA32 XER bits -- in [`PRegValue.flags`] /// CA and CA32 XER bits -- in [`PRegValue.flags`]
/// ///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue /// [`PRegValue.flags`]: struct@crate::register::PRegValue
pub const POWER_ISA_XER_CA_CA32_REG_NUM: u32 = 4; pub const POWER_ISA_XER_CA_CA32_REG_NUM: u32 = 4;
#[name_str = "xer[other]", expr_fn = power_isa_xer_other_reg, sim_fn = power_isa_xer_other_reg_sim]
/// only the XER bits that don't exist in [`PRegValue.flags`] /// only the XER bits that don't exist in [`PRegValue.flags`]
/// ///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue /// [`PRegValue.flags`]: struct@crate::register::PRegValue
pub const POWER_ISA_XER_OTHER_REG_NUM: u32 = 5; pub const POWER_ISA_XER_OTHER_REG_NUM: u32 = 5;
#[name_str = "temp", expr_fn = power_isa_temp_reg, sim_fn = power_isa_temp_reg_sim]
/// used as a temporary for things like computing the effective address before loading/storing memory /// used as a temporary for things like computing the effective address before loading/storing memory
pub const POWER_ISA_TEMP_REG_NUM: u32 = 8; pub const POWER_ISA_TEMP_REG_NUM: u32 = 8;
#[hdl]
pub fn power_isa_temp_reg() -> Expr<Self> {
#[hdl]
Self {
value: Self::POWER_ISA_TEMP_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
/// SO, OV, and OV32 XER bits -- in [`PRegValue.flags`]
///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
#[hdl]
pub fn power_isa_xer_so_ov_ov32_reg() -> Expr<Self> {
#[hdl]
Self {
value: Self::POWER_ISA_XER_SO_OV_OV32_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
/// CA and CA32 XER bits -- in [`PRegValue.flags`]
///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
#[hdl]
pub fn power_isa_xer_ca_ca32_reg() -> Expr<Self> {
#[hdl]
Self {
value: Self::POWER_ISA_XER_CA_CA32_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
/// only the XER bits that don't exist in [`PRegValue.flags`]
///
/// [`PRegValue.flags`]: struct@crate::register::PRegValue
#[hdl]
pub fn power_isa_xer_other_reg() -> Expr<Self> {
#[hdl]
Self {
value: Self::POWER_ISA_XER_OTHER_REG_NUM.cast_to_static::<UInt<_>>(),
}
}
#[name_str = "cr0", expr_fn = power_isa_cr_0_reg, sim_fn = power_isa_cr_0_reg_sim]
pub const POWER_ISA_CR_0_REG_NUM: u32 = range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 1); pub const POWER_ISA_CR_0_REG_NUM: u32 = range_u32_nth_or_panic(&Self::FLAG_REG_NUMS, 1);
#[names_fn = |names| {
fill_names_range(names, Self::POWER_ISA_CR_1_THRU_7_REG_NUMS, &["cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7"]);
}]
pub const POWER_ISA_CR_1_THRU_7_REG_NUMS: Range<u32> = 9..16; pub const POWER_ISA_CR_1_THRU_7_REG_NUMS: Range<u32> = 9..16;
#[
names_fn = |names| {
fill_names_range(names, Self::POWER_ISA_GPR_REG_NUMS, &suffix_str_with_0_to_31!("r"));
},
reg_num_fn = power_isa_gpr_reg_num,
expr_fn = power_isa_gpr_reg(UInt<5>),
expr_imm_fn = power_isa_gpr_reg_imm,
sim_fn = power_isa_gpr_reg_sim,
]
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
#[
names_fn = |names| {
fill_names_range(names, Self::POWER_ISA_FPR_REG_NUMS, &suffix_str_with_0_to_31!("f"));
},
reg_num_fn = power_isa_fpr_reg_num,
expr_fn = power_isa_fpr_reg(UInt<5>),
expr_imm_fn = power_isa_fpr_reg_imm,
sim_fn = power_isa_fpr_reg_sim,
]
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
}
impl MOpRegNum {
pub const fn power_isa_cr_reg_num(index: usize) -> u32 { pub const fn power_isa_cr_reg_num(index: usize) -> u32 {
if index == 0 { if index == 0 {
Self::POWER_ISA_CR_0_REG_NUM Self::POWER_ISA_CR_0_REG_NUM
@ -148,31 +265,6 @@ impl MOpRegNum {
} }
} }
pub const POWER_ISA_GPR_REG_NUMS: Range<u32> = 32..64;
pub const fn power_isa_gpr_reg_num(index: usize) -> u32 {
range_u32_nth_or_panic(&Self::POWER_ISA_GPR_REG_NUMS, index)
}
#[hdl]
pub fn power_isa_gpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
#[hdl]
Self {
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
}
}
#[hdl]
pub fn power_isa_gpr_reg_imm(index: usize) -> Expr<Self> {
#[hdl]
Self {
value: Self::power_isa_gpr_reg_num(index).cast_to_static::<UInt<_>>(),
}
}
#[hdl]
pub fn power_isa_gpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
#[hdl(sim)]
Self {
value: (Self::POWER_ISA_GPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
}
}
pub const fn power_isa_gpr_or_zero_reg_num(index: usize) -> u32 { pub const fn power_isa_gpr_or_zero_reg_num(index: usize) -> u32 {
if index == 0 { if index == 0 {
Self::CONST_ZERO_REG_NUM Self::CONST_ZERO_REG_NUM
@ -192,6 +284,13 @@ impl MOpRegNum {
power_isa_gpr_or_zero_reg power_isa_gpr_or_zero_reg
} }
#[hdl] #[hdl]
pub fn power_isa_gpr_or_zero_reg_imm(index: usize) -> Expr<Self> {
#[hdl]
Self {
value: Self::power_isa_gpr_or_zero_reg_num(index).cast_to_static::<UInt<_>>(),
}
}
#[hdl]
pub fn power_isa_gpr_or_zero_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> { pub fn power_isa_gpr_or_zero_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
#[hdl(sim)] #[hdl(sim)]
Self { Self {
@ -201,25 +300,6 @@ impl MOpRegNum {
.cast_to_static::<UInt<_>>(), .cast_to_static::<UInt<_>>(),
} }
} }
pub const POWER_ISA_FPR_REG_NUMS: Range<u32> = 64..96;
pub const fn power_isa_fpr_reg_num(index: usize) -> u32 {
range_u32_nth_or_panic(&Self::POWER_ISA_FPR_REG_NUMS, index)
}
#[hdl]
pub fn power_isa_fpr_reg(reg_num: Expr<UInt<5>>) -> Expr<Self> {
#[hdl]
Self {
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
}
}
#[hdl]
pub fn power_isa_fpr_reg_sim(reg_num: &SimValue<UInt<5>>) -> SimValue<Self> {
#[hdl(sim)]
Self {
value: (Self::POWER_ISA_FPR_REG_NUMS.start + reg_num).cast_to_static::<UInt<_>>(),
}
}
} }
#[hdl(cmp_eq)] #[hdl(cmp_eq)]

View file

@ -7,7 +7,9 @@ pub mod instruction;
pub mod main_memory_and_io; pub mod main_memory_and_io;
pub mod next_pc; pub mod next_pc;
pub mod powerisa_instructions_xml; pub mod powerisa_instructions_xml;
#[cfg(todo)]
pub mod reg_alloc; pub mod reg_alloc;
pub mod register; pub mod register;
pub mod rename_execute_retire;
pub mod unit; pub mod unit;
pub mod util; pub mod util;

View file

@ -20,17 +20,16 @@ use crate::{
CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize, CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize,
PhantomConstCpuConfig, TwiceCpuConfigFetchWidth, PhantomConstCpuConfig, TwiceCpuConfigFetchWidth,
}, },
util::array_vec::ArrayVec, util::{LFSR31, array_vec::ArrayVec},
}; };
use fayalite::{ use fayalite::{
expr::HdlPartialEqImpl,
int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType}, int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType},
prelude::*, prelude::*,
sim::value::SimOnlyValueTrait, sim::value::SimOnlyValueTrait,
ty::StaticType, ty::StaticType,
util::{DebugAsDisplay, ready_valid::ReadyValid}, util::{DebugAsDisplay, ready_valid::ReadyValid},
}; };
use std::{borrow::Cow, fmt}; use std::fmt;
pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize; pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize;
type FetchBlockIdInt = u8; type FetchBlockIdInt = u8;
@ -53,7 +52,7 @@ pub struct NextPcToFetchInterface<C: PhantomConstGet<CpuConfig>> {
pub config: C, pub config: C,
} }
#[hdl] #[hdl(cmp_eq)]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] /// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
/// since the actual instruction definition isn't finalized yet. /// since the actual instruction definition isn't finalized yet.
/// This will be replaced at a later point. /// This will be replaced at a later point.
@ -93,101 +92,6 @@ impl WipDecodedInsnKind {
} }
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for WipDecodedInsnKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[hdl]
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
let clear_unused_bits = |v: Cow<'_, SimValue<Self>>| {
#[hdl(sim)]
match &*v {
Self::NonBranch =>
{
#[hdl(sim)]
Self::NonBranch()
}
Self::Branch(target) =>
{
#[hdl(sim)]
Self::Branch(target)
}
Self::BranchCond(target) =>
{
#[hdl(sim)]
Self::BranchCond(target)
}
Self::IndirectBranch =>
{
#[hdl(sim)]
Self::IndirectBranch()
}
Self::Call(target) =>
{
#[hdl(sim)]
Self::Call(target)
}
Self::CallCond(target) =>
{
#[hdl(sim)]
Self::CallCond(target)
}
Self::IndirectCall =>
{
#[hdl(sim)]
Self::IndirectCall()
}
Self::Ret =>
{
#[hdl(sim)]
Self::Ret()
}
Self::RetCond =>
{
#[hdl(sim)]
Self::RetCond()
}
Self::Interrupt(target) =>
{
#[hdl(sim)]
Self::Interrupt(target)
}
Self::Unknown => v.into_owned(),
}
};
(SimValue::bits(&clear_unused_bits(lhs)) == SimValue::bits(&clear_unused_bits(rhs)))
.to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
!Self::cmp_sim_value_eq(lhs, rhs)
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
todo!()
}
}
#[hdl(cmp_eq)] #[hdl(cmp_eq)]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] /// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
/// since the actual instruction definition isn't finalized yet. /// since the actual instruction definition isn't finalized yet.
@ -2781,8 +2685,10 @@ impl<T: SimValueDefault, N: Size> SimValueDefault for ArrayType<T, N> {
} }
impl<T: Type> SimValueDefault for HdlOption<T> { impl<T: Type> SimValueDefault for HdlOption<T> {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> { fn sim_value_default(self) -> SimValue<Self> {
self.HdlNone().to_sim_value_with_type(self) #[hdl(sim)]
self.HdlNone()
} }
} }
@ -2911,50 +2817,13 @@ impl ResetSteps for CallStack {
} }
} }
#[hdl] #[hdl(cmp_eq)]
enum BTBEntryInsnKind { enum BTBEntryInsnKind {
Branch, Branch,
Call, Call,
Ret, Ret,
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for BTBEntryInsnKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) != SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl BTBEntryInsnKind { impl BTBEntryInsnKind {
#[hdl] #[hdl]
fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> { fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> {
@ -2983,7 +2852,7 @@ impl BTBEntryInsnKind {
} }
} }
#[hdl] #[hdl(cmp_eq)]
enum BTBEntryAddrKind { enum BTBEntryAddrKind {
Unconditional, Unconditional,
Indirect, Indirect,
@ -2991,43 +2860,6 @@ enum BTBEntryAddrKind {
CondNotTaken, CondNotTaken,
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for BTBEntryAddrKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) != SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl BTBEntryAddrKind { impl BTBEntryAddrKind {
#[hdl] #[hdl]
fn taken(this: &SimValue<Self>) -> bool { fn taken(this: &SimValue<Self>) -> bool {
@ -3123,33 +2955,9 @@ impl BTBEntry {
} }
} }
#[hdl]
struct LFSR31 {
// MSB is always zero, 32 bits makes it easier to manipulate
state: UInt<32>,
}
impl SimValueDefault for LFSR31 { impl SimValueDefault for LFSR31 {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> { fn sim_value_default(self) -> SimValue<Self> {
#[hdl(sim)] Self::new()
Self { state: 1u32 }
}
}
impl LFSR31 {
fn next(this: &mut SimValue<Self>) -> u32 {
let state = this.state.as_int();
let state = if state == 0 {
1u32
} else {
// a maximal-length 31-bit LFSR
let lsb = ((state >> 30) ^ (state >> 27)) & 1;
let msb = (state << 1) & ((1 << 31) - 1);
lsb | msb
};
*this.state = state.into();
state
} }
} }
@ -3163,7 +2971,7 @@ impl BranchTargetBuffer {
const LOG2_SIZE: usize = 4; const LOG2_SIZE: usize = 4;
const SIZE: usize = 1 << Self::LOG2_SIZE; const SIZE: usize = 1 << Self::LOG2_SIZE;
fn next_index_to_replace(this: &mut SimValue<Self>) -> usize { fn next_index_to_replace(this: &mut SimValue<Self>) -> usize {
LFSR31::next(&mut this.next_index_to_replace_lfsr) as usize % Self::SIZE LFSR31::next_sim(&mut this.next_index_to_replace_lfsr) as usize % Self::SIZE
} }
} }

View file

@ -6,9 +6,9 @@ use fayalite::{
expr::CastToImpl, expr::CastToImpl,
int::{BoolOrIntType, UIntInRange}, int::{BoolOrIntType, UIntInRange},
prelude::*, prelude::*,
ty::StaticType, ty::{SimValueDebug, StaticType},
}; };
use std::fmt; use std::{any::Any, fmt};
#[hdl] #[hdl]
pub enum FlagsMode { pub enum FlagsMode {
@ -47,6 +47,12 @@ pub trait PRegFlagsViewTrait: Type + PRegFlagsViewTraitSealed {
fn from_view_sim<T: ToSimValue>(view: Self::View<T>) -> SimValue<PRegFlags<T::Type>>; fn from_view_sim<T: ToSimValue>(view: Self::View<T>) -> SimValue<PRegFlags<T::Type>>;
fn view_unused_into_view<T>(unused: ViewUnused<T, PRegFlagsAllUnused>) -> Self::View<T>; fn view_unused_into_view<T>(unused: ViewUnused<T, PRegFlagsAllUnused>) -> Self::View<T>;
fn view_into_view_unused<T>(view: Self::View<T>) -> ViewUnused<T, PRegFlagsAllUnused>; fn view_into_view_unused<T>(view: Self::View<T>) -> ViewUnused<T, PRegFlagsAllUnused>;
fn debug_fmt<'a, T: 'a, F: FnMut(&'a T, bool) -> Option<D>, D: fmt::Debug>(
view: &'a Self::View<T>,
type_name: Option<&str>,
field: F,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result;
} }
pub struct ViewUnused<T, V: PRegFlagsViewTrait>(V::UnusedInner<T>); pub struct ViewUnused<T, V: PRegFlagsViewTrait>(V::UnusedInner<T>);
@ -467,6 +473,34 @@ macro_rules! impl_view_trait {
}; };
fields.into_view_unused() fields.into_view_unused()
} }
fn debug_fmt<'a, T: 'a, F: FnMut(&'a T, bool) -> Option<D>, D: fmt::Debug>(
view: &'a Self::View<T>,
type_name: Option<&str>,
mut field: F,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
let $View {
$unused: ViewUnused([$($unused_field,)*]),
$($view_field: $flags_field,)*
} = view;
let mut debug_struct = f.debug_struct(type_name.unwrap_or(stringify!($FlagsMode)));
#[allow(unused_mut)]
let mut any_skipped = false;
$(if let Some(v) = field($flags_field, true) {
debug_struct.field(stringify!($view_field), &v);
} else {
any_skipped = true;
})*
$(if let Some(v) = field($unused_field, false) {
debug_struct.field(stringify!($unused_field), &v);
})*
if any_skipped {
debug_struct.finish_non_exhaustive()
} else {
debug_struct.finish()
}
}
} }
}; };
} }
@ -739,6 +773,46 @@ impl<T: Type> PRegFlags<T> {
pub fn splat_sim(v: impl ToSimValue<Type = T>) -> SimValue<Self> { pub fn splat_sim(v: impl ToSimValue<Type = T>) -> SimValue<Self> {
Self::from_fields_sim(ViewUnused::splat(v.into_sim_value())) Self::from_fields_sim(ViewUnused::splat(v.into_sim_value()))
} }
#[hdl]
pub fn debug_fmt<V: PRegFlagsViewTrait>(
this: &SimValue<Self>,
type_name: Option<&str>,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
if let Some(this) = <dyn Any>::downcast_ref::<SimValue<PRegFlags>>(this) {
V::debug_fmt(
&PRegFlags::view_sim_ref::<V>(this),
type_name,
|v, _| v.then_some(*v),
f,
)
} else {
V::debug_fmt(
&PRegFlags::view_sim_ref::<V>(this),
type_name,
|v, _| Some(*v),
f,
)
}
}
#[hdl]
pub fn debug_fmt_mode(
this: &SimValue<Self>,
short_name: bool,
mode: &SimValue<FlagsMode>,
) -> impl fmt::Debug {
fmt::from_fn(move |f| {
#[hdl(sim)]
match mode {
FlagsMode::PowerISA(_) => {
Self::debug_fmt::<PRegFlagsPowerISA>(this, short_name.then_some("Pwr"), f)
}
FlagsMode::X86(_) => {
Self::debug_fmt::<PRegFlagsX86>(this, short_name.then_some("X86"), f)
}
}
})
}
} }
impl PRegFlags<UIntInRange<0, { PRegFlags::FLAG_COUNT }>> { impl PRegFlags<UIntInRange<0, { PRegFlags::FLAG_COUNT }>> {
@ -762,7 +836,7 @@ impl PRegFlags {
pub const FLAG_COUNT: usize = PRegFlagsAllUnused::UNUSED_INNER_LEN; pub const FLAG_COUNT: usize = PRegFlagsAllUnused::UNUSED_INNER_LEN;
} }
#[hdl(cmp_eq)] #[hdl(cmp_eq, custom_debug(sim))]
/// Unit output register's value -- a combination of an integer/fp register /// Unit output register's value -- a combination of an integer/fp register
/// and flags register and CR field. /// and flags register and CR field.
/// ///
@ -773,6 +847,15 @@ pub struct PRegValue {
pub flags: PRegFlags, pub flags: PRegFlags,
} }
impl SimValueDebug for PRegValue {
fn sim_value_debug(
value: &<Self as Type>::SimValue,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
fmt::Debug::fmt(&Self::debug_fmt::<PRegFlagsPowerISA>(value, Some("Pwr")), f)
}
}
impl PRegValue { impl PRegValue {
#[hdl] #[hdl]
pub fn zeroed() -> Expr<Self> { pub fn zeroed() -> Expr<Self> {
@ -782,4 +865,47 @@ impl PRegValue {
flags: PRegFlags::zeroed(), flags: PRegFlags::zeroed(),
} }
} }
#[hdl]
pub fn zeroed_sim() -> SimValue<Self> {
#[hdl(sim)]
Self {
int_fp: 0u64,
flags: PRegFlags::zeroed_sim(),
}
}
#[hdl]
pub fn debug_fmt<V: PRegFlagsViewTrait>(
this: &<Self as Type>::SimValue,
flags_type_name: Option<&str>,
) -> impl fmt::Debug {
fmt::from_fn(move |f| {
#[hdl(sim)]
let Self { int_fp, flags } = this;
f.debug_struct("PRegValue")
.field("int_fp", int_fp)
.field(
"flags",
&fmt::from_fn(|f| PRegFlags::debug_fmt::<V>(flags, flags_type_name, f)),
)
.finish()
})
}
#[hdl]
pub fn debug_fmt_mode(
this: &SimValue<Self>,
flags_short_name: bool,
mode: &SimValue<FlagsMode>,
) -> impl fmt::Debug {
fmt::from_fn(move |f| {
#[hdl(sim)]
let Self { int_fp, flags } = this;
f.debug_struct("PRegValue")
.field("int_fp", int_fp)
.field(
"flags",
&PRegFlags::debug_fmt_mode(flags, flags_short_name, mode),
)
.finish()
})
}
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use crate::{
config::{CpuConfig, CpuConfig2PowOutRegNumWidth, CpuConfigUnitCount, PhantomConstCpuConfig},
instruction::{L2RegNum, MOpRegNum, PRegNum, UnitNum, UnitOutRegNum},
rename_execute_retire::L2RegFileLen,
};
use fayalite::{int::UIntInRangeInclusiveType, prelude::*};
#[hdl(no_static)]
pub(crate) struct RenameTableEntry<C: PhantomConstGet<CpuConfig>> {
pub(crate) l1: HdlOption<PRegNum<C>>,
pub(crate) l2: HdlOption<L2RegNum>,
}
impl<C: PhantomConstCpuConfig> RenameTableEntry<C> {
#[hdl]
pub(crate) fn const_zero(self) -> SimValue<Self> {
#[hdl(sim)]
Self {
l1: #[hdl(sim)]
(self.l1).HdlSome(self.l1.HdlSome.const_zero()),
l2: #[hdl(sim)]
HdlNone(),
}
}
}
/// make arrays dynamically-sized to avoid putting large types on the stack
#[hdl(get(|c| 1 << MOpRegNum::WIDTH))]
type MOpRegCount<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(no_static)]
pub(crate) struct RenameTableDebugState<C: PhantomConstGet<CpuConfig>> {
entries: ArrayType<TraceAsString<RenameTableEntry<C>>, MOpRegCount<C>>,
l1_ref_counts: ArrayType<
ArrayType<
UIntInRangeInclusiveType<ConstUsize<0>, MOpRegCount<C>>,
CpuConfig2PowOutRegNumWidth<C>,
>,
CpuConfigUnitCount<C>,
>,
l2_ref_counts:
ArrayType<UIntInRangeInclusiveType<ConstUsize<0>, MOpRegCount<C>>, L2RegFileLen<C>>,
config: C,
}
#[derive(Debug)]
pub(crate) struct RenameTable<C: PhantomConstCpuConfig> {
entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]>,
l1_ref_counts: Box<[Box<[usize]>]>,
l2_ref_counts: Box<[usize]>,
config: C,
}
impl<C: PhantomConstCpuConfig> Clone for RenameTable<C> {
fn clone(&self) -> Self {
Self {
entries: self.entries.clone(),
config: self.config.clone(),
l1_ref_counts: self.l1_ref_counts.clone(),
l2_ref_counts: self.l2_ref_counts.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
let Self {
entries,
l1_ref_counts,
l2_ref_counts,
config,
} = self;
entries.clone_from(&source.entries);
l1_ref_counts.clone_from(&source.l1_ref_counts);
l2_ref_counts.clone_from(&source.l2_ref_counts);
*config = source.config;
}
}
#[derive(Debug, Clone)]
pub(crate) enum RenameTableUpdate<C: PhantomConstCpuConfig> {
Write {
unrenamed_reg_num: u32,
new: SimValue<TraceAsString<RenameTableEntry<C>>>,
},
UpdateForReadL2Reg {
dest: SimValue<PRegNum<C>>,
src: SimValue<L2RegNum>,
},
UpdateForWriteL2Reg {
dest: SimValue<L2RegNum>,
src: SimValue<PRegNum<C>>,
},
DropAllL2RegFileOutputs,
}
impl<C: PhantomConstCpuConfig> RenameTable<C> {
pub(crate) fn new(config: C) -> Self {
let entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]> =
vec![
RenameTableEntry[config].const_zero().into_trace_as_string();
1 << MOpRegNum::WIDTH
]
.try_into()
.expect("size is known to match");
Self {
entries,
l1_ref_counts: vec![
vec![0; CpuConfig2PowOutRegNumWidth[config]].into_boxed_slice();
CpuConfigUnitCount[config]
]
.into_boxed_slice(),
l2_ref_counts: vec![0; L2RegFileLen[config]].into_boxed_slice(),
config,
}
}
pub(crate) fn entries(
&self,
) -> &[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH] {
&self.entries
}
#[hdl]
pub(crate) fn to_debug_state(&self) -> SimValue<RenameTableDebugState<C>> {
let Self {
entries,
l1_ref_counts,
l2_ref_counts,
config,
} = self;
let ty = RenameTableDebugState[*config];
#[hdl(sim)]
RenameTableDebugState::<_> {
entries: entries.to_sim_value_with_type(ty.entries),
l1_ref_counts: l1_ref_counts.to_sim_value_with_type(ty.l1_ref_counts),
l2_ref_counts: l2_ref_counts.to_sim_value_with_type(ty.l2_ref_counts),
config,
}
}
#[hdl]
pub(crate) fn l1_ref_counts(&self) -> &[Box<[usize]>] {
let mut expected = vec![
vec![0usize; CpuConfig2PowOutRegNumWidth[self.config]]
.into_boxed_slice();
CpuConfigUnitCount[self.config]
];
for entry in self.entries.iter() {
#[hdl(sim)]
let RenameTableEntry::<_> { l1, l2: _ } = entry.inner();
#[hdl(sim)]
if let HdlSome(l1) = l1 {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
expected[unit_index][UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1;
}
}
}
assert_eq!(*expected, *self.l1_ref_counts);
&self.l1_ref_counts
}
#[hdl]
pub(crate) fn l2_ref_counts(&self) -> &[usize] {
let mut expected = vec![0usize; L2RegNum.l2_reg_count()];
for entry in self.entries.iter() {
#[hdl(sim)]
let RenameTableEntry::<_> { l1: _, l2 } = entry.inner();
#[hdl(sim)]
if let HdlSome(l2) = l2 {
expected[L2RegNum::value_sim(l2)] += 1
}
}
assert_eq!(*expected, *self.l2_ref_counts);
&self.l2_ref_counts
}
#[hdl]
pub(crate) fn update<'a>(&mut self, update: &RenameTableUpdate<C>, rename_table_name: &str) {
let mut update_entry =
|entry: &mut SimValue<TraceAsString<RenameTableEntry<C>>>,
new: SimValue<TraceAsString<RenameTableEntry<C>>>| {
#[hdl(sim)]
let RenameTableEntry::<_> { l1, l2 } = entry.inner();
#[hdl(sim)]
if let HdlSome(l1) = l1 {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
let ref_count = &mut self.l1_ref_counts[unit_index]
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
unreachable!("{rename_table_name}: l1 ref count went negative: {l1:?}")
});
}
}
#[hdl(sim)]
if let HdlSome(l2) = l2 {
let ref_count = &mut self.l2_ref_counts[L2RegNum::value_sim(l2)];
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
unreachable!("{rename_table_name}: l2 ref count went negative: {l2:?}")
});
}
#[hdl(sim)]
let RenameTableEntry::<_> { l1, l2 } = new.inner();
#[hdl(sim)]
if let HdlSome(l1) = l1 {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
let ref_count = &mut self.l1_ref_counts[unit_index]
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
*ref_count += 1;
assert!(
*ref_count <= 1 << MOpRegNum::WIDTH,
"{rename_table_name}: l1 ref count overflowed: {l1:?}",
);
}
}
#[hdl(sim)]
if let HdlSome(l2) = l2 {
let ref_count = &mut self.l2_ref_counts[L2RegNum::value_sim(l2)];
*ref_count += 1;
assert!(
*ref_count <= 1 << MOpRegNum::WIDTH,
"{rename_table_name}: l2 ref count overflowed: {l2:?}",
);
}
*entry = new;
};
match update {
RenameTableUpdate::Write {
unrenamed_reg_num,
new,
} => {
if *unrenamed_reg_num == MOpRegNum::CONST_ZERO_REG_NUM {
// writing to const zero reg does nothing
return;
}
println!("{rename_table_name}: Write: {unrenamed_reg_num:#x} <- {new:?}");
update_entry(&mut self.entries[*unrenamed_reg_num as usize], new.clone());
}
RenameTableUpdate::UpdateForReadL2Reg { dest, src } => {
let new = #[hdl(sim)]
RenameTableEntry::<_> {
l1: #[hdl(sim)]
(HdlOption[dest.ty()]).HdlSome(dest),
l2: #[hdl(sim)]
HdlSome(src),
};
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
#[hdl(sim)]
if let HdlSome(l2) = &entry.inner().l2 {
if L2RegNum::value_sim(l2) == L2RegNum::value_sim(src) {
println!(
"{rename_table_name}: UpdateForReadL2Reg: {unrenamed_reg_num:#x} \
updating from {entry:?} to {new:?}",
);
#[hdl(sim)]
if let HdlSome(_) = &entry.inner().l1 {
unreachable!("l1 should be HdlNone: {entry:?}");
}
update_entry(entry, new.to_trace_as_string());
}
}
}
}
RenameTableUpdate::UpdateForWriteL2Reg { dest, src } => {
let new = #[hdl(sim)]
RenameTableEntry::<_> {
l1: #[hdl(sim)]
(HdlOption[src.ty()]).HdlNone(),
l2: #[hdl(sim)]
HdlSome(dest),
};
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
#[hdl(sim)]
if let HdlSome(l1) = &entry.inner().l1 {
if l1 == src {
println!(
"{rename_table_name}: UpdateForWriteL2Reg: {unrenamed_reg_num:#x} \
updating from {entry:?} to {new:?}",
);
#[hdl(sim)]
if let HdlSome(_) = &entry.inner().l2 {
unreachable!("l2 should be HdlNone: {entry:?}");
}
update_entry(entry, new.to_trace_as_string());
}
}
}
}
RenameTableUpdate::DropAllL2RegFileOutputs => {
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
#[hdl(sim)]
if let HdlSome(_) = &entry.inner().l1 {
#[hdl(sim)]
if let HdlSome(_) = &entry.inner().l2 {
let mut new = entry.inner().clone();
new.l1 = #[hdl(sim)]
(new.l1.ty()).HdlNone();
println!(
"{rename_table_name}: DropAllL2RegFileOutputs: {unrenamed_reg_num:#x} \
updating from {entry:?} to {new:?}",
);
update_entry(entry, new.to_trace_as_string());
}
}
}
}
}
}
#[hdl]
pub(crate) fn used_unit_out_reg_count(&self, unit_index: usize) -> usize {
self.l1_ref_counts()[unit_index]
.iter()
.filter(|ref_count| **ref_count != 0)
.count()
}
}

View file

@ -0,0 +1,564 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use crate::{
config::{
CpuConfig, CpuConfig2PowOutRegNumWidth, CpuConfigRobSize, CpuConfigUnitCount,
PhantomConstCpuConfig,
},
instruction::{
COMMON_MOP_SRC_LEN, L2RegNum, L2RegisterFileMOp, MOp, MOpTrait, PRegNum, UnitNum,
UnitOutRegNum,
},
next_pc::SimValueDefault,
rename_execute_retire::{
L2RegFileLen, MOpId, MOpInUnitState, MOpInstance, NextPcPredictorOp, RenamedMOp,
UnitCausedCancel, rename_table::RenameTableUpdate, zeroed,
},
util::array_vec::ArrayVec,
};
use fayalite::{
int::{UIntInRangeInclusiveType, UIntInRangeType},
prelude::*,
ty::StaticType,
};
use std::{collections::VecDeque, mem};
#[hdl]
type SimOnlyMOpInUnitState = SimOnly<MOpInUnitState>;
#[hdl(no_static)]
struct RobEntryDebugState<C: PhantomConstGet<CpuConfig>> {
/// See [`RobEntry::is_register_fence`]
is_register_fence: Bool,
/// See [`RobEntry::is_register_fence`]
done_waiting_for_register_fences: Bool,
mop: MOpInstance<RenamedMOp<C>>,
unit_index: UIntInRangeType<ConstUsize<0>, CpuConfigUnitCount<C>>,
mop_in_unit_state: SimOnlyMOpInUnitState,
is_speculative: Bool,
all_prior_mops_finished_and_or_caused_cancel: Bool,
output: HdlOption<NextPcPredictorOp<C>>,
caused_cancel: HdlOption<UnitCausedCancel<C>>,
}
impl<C: PhantomConstCpuConfig> SimValueDefault for RobEntryDebugState<C> {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> {
let Self {
mop,
is_register_fence: _,
done_waiting_for_register_fences: _,
unit_index,
mop_in_unit_state: _,
is_speculative: _,
all_prior_mops_finished_and_or_caused_cancel: _,
output,
caused_cancel,
} = self;
#[hdl(sim)]
Self {
mop: zeroed(mop),
is_register_fence: false,
done_waiting_for_register_fences: false,
unit_index: zeroed(unit_index),
mop_in_unit_state: SimOnlyValue::default(),
is_speculative: false,
all_prior_mops_finished_and_or_caused_cancel: false,
output: #[hdl(sim)]
output.HdlNone(),
caused_cancel: #[hdl(sim)]
caused_cancel.HdlNone(),
}
}
}
#[derive(Debug)]
pub(crate) struct RobEntry<C: PhantomConstCpuConfig> {
/// Block this and all later µOps until all prior µOps are finished and didn't cause a cancel.
/// Not to be confused with memory fences.
pub(crate) is_register_fence: bool,
/// See [`Self::is_register_fence`]
pub(crate) done_waiting_for_register_fences: bool,
pub(crate) mop: SimValue<MOpInstance<RenamedMOp<C>>>,
pub(crate) unit_index: usize,
pub(crate) mop_in_unit_state: MOpInUnitState,
pub(crate) is_speculative: bool,
pub(crate) all_prior_mops_finished_and_or_caused_cancel: bool,
pub(crate) output: Option<SimValue<NextPcPredictorOp<C>>>,
pub(crate) caused_cancel: Option<SimValue<UnitCausedCancel<C>>>,
}
impl<C: PhantomConstCpuConfig> RobEntry<C> {
pub(crate) fn new(
mop: SimValue<MOpInstance<RenamedMOp<C>>>,
unit_index: usize,
is_register_fence: bool,
) -> Self {
Self {
mop,
is_register_fence,
done_waiting_for_register_fences: false,
unit_index,
mop_in_unit_state: MOpInUnitState::NotYetEnqueued,
is_speculative: true,
all_prior_mops_finished_and_or_caused_cancel: false,
output: None,
caused_cancel: None,
}
}
fn dest_reg(&self) -> Option<&SimValue<PRegNum<C>>> {
let dest_reg = MOpTrait::dest_reg_sim_ref(self.mop.mop.inner());
let unit_index = UnitNum::index_sim(&dest_reg.unit_num)?;
assert_eq!(unit_index, self.unit_index);
Some(dest_reg)
}
fn unit_out_reg(&self) -> Option<&SimValue<UnitOutRegNum<C>>> {
Some(&self.dest_reg()?.unit_out_reg)
}
pub(crate) fn unit_out_reg_index(&self) -> Option<usize> {
Some(UnitOutRegNum::value_sim(self.unit_out_reg()?))
}
#[hdl]
fn debug_state(&self, config: C) -> SimValue<RobEntryDebugState<C>> {
let Self {
is_register_fence,
done_waiting_for_register_fences,
mop,
unit_index,
mop_in_unit_state,
is_speculative,
all_prior_mops_finished_and_or_caused_cancel,
output,
caused_cancel,
} = self;
let ret_ty = RobEntryDebugState[config];
#[hdl(sim)]
RobEntryDebugState::<C> {
is_register_fence,
done_waiting_for_register_fences,
mop,
unit_index: unit_index.into_sim_value_with_type(ret_ty.unit_index),
mop_in_unit_state: SimOnlyValue::new(*mop_in_unit_state),
is_speculative,
all_prior_mops_finished_and_or_caused_cancel,
output: output.into_sim_value_with_type(ret_ty.output),
caused_cancel: caused_cancel.into_sim_value_with_type(ret_ty.caused_cancel),
}
}
#[hdl]
fn for_each_reg<S>(
&self,
mut shared_state: S,
mut l1_reg: impl FnMut(&mut S, &SimValue<PRegNum<C>>),
mut l2_reg: impl FnMut(&mut S, &SimValue<L2RegNum>),
) {
l1_reg(
&mut shared_state,
MOpTrait::dest_reg_sim_ref(self.mop.mop.inner()),
);
MOpTrait::for_each_src_reg_sim_ref(self.mop.mop.inner(), &mut |l1, _| {
l1_reg(&mut shared_state, l1);
});
#[hdl(sim)]
if let RenamedMOp::<_>::TransformedMove(mop) = self.mop.mop.inner() {
#[hdl(sim)]
match mop {
L2RegisterFileMOp::<_, _>::ReadL2Reg(v) => {
l2_reg(&mut shared_state, &v.common.imm);
}
L2RegisterFileMOp::<_, _>::WriteL2Reg(v) => {
l2_reg(&mut shared_state, &v.common.imm);
}
}
}
}
}
#[hdl]
struct RobEntriesDebugState {
unrenamed: MOpInstance<MOp>,
/// number of renamed &micro;Ops that this unrenamed &micro;Op corresponds to
renamed_entries_len: UInt<8>,
}
impl SimValueDefault for RobEntriesDebugState {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> {
let Self {
unrenamed,
renamed_entries_len,
} = self;
#[hdl(sim)]
Self {
unrenamed: zeroed(unrenamed),
renamed_entries_len: renamed_entries_len.sim_value_default(),
}
}
}
#[derive(Debug)]
struct RobEntries<C: PhantomConstCpuConfig> {
unrenamed: SimValue<MOpInstance<MOp>>,
rename_table_updates: Vec<RenameTableUpdate<C>>,
renamed_entries: VecDeque<RobEntry<C>>,
}
impl<C: PhantomConstCpuConfig> RobEntries<C> {
#[hdl]
fn debug_state(&self) -> SimValue<RobEntriesDebugState> {
let Self {
unrenamed,
rename_table_updates: _,
renamed_entries,
} = self;
#[hdl(sim)]
RobEntriesDebugState {
unrenamed,
renamed_entries_len: u8::try_from(renamed_entries.len())
.expect("renamed_entries.len() should fit in u8"),
}
}
}
#[hdl(get(|c| c.rob_size.get() * (1 + COMMON_MOP_SRC_LEN)))]
type L1RegMaxRefCount<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(no_static)]
pub(crate) struct ReorderBufferDebugState<C: PhantomConstGet<CpuConfig>> {
next_renamed_mop_id: MOpId,
entries: ArrayVec<RobEntriesDebugState, CpuConfigRobSize<C>>,
incomplete_back_entry: HdlOption<RobEntriesDebugState>,
renamed: ArrayVec<RobEntryDebugState<C>, CpuConfigRobSize<C>>,
l1_reg_ref_counts: ArrayType<
ArrayType<
UIntInRangeInclusiveType<ConstUsize<0>, L1RegMaxRefCount<C>>,
CpuConfig2PowOutRegNumWidth<C>,
>,
CpuConfigUnitCount<C>,
>,
l2_reg_ref_counts:
ArrayType<UIntInRangeInclusiveType<ConstUsize<0>, CpuConfigRobSize<C>>, L2RegFileLen<C>>,
config: C,
}
impl<C: PhantomConstCpuConfig> SimValueDefault for ReorderBufferDebugState<C> {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> {
let Self {
next_renamed_mop_id,
entries,
incomplete_back_entry,
renamed,
l1_reg_ref_counts,
l2_reg_ref_counts,
config,
} = self;
#[hdl(sim)]
Self {
next_renamed_mop_id: next_renamed_mop_id.sim_value_default(),
entries: entries.sim_value_default(),
incomplete_back_entry: incomplete_back_entry.sim_value_default(),
renamed: renamed.sim_value_default(),
l1_reg_ref_counts: zeroed(l1_reg_ref_counts),
l2_reg_ref_counts: zeroed(l2_reg_ref_counts),
config,
}
}
}
#[derive(Debug)]
pub(crate) struct ReorderBuffer<C: PhantomConstCpuConfig> {
next_renamed_mop_id: SimValue<MOpId>,
entries: VecDeque<RobEntries<C>>,
incomplete_back_entry: Option<RobEntries<C>>,
l1_reg_ref_counts: Box<[Box<[usize]>]>,
l2_reg_ref_counts: Box<[usize]>,
config: C,
}
impl<C: PhantomConstCpuConfig> ReorderBuffer<C> {
pub(crate) fn new(config: C) -> Self {
Self {
next_renamed_mop_id: MOpId.zero().into_sim_value(),
entries: VecDeque::new(),
incomplete_back_entry: None,
l1_reg_ref_counts: vec![
vec![0; CpuConfig2PowOutRegNumWidth[config]].into_boxed_slice();
CpuConfigUnitCount[config]
]
.into_boxed_slice(),
l2_reg_ref_counts: vec![0; L2RegNum.l2_reg_count()].into_boxed_slice(),
config,
}
}
#[hdl]
pub(crate) fn l1_reg_ref_counts(&self) -> &[Box<[usize]>] {
let mut expected = vec![
vec![0usize; CpuConfig2PowOutRegNumWidth[self.config]]
.into_boxed_slice();
CpuConfigUnitCount[self.config]
];
for entry in self.renamed() {
entry.for_each_reg(
(),
|(), l1| {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
expected[unit_index][UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1
}
},
|(), _l2| {},
);
}
assert_eq!(*expected, *self.l1_reg_ref_counts);
&self.l1_reg_ref_counts
}
#[hdl]
pub(crate) fn l2_reg_ref_counts(&self) -> &[usize] {
let mut expected = vec![0usize; L2RegNum.l2_reg_count()];
for entry in self.renamed() {
entry.for_each_reg(
(),
|(), _l1| {},
|(), l2| expected[L2RegNum::value_sim(l2)] += 1,
);
}
assert_eq!(*expected, *self.l2_reg_ref_counts);
&self.l2_reg_ref_counts
}
#[hdl]
pub(crate) fn debug_state(&self) -> SimValue<ReorderBufferDebugState<C>> {
let Self {
next_renamed_mop_id,
entries,
incomplete_back_entry,
l1_reg_ref_counts,
l2_reg_ref_counts,
config,
} = self;
let ty = ReorderBufferDebugState[*config];
#[hdl(sim)]
ReorderBufferDebugState::<_> {
next_renamed_mop_id,
entries: ty
.entries
.from_iter_sim(
zeroed(StaticType::TYPE),
entries.iter().map(RobEntries::debug_state),
)
.expect("known to fit"),
incomplete_back_entry: incomplete_back_entry.as_ref().map(|v| v.debug_state()),
renamed: ty
.renamed
.from_iter_sim(
ty.renamed.element().sim_value_default(),
self.renamed().map(|v| v.debug_state(*config)),
)
.ok()
.expect("known to fit"),
l1_reg_ref_counts: l1_reg_ref_counts.to_sim_value_with_type(ty.l1_reg_ref_counts),
l2_reg_ref_counts: l2_reg_ref_counts.to_sim_value_with_type(ty.l2_reg_ref_counts),
config,
}
}
pub(crate) fn unrenamed_len(&self) -> usize {
self.entries.len()
}
pub(crate) fn unrenamed(
&self,
) -> impl DoubleEndedIterator<Item = &SimValue<MOpInstance<MOp>>> + Clone {
self.entries.iter().map(|v| &v.unrenamed)
}
fn retire_groups_unrenamed_ranges(
&self,
) -> impl Clone + Iterator<Item = std::ops::Range<usize>> {
let mut next_group_start = 0;
self.entries
.iter()
.enumerate()
.filter_map(move |(index, entry)| {
if *entry.unrenamed.is_last_mop_in_insn {
let group_start = next_group_start;
next_group_start = index + 1;
Some(group_start..next_group_start)
} else {
None
}
})
}
pub(crate) fn retire_groups(
&self,
) -> impl Clone + Iterator<Item: DoubleEndedIterator<Item = &VecDeque<RobEntry<C>>> + Clone>
{
self.retire_groups_unrenamed_ranges().map(|range| {
self.entries
.range(range)
.map(|entries| &entries.renamed_entries)
})
}
pub(crate) fn renamed_len(&self) -> usize {
let Self {
next_renamed_mop_id: _,
entries,
incomplete_back_entry,
l1_reg_ref_counts: _,
l2_reg_ref_counts: _,
config: _,
} = self;
entries
.iter()
.chain(incomplete_back_entry)
.map(|entries| entries.renamed_entries.len())
.sum()
}
pub(crate) fn renamed(&self) -> impl DoubleEndedIterator<Item = &RobEntry<C>> + Clone {
let Self {
next_renamed_mop_id: _,
entries,
incomplete_back_entry,
l1_reg_ref_counts: _,
l2_reg_ref_counts: _,
config: _,
} = self;
entries
.iter()
.chain(incomplete_back_entry)
.flat_map(|entries| &entries.renamed_entries)
}
pub(crate) fn renamed_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut RobEntry<C>> {
let Self {
next_renamed_mop_id: _,
entries,
incomplete_back_entry,
l1_reg_ref_counts: _,
l2_reg_ref_counts: _,
config: _,
} = self;
entries
.iter_mut()
.chain(incomplete_back_entry)
.flat_map(|entries| &mut entries.renamed_entries)
}
fn try_renamed_by_id_mut(&mut self, id: &SimValue<MOpId>) -> Option<&mut RobEntry<C>> {
self.renamed_mut().find(|v| v.mop.id == *id)
}
pub(crate) fn renamed_by_id_mut(&mut self, id: &SimValue<MOpId>) -> &mut RobEntry<C> {
match self.try_renamed_by_id_mut(id) {
Some(v) => v,
None => panic!("MOpId not found: {id:?}"),
}
}
pub(crate) fn renamed_push_back_with_new_id(
&mut self,
unrenamed: &SimValue<MOpInstance<MOp>>,
mut renamed: RobEntry<C>,
) -> &SimValue<MOpId> {
let replacement_id = self
.next_renamed_mop_id
.as_int()
.wrapping_add(1)
.into_sim_value();
renamed.mop.id = mem::replace(&mut self.next_renamed_mop_id, replacement_id);
println!("renamed_push_back_with_new_id: {:?}", renamed.mop);
renamed.for_each_reg(
(),
|(), l1| {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
self.l1_reg_ref_counts[unit_index]
[UnitOutRegNum::value_sim(&l1.unit_out_reg)] += 1;
}
},
|(), l2| self.l2_reg_ref_counts[L2RegNum::value_sim(l2)] += 1,
);
let renamed_entries = &mut self
.incomplete_back_entry
.get_or_insert_with(|| RobEntries {
unrenamed: unrenamed.clone(),
rename_table_updates: Vec::new(),
renamed_entries: VecDeque::new(),
})
.renamed_entries;
renamed_entries.push_back(renamed);
&renamed_entries.back().expect("just pushed").mop.id
}
pub(crate) fn has_incomplete_back_entry(&self) -> bool {
self.incomplete_back_entry.is_some()
}
pub(crate) fn finished_unrenamed_push_back(&mut self, unrenamed: &SimValue<MOpInstance<MOp>>) {
let entry = self
.incomplete_back_entry
.take()
.unwrap_or_else(|| RobEntries {
unrenamed: unrenamed.clone(),
rename_table_updates: Vec::new(),
renamed_entries: VecDeque::new(),
});
self.entries.push_back(entry);
}
pub(crate) fn clear(&mut self) {
let Self {
next_renamed_mop_id: _,
entries,
incomplete_back_entry,
l1_reg_ref_counts,
l2_reg_ref_counts,
config: _,
} = self;
entries.clear();
l2_reg_ref_counts.fill(0);
for i in l1_reg_ref_counts {
i.fill(0);
}
*incomplete_back_entry = None;
}
pub(crate) fn unrenamed_back_append_rename_table_update(
&mut self,
unrenamed: &SimValue<MOpInstance<MOp>>,
update: RenameTableUpdate<C>,
) {
self.incomplete_back_entry
.get_or_insert_with(|| RobEntries {
unrenamed: unrenamed.clone(),
rename_table_updates: Vec::new(),
renamed_entries: VecDeque::new(),
})
.rename_table_updates
.push(update);
}
pub(crate) fn all_mops_are_finished_and_or_caused_cancel(&self) -> bool {
self.renamed().next().is_none_or(|entry| {
entry.all_prior_mops_finished_and_or_caused_cancel
&& entry.mop_in_unit_state.is_finished_and_or_caused_cancel()
})
}
pub(crate) fn entries_pop_front(
&mut self,
) -> Option<(Vec<RenameTableUpdate<C>>, VecDeque<RobEntry<C>>)> {
let RobEntries {
unrenamed: _,
rename_table_updates,
renamed_entries,
} = self.entries.pop_front()?;
for entry in &renamed_entries {
entry.for_each_reg(
(),
|(), l1| {
if let Some(unit_index) = UnitNum::index_sim(&l1.unit_num) {
let ref_count = &mut self.l1_reg_ref_counts[unit_index]
[UnitOutRegNum::value_sim(&l1.unit_out_reg)];
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
unreachable!("ReorderBuffer: l1 ref count went negative: {l1:?}")
});
}
},
|(), l2| {
let ref_count = &mut self.l2_reg_ref_counts[L2RegNum::value_sim(l2)];
*ref_count = ref_count.checked_sub(1).unwrap_or_else(|| {
unreachable!("ReorderBuffer: l2 ref count went negative: {l2:?}")
});
},
);
}
Some((rename_table_updates, renamed_entries))
}
}

View file

@ -0,0 +1,207 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use crate::{config::CpuConfig, rename_execute_retire::ExecuteToUnitInterface};
use fayalite::{
bundle::{BundleField, BundleType, NoBuilder},
expr::ops::FieldAccess,
intern::{Intern, Interned, Memoize},
prelude::*,
ty::{
OpaqueSimValue, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
SimValueDebug,
},
};
use std::{fmt, marker::PhantomData, ops::Index};
/// a bundle with fields of type [`ExecuteToUnitInterface<C>`] for each unit
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct ExecuteToUnitInterfaces<C: Type + PhantomConstGet<CpuConfig>> {
bundle_ty: Bundle,
config: C,
}
impl<C: Type + PhantomConstGet<CpuConfig>> fmt::Debug for ExecuteToUnitInterfaces<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ExecuteToUnitInterfaces ")?;
let fields = self.bundle_ty.fields();
let field_offsets = self.bundle_ty.field_offsets();
f.debug_set()
.entries(
fields.iter().enumerate().map(|(index, field)| {
field.fmt_debug_in_struct(field_offsets[index].bit_width)
}),
)
.finish()
}
}
const CONFIG_FIELD_NAME: &str = "config";
impl<C: Type + PhantomConstGet<CpuConfig>> ExecuteToUnitInterfaces<C> {
pub fn new(config: C) -> Self {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
struct MyMemoize<C>(PhantomData<C>);
impl<C: Type + PhantomConstGet<CpuConfig>> Memoize for MyMemoize<C> {
type Input = C;
type InputOwned = C;
type Output = ExecuteToUnitInterfaces<C>;
fn inner(self, &config: &Self::Input) -> Self::Output {
let unit_ty = ExecuteToUnitInterface[config].canonical();
let bundle_ty = Bundle::new(
(0..config.get().units.len())
.map(|unit_index| BundleField {
name: format!(
"u{unit_index}_{:?}",
config.get().units[unit_index].kind,
)
.intern_deref(),
flipped: false,
ty: unit_ty,
})
.chain([BundleField {
name: CONFIG_FIELD_NAME.intern(),
flipped: false,
ty: config.canonical(),
}])
.collect(),
);
ExecuteToUnitInterfaces { bundle_ty, config }
}
}
MyMemoize(PhantomData).get_owned(config)
}
pub fn bundle_ty(self) -> Bundle {
self.bundle_ty
}
pub fn config(self) -> C {
self.config
}
#[track_caller]
pub fn unit_field_name(self, unit_index: usize) -> Interned<str> {
assert!(unit_index < self.config.get().units.len());
self.bundle_ty.fields()[unit_index].name
}
pub fn unit_fields(
this: impl ToExpr<Type = Self>,
) -> Interned<[Expr<ExecuteToUnitInterface<C>>]> {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
struct MyMemoize<C>(PhantomData<C>);
impl<C: Type + PhantomConstGet<CpuConfig>> Memoize for MyMemoize<C> {
type Input = Expr<ExecuteToUnitInterfaces<C>>;
type InputOwned = Expr<ExecuteToUnitInterfaces<C>>;
type Output = Interned<[Expr<ExecuteToUnitInterface<C>>]>;
fn inner(self, this: &Self::Input) -> Self::Output {
let bundle = Expr::as_bundle(*this);
(0..this.ty().config.get().units.len())
.map(|unit_index| FieldAccess::new_by_index(bundle, unit_index).to_expr())
.collect()
}
}
MyMemoize(PhantomData).get_owned(this.to_expr())
}
}
#[doc(hidden)]
pub struct ExecuteToUnitInterfacesWithoutGenerics(());
#[expect(non_upper_case_globals)]
pub const ExecuteToUnitInterfaces: ExecuteToUnitInterfacesWithoutGenerics =
ExecuteToUnitInterfacesWithoutGenerics(());
impl<C: Type + PhantomConstGet<CpuConfig>> Index<C> for ExecuteToUnitInterfacesWithoutGenerics {
type Output = ExecuteToUnitInterfaces<C>;
fn index(&self, config: C) -> &Self::Output {
Interned::into_inner(ExecuteToUnitInterfaces::new(config).intern())
}
}
impl<C: Type + PhantomConstGet<CpuConfig>> SimValueDebug for ExecuteToUnitInterfaces<C> {
fn sim_value_debug(
value: &<Self as Type>::SimValue,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
fmt::Debug::fmt(value, f)
}
}
impl<C: Type + PhantomConstGet<CpuConfig>> Type for ExecuteToUnitInterfaces<C> {
type BaseType = Bundle;
type MaskType = Bundle;
type SimValue = OpaqueSimValue;
type MatchVariant = <Bundle as Type>::MatchVariant;
type MatchActiveScope = <Bundle as Type>::MatchActiveScope;
type MatchVariantAndInactiveScope = <Bundle as Type>::MatchVariantAndInactiveScope;
type MatchVariantsIter = <Bundle as Type>::MatchVariantsIter;
fn match_variants(
this: Expr<Self>,
source_location: SourceLocation,
) -> Self::MatchVariantsIter {
Type::match_variants(Expr::as_bundle(this), source_location)
}
fn mask_type(&self) -> Self::MaskType {
self.bundle_ty.mask_type()
}
fn canonical(&self) -> CanonicalType {
self.bundle_ty.canonical()
}
fn from_canonical(canonical_type: CanonicalType) -> Self {
let bundle_ty = Bundle::from_canonical(canonical_type);
let config = if let Some(BundleField {
name,
flipped: false,
ty,
}) = bundle_ty.fields().last()
&& **name == *CONFIG_FIELD_NAME
{
C::from_canonical(*ty)
} else {
panic!(
"ExecuteToUnitInterfaces must have `{}` field",
CONFIG_FIELD_NAME
);
};
let retval = Self::new(config);
assert_eq!(bundle_ty, retval.bundle_ty);
retval
}
fn source_location() -> SourceLocation {
SourceLocation::caller()
}
fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue {
<Bundle as Type>::sim_value_from_opaque(&self.bundle_ty, opaque)
}
fn sim_value_clone_from_opaque(
&self,
value: &mut Self::SimValue,
opaque: OpaqueSimValueSlice<'_>,
) {
<Bundle as Type>::sim_value_clone_from_opaque(&self.bundle_ty, value, opaque)
}
fn sim_value_to_opaque<'w>(
&self,
value: &Self::SimValue,
writer: OpaqueSimValueWriter<'w>,
) -> OpaqueSimValueWritten<'w> {
<Bundle as Type>::sim_value_to_opaque(&self.bundle_ty, value, writer)
}
}
impl<C: Type + PhantomConstGet<CpuConfig>> BundleType for ExecuteToUnitInterfaces<C> {
type Builder = NoBuilder;
fn fields(&self) -> Interned<[BundleField]> {
self.bundle_ty.fields()
}
}

View file

@ -0,0 +1,41 @@
%% SPDX-License-Identifier: LGPL-3.0-or-later
%% See Notices.txt for copyright information
stateDiagram-v2
direction LR
state "Inputs not ready<br/>Speculative<br/>Can cause cancel" as inr_s_c
state "Inputs not ready<br/>Speculative" as inr_s
state "Inputs ready<br/>Speculative<br/>Can cause cancel" as ir_s_c
state "Inputs ready<br/>Speculative" as ir_s
state "Inputs ready<br/>Can cause cancel" as ir_c
state "Inputs ready" as ir
state "Output ready<br/>Speculative<br/>Can cause cancel" as or_s_c
state "Output ready<br/>Can cause cancel" as or_c
state "Output ready<br/>Speculative" as or_s
state "Output ready" as or
[*] --> inr_s_c: Enqueue
inr_s_c --> inr_s: Can't cause cancel
ir_s_c --> ir_s: Can't cause cancel
ir_c --> ir: Can't cause cancel
or_s_c --> or_s: Can't cause cancel
or_c --> or: Can't cause cancel
ir_s_c --> ir_c: No longer speculative
ir_s --> ir: No longer speculative
or_s_c --> or_c: No longer speculative
or_s --> or: No longer speculative
inr_s_c --> ir_s_c: Inputs ready
inr_s --> ir_s: Inputs ready
ir_s_c --> or_s_c: Output Ready
ir_c --> or_c: Output Ready
ir_s --> or_s: Output Ready
ir --> or: Output Ready
or_s_c --> [*]: Finish
or_c --> [*]: Finish
or_s --> [*]: Finish
or --> [*]: Finish

View file

@ -2,11 +2,11 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
use crate::{ use crate::{
config::CpuConfig, config::{CpuConfig, PhantomConstCpuConfig},
instruction::{ instruction::{
AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait, AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait,
MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, RenamedMOp, UnitOutRegNum, MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, PRegNum, RenamedMOp,
mop_enum, UnitOutRegNum, mop_enum,
}, },
register::{FlagsMode, PRegValue}, register::{FlagsMode, PRegValue},
unit::unit_base::UnitToRegAlloc, unit::unit_base::UnitToRegAlloc,
@ -26,13 +26,13 @@ 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, $SrcReg:ident: Type, #[MOp(get_ty = $transformed_move_op_get_ty:expr)] $TransformedMoveOp:ident: Type> {
$( $(
$(#[transformed_move $($transformed_move:tt)*])? $(#[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, $extract_sim:ident, $extract_sim_ref:ident, $extract_sim_mut:ident)]
$(#[$variant_meta:meta])* $(#[$variant_meta:meta])*
$Unit:ident($Op:ty), $Unit:ident($Op:ty),
)* )*
@ -48,7 +48,7 @@ macro_rules! all_units {
} }
impl $UnitKind { impl $UnitKind {
pub fn unit(self, config: &CpuConfig, unit_index: usize) -> DynUnit { pub fn unit(self, config: PhantomConst<CpuConfig>, unit_index: usize) -> DynUnit {
match self { match self {
$($UnitKind::$Unit => $create_dyn_unit_fn(config, unit_index),)* $($UnitKind::$Unit => $create_dyn_unit_fn(config, unit_index),)*
} }
@ -83,15 +83,15 @@ macro_rules! all_units {
mop_enum! { mop_enum! {
#[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,
$SrcRegWidth: Size, $SrcReg: Type,
#[MOp(get_ty = $transformed_move_op_get_ty)] $TransformedMoveOp: Type, #[MOp(get_ty = $transformed_move_op_get_ty)] $TransformedMoveOp: Type,
#[MOpVisitVariants] [ #[MOpVisitVariants] [
$TransformedMoveOp: MOpVisitVariants<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, $TransformedMoveOp: MOpVisitVariants<DestReg = $DestReg, SrcReg = $SrcReg>,
$($Op: MOpVisitVariants<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>,)* $($Op: MOpVisitVariants<DestReg = $DestReg, SrcReg = $SrcReg>,)*
] ]
> { > {
$( $(
@ -101,7 +101,7 @@ macro_rules! all_units {
} }
} }
impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> { impl<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcReg, $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]
@ -112,6 +112,15 @@ macro_rules! all_units {
} }
unit_kind unit_kind
} }
#[hdl]
$vis fn kind_sim(expr: &SimValue<Self>) -> UnitKind {
#![allow(unreachable_patterns)]
#[hdl(sim)]
match expr {
$(Self::$Unit(_) => $UnitKind::$Unit,)*
_ => unreachable!(),
}
}
$( $(
#[hdl] #[hdl]
$vis fn $extract(expr: impl ToExpr<Type = Self>) -> Expr<HdlOption<$Op>> { $vis fn $extract(expr: impl ToExpr<Type = Self>) -> Expr<HdlOption<$Op>> {
@ -126,19 +135,47 @@ macro_rules! all_units {
} }
$extract $extract
} }
#[hdl]
$vis fn $extract_sim(expr: impl ToSimValue<Type = Self>) -> Option<SimValue<$Op>> {
let expr = expr.into_sim_value();
#[hdl(sim)]
if let Self::$Unit(v) = expr {
Some(v)
} else {
None
}
}
#[hdl]
$vis fn $extract_sim_ref(expr: &SimValue<Self>) -> Option<&SimValue<$Op>> {
#[hdl(sim)]
if let Self::$Unit(v) = expr {
Some(v)
} else {
None
}
}
#[hdl]
$vis fn $extract_sim_mut(expr: &mut SimValue<Self>) -> Option<&mut SimValue<$Op>> {
#[hdl(sim)]
if let Self::$Unit(v) = expr {
Some(v)
} else {
None
}
}
)* )*
$vis fn with_transformed_move_op_ty<T>(self, new_transformed_move_op_ty: T) -> $UnitMOpEnum<$DestReg, $SrcRegWidth, T> $vis fn with_transformed_move_op_ty<T>(self, new_transformed_move_op_ty: T) -> $UnitMOpEnum<$DestReg, $SrcReg, T>
where where
T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, $TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
{ {
$UnitMOpEnum[self.dest_reg_ty()][self.src_reg_width()][new_transformed_move_op_ty] $UnitMOpEnum[self.dest_reg_ty()][self.src_reg_ty()][new_transformed_move_op_ty]
} }
} }
all_units! { all_units! {
@split_by_transformed_move @split_by_transformed_move
$vis enum $UnitMOpEnum<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> { $vis enum $UnitMOpEnum<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> {
$( $(
$(#[transformed_move $($transformed_move)*])? $(#[transformed_move $($transformed_move)*])?
$Unit($Op), $Unit($Op),
@ -163,23 +200,23 @@ macro_rules! all_units {
}; };
( (
@split_by_transformed_move @split_by_transformed_move
$vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcRegWidth:ident: Size, $TransformedMoveOp:ident: Type> { $vis:vis enum $UnitMOpEnum:ident<$DestReg:ident: Type, $SrcReg:ident: Type, $TransformedMoveOp:ident: Type> {
$($BeforeUnit:ident($BeforeOp:ty),)* $($BeforeUnit:ident($BeforeOp:ty),)*
#[transformed_move] #[transformed_move]
$TransformedMove:ident($TransformedMoveOp2:ty), $TransformedMove:ident($TransformedMoveOp2:ty),
$($AfterUnit:ident($AfterOp:ty),)* $($AfterUnit:ident($AfterOp:ty),)*
} }
) => { ) => {
impl<$DestReg: Type, $SrcRegWidth: Size, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcRegWidth, $TransformedMoveOp> { impl<$DestReg: Type, $SrcReg: Type, $TransformedMoveOp: Type> $UnitMOpEnum<$DestReg, $SrcReg, $TransformedMoveOp> {
#[hdl] #[hdl]
$vis fn try_with_transformed_move_op<T>( $vis fn try_with_transformed_move_op<T>(
this: impl ToExpr<Type = Self>, this: impl ToExpr<Type = Self>,
new_transformed_move_op_ty: T, new_transformed_move_op_ty: T,
connect_transformed_move_op: impl FnOnce(Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>>, Expr<$TransformedMoveOp>), connect_transformed_move_op: impl FnOnce(Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcReg, T>>>, Expr<$TransformedMoveOp>),
) -> Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcRegWidth, T>>> ) -> Expr<HdlOption<$UnitMOpEnum<$DestReg, $SrcReg, T>>>
where where
T: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcRegWidth = $SrcRegWidth>, $TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
{ {
let this = this.to_expr(); let this = this.to_expr();
let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty); let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty);
@ -196,12 +233,51 @@ macro_rules! all_units {
} }
with_transformed_move_op with_transformed_move_op
} }
#[hdl]
$vis fn try_with_transformed_move_op_sim<T, E>(
this: impl ToSimValue<Type = Self>,
new_transformed_move_op_ty: T,
f: impl FnOnce(SimValue<$TransformedMoveOp>) -> Result<SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>, E>,
) -> Result<SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>, E>
where
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
{
#![allow(unreachable_patterns)]
let this = this.into_sim_value();
let new_ty = this.ty().with_transformed_move_op_ty(new_transformed_move_op_ty);
#[hdl(sim)]
match this {
$(Self::$BeforeUnit(unit) => Ok(
#[hdl(sim)]
new_ty.$BeforeUnit(unit)
),)*
Self::$TransformedMove(unit) => f(unit),
$(Self::$AfterUnit(unit) => Ok(
#[hdl(sim)]
new_ty.$AfterUnit(unit)
),)*
_ => unreachable!(),
}
}
$vis fn with_transformed_move_op_sim<T>(
this: impl ToSimValue<Type = Self>,
new_transformed_move_op_ty: T,
f: impl FnOnce(SimValue<$TransformedMoveOp>) -> SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>,
) -> SimValue<$UnitMOpEnum<$DestReg, $SrcReg, T>>
where
T: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
$TransformedMoveOp: MOpTrait<DestReg = $DestReg, SrcReg = $SrcReg>,
{
let Ok::<_, std::convert::Infallible>(retval) = Self::try_with_transformed_move_op_sim(this, new_transformed_move_op_ty, move |v| Ok(f(v)));
retval
}
} }
const _: () = { const _: () = {
#[hdl] #[hdl]
type $DestReg = MOpDestReg; type $DestReg = MOpDestReg;
type $SrcRegWidth = ConstUsize<{ MOpRegNum::WIDTH }>; type $SrcReg = MOpRegNum;
$(impl MOpInto<MOp> for $BeforeOp { $(impl MOpInto<MOp> for $BeforeOp {
fn mop_into_ty(self) -> MOp { fn mop_into_ty(self) -> MOp {
@ -222,21 +298,21 @@ macro_rules! all_units {
})* })*
}; };
$(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $BeforeOp { $(impl<$DestReg: Type, $SrcReg: Type> MOpInto<RenamedMOp<$DestReg, $SrcReg>> for $BeforeOp {
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> { fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcReg> {
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)] RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_ty(self)]
} }
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> { fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcReg>> {
MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(this.ty()).$BeforeUnit(this) MOpInto::<RenamedMOp<$DestReg, $SrcReg>>::mop_into_ty(this.ty()).$BeforeUnit(this)
} }
})* })*
$(impl<$DestReg: Type, $SrcRegWidth: Size> MOpInto<RenamedMOp<$DestReg, $SrcRegWidth>> for $AfterOp { $(impl<$DestReg: Type, $SrcReg: Type> MOpInto<RenamedMOp<$DestReg, $SrcReg>> for $AfterOp {
fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcRegWidth> { fn mop_into_ty(self) -> RenamedMOp<$DestReg, $SrcReg> {
RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_width(self)] RenamedMOp[MOpTrait::dest_reg_ty(self)][MOpTrait::src_reg_ty(self)]
} }
fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcRegWidth>> { fn mop_into(this: Expr<Self>) -> Expr<RenamedMOp<$DestReg, $SrcReg>> {
MOpInto::<RenamedMOp<$DestReg, $SrcRegWidth>>::mop_into_ty(this.ty()).$AfterUnit(this) MOpInto::<RenamedMOp<$DestReg, $SrcReg>>::mop_into_ty(this.ty()).$AfterUnit(this)
} }
})* })*
}; };
@ -245,24 +321,24 @@ 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, SrcReg: Type,
#[MOp(get_ty = |this: UnitMOp<DestReg, SrcRegWidth, TransformedMoveOp>, new_dest_reg, new_src_reg_width| { #[MOp(get_ty = |this: UnitMOp<DestReg, SrcReg, TransformedMoveOp>, new_dest_reg, new_src_reg| {
this.TransformedMove.mapped_ty(new_dest_reg, new_src_reg_width) this.TransformedMove.mapped_ty(new_dest_reg, new_src_reg)
})] TransformedMoveOp: Type })] 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, alu_branch_mop_sim, alu_branch_mop_sim_ref, alu_branch_mop_sim_mut)]
AluBranch(AluBranchMOp<DestReg, SrcRegWidth>), AluBranch(AluBranchMOp<DestReg, SrcReg>),
#[transformed_move] #[transformed_move]
#[create_dyn_unit_fn = |config, unit_index| todo!()] #[create_dyn_unit_fn = |config, unit_index| todo!()]
#[extract = transformed_move_mop] #[extract(transformed_move_mop, transformed_move_mop_sim, transformed_move_mop_sim_ref, transformed_move_mop_sim_mut)]
TransformedMove(TransformedMoveOp), 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, load_store_mop_sim, load_store_mop_sim_ref, load_store_mop_sim_mut)]
LoadStore(LoadStoreMOp<DestReg, SrcRegWidth>), LoadStore(LoadStoreMOp<DestReg, SrcReg>),
} }
} }
@ -277,9 +353,9 @@ pub struct UnitResultCompleted<ExtraOut> {
pub extra_out: ExtraOut, pub extra_out: ExtraOut,
} }
#[hdl(cmp_eq)] #[hdl(cmp_eq, no_static)]
pub struct UnitOutputWrite<OutRegNumWidth: Size> { pub struct UnitOutputWrite<C: PhantomConstGet<CpuConfig>> {
pub which: UnitOutRegNum<OutRegNumWidth>, pub which: UnitOutRegNum<C>,
pub value: PRegValue, pub value: PRegValue,
} }
@ -300,21 +376,21 @@ impl<ExtraOut: Type> UnitResult<ExtraOut> {
} }
} }
#[hdl] #[hdl(no_static)]
pub struct UnitOutput<OutRegNumWidth: Size, ExtraOut> { pub struct UnitOutput<C: PhantomConstGet<CpuConfig>, ExtraOut> {
pub which: UnitOutRegNum<OutRegNumWidth>, pub which: UnitOutRegNum<C>,
pub result: UnitResult<ExtraOut>, pub result: UnitResult<ExtraOut>,
} }
impl<OutRegNumWidth: Size, ExtraOut: Type> UnitOutput<OutRegNumWidth, ExtraOut> { impl<C: PhantomConstCpuConfig, ExtraOut: Type> UnitOutput<C, ExtraOut> {
pub fn extra_out_ty(self) -> ExtraOut { pub fn extra_out_ty(self) -> ExtraOut {
self.result.extra_out_ty() self.result.extra_out_ty()
} }
} }
#[hdl(cmp_eq)] #[hdl(cmp_eq, no_static)]
pub struct UnitCancelInput<OutRegNumWidth: Size> { pub struct UnitCancelInput<C: PhantomConstGet<CpuConfig>> {
pub which: UnitOutRegNum<OutRegNumWidth>, pub which: UnitOutRegNum<C>,
} }
pub trait UnitTrait: pub trait UnitTrait:
@ -332,7 +408,9 @@ pub trait UnitTrait:
fn extract_mop( fn extract_mop(
&self, &self,
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
) -> Expr<HdlOption<Self::MOp>>; ) -> Expr<HdlOption<Self::MOp>>;
fn module(&self) -> Interned<Module<Self::Type>>; fn module(&self) -> Interned<Module<Self::Type>>;
@ -340,7 +418,7 @@ pub trait UnitTrait:
fn unit_to_reg_alloc( fn unit_to_reg_alloc(
&self, &self,
this: Expr<Self::Type>, this: Expr<Self::Type>,
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>>; ) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>>;
fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain>; fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain>;
@ -390,7 +468,9 @@ impl UnitTrait for DynUnit {
fn extract_mop( fn extract_mop(
&self, &self,
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
) -> Expr<HdlOption<Self::MOp>> { ) -> Expr<HdlOption<Self::MOp>> {
self.unit.extract_mop(mop) self.unit.extract_mop(mop)
} }
@ -402,7 +482,7 @@ impl UnitTrait for DynUnit {
fn unit_to_reg_alloc( fn unit_to_reg_alloc(
&self, &self,
this: Expr<Self::Type>, this: Expr<Self::Type>,
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> { ) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
self.unit.unit_to_reg_alloc(this) self.unit.unit_to_reg_alloc(this)
} }
@ -445,7 +525,9 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
fn extract_mop( fn extract_mop(
&self, &self,
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
) -> 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)))
} }
@ -457,7 +539,7 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
fn unit_to_reg_alloc( fn unit_to_reg_alloc(
&self, &self,
this: Expr<Self::Type>, this: Expr<Self::Type>,
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> { ) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
Expr::from_bundle(Expr::as_bundle( Expr::from_bundle(Expr::as_bundle(
self.0.unit_to_reg_alloc(Expr::from_bundle(this)), self.0.unit_to_reg_alloc(Expr::from_bundle(this)),
)) ))

View file

@ -5,8 +5,8 @@ use crate::{
config::CpuConfig, config::CpuConfig,
instruction::{ instruction::{
AddSubMOp, AluBranchMOp, AluCommonMOp, BranchMOp, COMMON_MOP_SRC_LEN, CommonMOpDefaultImm, AddSubMOp, AluBranchMOp, AluCommonMOp, BranchMOp, COMMON_MOP_SRC_LEN, CommonMOpDefaultImm,
CompareMOp, LogicalFlagsMOp, LogicalMOp, MOpTrait, OutputIntegerMode, ReadSpecialMOp, CompareMOp, LogicalFlagsMOp, LogicalMOp, MOpTrait, OutputIntegerMode, PRegNum,
RenamedMOp, ShiftRotateMOp, UnitOutRegNum, ReadSpecialMOp, RenamedMOp, ShiftRotateMOp, UnitOutRegNum,
}, },
register::{ register::{
FlagsMode, PRegFlagsPowerISA, PRegFlagsPowerISAView, PRegFlagsViewTrait, PRegFlagsX86, FlagsMode, PRegFlagsPowerISA, PRegFlagsPowerISAView, PRegFlagsViewTrait, PRegFlagsX86,
@ -19,16 +19,19 @@ use crate::{
}, },
}; };
use fayalite::{ use fayalite::{
intern::{Intern, Interned}, intern::Interned, module::wire_with_loc, prelude::*, util::ready_valid::ReadyValid,
module::wire_with_loc,
prelude::*,
util::ready_valid::ReadyValid,
}; };
use std::{collections::HashMap, ops::RangeTo}; use std::{collections::HashMap, ops::RangeTo};
#[hdl] #[hdl]
fn add_sub<SrcCount: KnownSize>( fn add_sub<SrcCount: KnownSize>(
mop: Expr<AddSubMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>, mop: Expr<
AddSubMOp<
UnitOutRegNum<PhantomConst<CpuConfig>>,
PRegNum<PhantomConst<CpuConfig>>,
SrcCount,
>,
>,
pc: Expr<UInt<64>>, pc: Expr<UInt<64>>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
@ -245,7 +248,9 @@ fn add_sub<SrcCount: KnownSize>(
#[hdl] #[hdl]
fn logical_flags( fn logical_flags(
mop: Expr<LogicalFlagsMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
LogicalFlagsMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
) -> Expr<UnitResultCompleted<()>> { ) -> Expr<UnitResultCompleted<()>> {
@ -259,7 +264,13 @@ fn logical_flags(
#[hdl] #[hdl]
fn logical( fn logical(
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<2>>>, mop: Expr<
LogicalMOp<
UnitOutRegNum<PhantomConst<CpuConfig>>,
PRegNum<PhantomConst<CpuConfig>>,
ConstUsize<2>,
>,
>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
) -> Expr<UnitResultCompleted<()>> { ) -> Expr<UnitResultCompleted<()>> {
@ -273,7 +284,13 @@ fn logical(
#[hdl] #[hdl]
fn logical_i( fn logical_i(
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<1>>>, mop: Expr<
LogicalMOp<
UnitOutRegNum<PhantomConst<CpuConfig>>,
PRegNum<PhantomConst<CpuConfig>>,
ConstUsize<1>,
>,
>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
) -> Expr<UnitResultCompleted<()>> { ) -> Expr<UnitResultCompleted<()>> {
@ -287,7 +304,9 @@ fn logical_i(
#[hdl] #[hdl]
fn shift_rotate( fn shift_rotate(
mop: Expr<ShiftRotateMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
ShiftRotateMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
) -> Expr<UnitResultCompleted<()>> { ) -> Expr<UnitResultCompleted<()>> {
@ -301,7 +320,13 @@ fn shift_rotate(
#[hdl] #[hdl]
fn compare<SrcCount: KnownSize>( fn compare<SrcCount: KnownSize>(
mop: Expr<CompareMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>, mop: Expr<
CompareMOp<
UnitOutRegNum<PhantomConst<CpuConfig>>,
PRegNum<PhantomConst<CpuConfig>>,
SrcCount,
>,
>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
) -> Expr<UnitResultCompleted<()>> { ) -> Expr<UnitResultCompleted<()>> {
@ -315,7 +340,13 @@ fn compare<SrcCount: KnownSize>(
#[hdl] #[hdl]
fn branch<SrcCount: KnownSize>( fn branch<SrcCount: KnownSize>(
mop: Expr<BranchMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>, mop: Expr<
BranchMOp<
UnitOutRegNum<PhantomConst<CpuConfig>>,
PRegNum<PhantomConst<CpuConfig>>,
SrcCount,
>,
>,
pc: Expr<UInt<64>>, pc: Expr<UInt<64>>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
@ -330,7 +361,9 @@ fn branch<SrcCount: KnownSize>(
#[hdl] #[hdl]
fn read_special( fn read_special(
mop: Expr<ReadSpecialMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
ReadSpecialMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
pc: Expr<UInt<64>>, pc: Expr<UInt<64>>,
flags_mode: Expr<FlagsMode>, flags_mode: Expr<FlagsMode>,
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>, src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
@ -344,20 +377,15 @@ fn read_special(
} }
#[hdl_module] #[hdl_module]
pub fn alu_branch(config: &CpuConfig, unit_index: usize) { pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
#[hdl] #[hdl]
let cd: ClockDomain = m.input(); let cd: ClockDomain = m.input();
#[hdl] #[hdl]
let unit_to_reg_alloc: UnitToRegAlloc< let unit_to_reg_alloc: UnitToRegAlloc<
AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>, PhantomConst<CpuConfig>,
AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
(), (),
DynSize, > = m.output(UnitToRegAlloc[config][AluBranchMOp[UnitOutRegNum[config]][PRegNum[config]]][()]);
DynSize,
DynSize,
> = m.output(config.unit_to_reg_alloc(
AluBranchMOp[config.unit_out_reg_num()][config.p_reg_num_width()],
(),
));
#[hdl] #[hdl]
let global_state: GlobalState = m.input(); let global_state: GlobalState = m.input();
@ -375,10 +403,11 @@ pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
#[hdl] #[hdl]
if let HdlSome(execute_start) = ReadyValid::firing_data(unit_base.execute_start) { if let HdlSome(execute_start) = ReadyValid::firing_data(unit_base.execute_start) {
#[hdl] #[hdl]
let ExecuteStart::<_> { let ExecuteStart::<_, _> {
mop, mop,
pc, pc,
src_values, src_values,
config: _,
} = execute_start; } = execute_start;
#[hdl] #[hdl]
match mop { match mop {
@ -580,14 +609,14 @@ pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct AluBranch { pub struct AluBranch {
config: Interned<CpuConfig>, config: PhantomConst<CpuConfig>,
module: Interned<Module<alu_branch>>, module: Interned<Module<alu_branch>>,
} }
impl AluBranch { impl AluBranch {
pub fn new(config: &CpuConfig, unit_index: usize) -> Self { pub fn new(config: PhantomConst<CpuConfig>, unit_index: usize) -> Self {
Self { Self {
config: config.intern(), config,
module: alu_branch(config, unit_index), module: alu_branch(config, unit_index),
} }
} }
@ -596,7 +625,8 @@ impl AluBranch {
impl UnitTrait for AluBranch { impl UnitTrait for AluBranch {
type Type = alu_branch; type Type = alu_branch;
type ExtraOut = (); type ExtraOut = ();
type MOp = AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>; type MOp =
AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>;
fn ty(&self) -> Self::Type { fn ty(&self) -> Self::Type {
self.module.io_ty() self.module.io_ty()
@ -616,7 +646,9 @@ impl UnitTrait for AluBranch {
fn extract_mop( fn extract_mop(
&self, &self,
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>, mop: Expr<
RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, PRegNum<PhantomConst<CpuConfig>>>,
>,
) -> Expr<HdlOption<Self::MOp>> { ) -> Expr<HdlOption<Self::MOp>> {
UnitMOp::alu_branch_mop(mop) UnitMOp::alu_branch_mop(mop)
} }
@ -628,7 +660,7 @@ impl UnitTrait for AluBranch {
fn unit_to_reg_alloc( fn unit_to_reg_alloc(
&self, &self,
this: Expr<Self::Type>, this: Expr<Self::Type>,
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> { ) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
this.unit_to_reg_alloc this.unit_to_reg_alloc
} }

View file

@ -2,7 +2,7 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
use crate::{ use crate::{
config::CpuConfig, config::{CpuConfig, CpuConfigUnitCount, PhantomConstCpuConfig},
instruction::{COMMON_MOP_SRC_LEN, MOpTrait, PRegNum, UnitNum, UnitOutRegNum}, instruction::{COMMON_MOP_SRC_LEN, MOpTrait, PRegNum, UnitNum, UnitOutRegNum},
register::PRegValue, register::PRegValue,
unit::{UnitCancelInput, UnitOutput, UnitOutputWrite}, unit::{UnitCancelInput, UnitOutput, UnitOutputWrite},
@ -15,13 +15,11 @@ use fayalite::{
ty::StaticType, ty::StaticType,
util::ready_valid::ReadyValid, util::ready_valid::ReadyValid,
}; };
use std::marker::PhantomData;
#[hdl] #[hdl(no_static)]
pub struct UnitForwardingInfo<UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size> { pub struct UnitForwardingInfo<C: PhantomConstGet<CpuConfig>> {
pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<OutRegNumWidth>>, UnitCount>, pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<C>>, CpuConfigUnitCount<C>>,
pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<OutRegNumWidth>>, UnitCount>, pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<C>>, CpuConfigUnitCount<C>>,
pub _phantom: PhantomData<UnitNumWidth>,
} }
#[hdl] #[hdl]
@ -30,26 +28,18 @@ pub struct UnitInput<MOp: Type> {
pub pc: UInt<64>, pub pc: UInt<64>,
} }
#[hdl] #[hdl(no_static)]
pub struct UnitToRegAlloc< pub struct UnitToRegAlloc<C: PhantomConstGet<CpuConfig>, MOp: Type, ExtraOut: Type> {
MOp: Type,
ExtraOut: Type,
UnitNumWidth: Size,
OutRegNumWidth: Size,
UnitCount: Size,
> {
#[hdl(flip)] #[hdl(flip)]
pub unit_forwarding_info: UnitForwardingInfo<UnitNumWidth, OutRegNumWidth, UnitCount>, pub unit_forwarding_info: UnitForwardingInfo<C>,
#[hdl(flip)] #[hdl(flip)]
pub input: ReadyValid<UnitInput<MOp>>, pub input: ReadyValid<UnitInput<MOp>>,
#[hdl(flip)] #[hdl(flip)]
pub cancel_input: HdlOption<UnitCancelInput<OutRegNumWidth>>, pub cancel_input: HdlOption<UnitCancelInput<C>>,
pub output: HdlOption<UnitOutput<OutRegNumWidth, ExtraOut>>, pub output: HdlOption<UnitOutput<C, ExtraOut>>,
} }
impl<MOp: Type, ExtraOut: Type, UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size> impl<C: PhantomConstCpuConfig, MOp: Type, ExtraOut: Type> UnitToRegAlloc<C, MOp, ExtraOut> {
UnitToRegAlloc<MOp, ExtraOut, UnitNumWidth, OutRegNumWidth, UnitCount>
{
pub fn mop_ty(self) -> MOp { pub fn mop_ty(self) -> MOp {
self.input.data.HdlSome.mop self.input.data.HdlSome.mop
} }
@ -58,16 +48,20 @@ impl<MOp: Type, ExtraOut: Type, UnitNumWidth: Size, OutRegNumWidth: Size, UnitCo
} }
} }
#[hdl] #[hdl(no_static)]
pub struct ExecuteStart<MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>>> { pub struct ExecuteStart<
C: PhantomConstGet<CpuConfig>,
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<C>>,
> {
pub mop: MOp, pub mop: MOp,
pub pc: UInt<64>, pub pc: UInt<64>,
pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>, pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
pub config: C,
} }
#[hdl] #[hdl(no_static)]
pub struct ExecuteEnd<OutRegNumWidth: Size, ExtraOut> { pub struct ExecuteEnd<C: PhantomConstGet<CpuConfig>, ExtraOut> {
pub unit_output: UnitOutput<OutRegNumWidth, ExtraOut>, pub unit_output: UnitOutput<C, ExtraOut>,
} }
#[hdl] #[hdl]
@ -240,10 +234,14 @@ impl InFlightOpsSummary<DynSize> {
#[hdl_module] #[hdl_module]
pub fn unit_base< pub fn unit_base<
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>, MOp: Type
+ MOpTrait<
DestReg = UnitOutRegNum<PhantomConst<CpuConfig>>,
SrcReg = PRegNum<PhantomConst<CpuConfig>>,
>,
ExtraOut: Type, ExtraOut: Type,
>( >(
config: &CpuConfig, config: PhantomConst<CpuConfig>,
unit_index: usize, unit_index: usize,
mop_ty: MOp, mop_ty: MOp,
extra_out_ty: ExtraOut, extra_out_ty: ExtraOut,
@ -251,17 +249,18 @@ pub fn unit_base<
#[hdl] #[hdl]
let cd: ClockDomain = m.input(); let cd: ClockDomain = m.input();
#[hdl] #[hdl]
let unit_to_reg_alloc: UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> = let unit_to_reg_alloc: UnitToRegAlloc<PhantomConst<CpuConfig>, MOp, ExtraOut> =
m.output(config.unit_to_reg_alloc(mop_ty, extra_out_ty)); m.output(UnitToRegAlloc[config][mop_ty][extra_out_ty]);
#[hdl] #[hdl]
let execute_start: ReadyValid<ExecuteStart<MOp>> = m.output(ReadyValid[ExecuteStart[mop_ty]]); let execute_start: ReadyValid<ExecuteStart<PhantomConst<CpuConfig>, MOp>> =
m.output(ReadyValid[ExecuteStart[config][mop_ty]]);
#[hdl] #[hdl]
let execute_end: HdlOption<ExecuteEnd<DynSize, ExtraOut>> = let execute_end: HdlOption<ExecuteEnd<PhantomConst<CpuConfig>, ExtraOut>> =
m.input(HdlOption[ExecuteEnd[config.out_reg_num_width][extra_out_ty]]); m.input(HdlOption[ExecuteEnd[config][extra_out_ty]]);
connect(execute_start.data, execute_start.ty().data.HdlNone()); connect(execute_start.data, execute_start.ty().data.HdlNone());
let max_in_flight = config.unit_max_in_flight(unit_index).get(); let max_in_flight = config.get().unit_max_in_flight(unit_index).get();
let in_flight_op_ty = InFlightOp[mop_ty]; let in_flight_op_ty = InFlightOp[mop_ty];
#[hdl] #[hdl]
let in_flight_ops = reg_builder() let in_flight_ops = reg_builder()
@ -279,16 +278,15 @@ pub fn unit_base<
); );
#[hdl] #[hdl]
let UnitForwardingInfo::<_, _, _> { let UnitForwardingInfo::<_> {
unit_output_writes, unit_output_writes,
unit_reg_frees, unit_reg_frees,
_phantom: _,
} = unit_to_reg_alloc.unit_forwarding_info; } = unit_to_reg_alloc.unit_forwarding_info;
#[hdl] #[hdl]
let read_src_regs = wire(mop_ty.src_regs_ty()); let read_src_regs = wire(mop_ty.src_regs_ty());
connect( connect(
read_src_regs, read_src_regs,
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize), repeat(PRegNum[config].const_zero(), ConstUsize),
); );
#[hdl] #[hdl]
let read_src_values = wire(); let read_src_values = wire();
@ -297,7 +295,7 @@ pub fn unit_base<
let input_src_regs = wire(mop_ty.src_regs_ty()); let input_src_regs = wire(mop_ty.src_regs_ty());
connect( connect(
input_src_regs, input_src_regs,
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize), repeat(PRegNum[config].const_zero(), ConstUsize),
); );
#[hdl] #[hdl]
let input_src_regs_valid = wire(); let input_src_regs_valid = wire();
@ -309,7 +307,7 @@ pub fn unit_base<
Bool, Bool,
SourceLocation::caller(), SourceLocation::caller(),
); );
mem.depth(1 << config.out_reg_num_width); mem.depth(1 << config.get().out_reg_num_width);
mem mem
}) })
.collect(); .collect();
@ -319,11 +317,11 @@ pub fn unit_base<
PRegValue, PRegValue,
SourceLocation::caller(), SourceLocation::caller(),
); );
unit_output_regs.depth(1 << config.out_reg_num_width); unit_output_regs.depth(1 << config.get().out_reg_num_width);
for src_index in 0..COMMON_MOP_SRC_LEN { for src_index in 0..COMMON_MOP_SRC_LEN {
let read_port = unit_output_regs.new_read_port(); let read_port = unit_output_regs.new_read_port();
let p_reg_num = read_src_regs[src_index].cast_bits_to(config.p_reg_num()); let p_reg_num = read_src_regs[src_index];
connect_any(read_port.addr, p_reg_num.unit_out_reg.value); connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
connect(read_port.en, false); connect(read_port.en, false);
connect(read_port.clk, cd.clk); connect(read_port.clk, cd.clk);
@ -336,7 +334,7 @@ pub fn unit_base<
for src_index in 0..COMMON_MOP_SRC_LEN { for src_index in 0..COMMON_MOP_SRC_LEN {
let read_port = unit_output_regs_valid[unit_index].new_read_port(); let read_port = unit_output_regs_valid[unit_index].new_read_port();
let p_reg_num = input_src_regs[src_index].cast_bits_to(config.p_reg_num()); let p_reg_num = input_src_regs[src_index];
connect_any(read_port.addr, p_reg_num.unit_out_reg.value); connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
connect(read_port.en, false); connect(read_port.en, false);
connect(read_port.clk, cd.clk); connect(read_port.clk, cd.clk);
@ -367,13 +365,13 @@ pub fn unit_base<
connect_any(ready_write_port.addr, unit_output_write.which.value); connect_any(ready_write_port.addr, unit_output_write.which.value);
connect(ready_write_port.en, true); connect(ready_write_port.en, true);
let p_reg_num = #[hdl] let p_reg_num = #[hdl]
PRegNum::<_, _> { PRegNum::<_> {
unit_num: config.unit_num().from_index(unit_index), unit_num: UnitNum[config].from_index(unit_index),
unit_out_reg: unit_output_write.which, unit_out_reg: unit_output_write.which,
}; };
for src_index in 0..COMMON_MOP_SRC_LEN { for src_index in 0..COMMON_MOP_SRC_LEN {
#[hdl] #[hdl]
if input_src_regs[src_index].cmp_eq(p_reg_num.cast_to_bits()) { if input_src_regs[src_index].cmp_eq(p_reg_num) {
connect(input_src_regs_valid[src_index], true); connect(input_src_regs_valid[src_index], true);
} }
} }
@ -399,10 +397,11 @@ pub fn unit_base<
execute_start.data, execute_start.data,
HdlSome( HdlSome(
#[hdl] #[hdl]
ExecuteStart::<_> { ExecuteStart::<_, _> {
mop: in_flight_op.mop, mop: in_flight_op.mop,
pc: in_flight_op.pc, pc: in_flight_op.pc,
src_values: read_src_values, src_values: read_src_values,
config,
}, },
), ),
); );
@ -425,7 +424,7 @@ pub fn unit_base<
let input_mop_src_regs = wire(mop_ty.src_regs_ty()); let input_mop_src_regs = wire(mop_ty.src_regs_ty());
connect( connect(
input_mop_src_regs, input_mop_src_regs,
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize), repeat(PRegNum[config].const_zero(), ConstUsize),
); );
MOp::connect_src_regs(mop, input_mop_src_regs); MOp::connect_src_regs(mop, input_mop_src_regs);
let src_ready_flags = wire_with_loc( let src_ready_flags = wire_with_loc(
@ -495,10 +494,7 @@ pub fn unit_base<
SourceLocation::caller(), SourceLocation::caller(),
mop_ty.src_regs_ty(), mop_ty.src_regs_ty(),
); );
connect( connect(src_regs, repeat(PRegNum[config].const_zero(), ConstUsize));
src_regs,
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
);
MOp::connect_src_regs(mop, src_regs); MOp::connect_src_regs(mop, src_regs);
#[hdl] #[hdl]
@ -521,13 +517,13 @@ pub fn unit_base<
value: _, value: _,
} = unit_output_write; } = unit_output_write;
let p_reg_num = #[hdl] let p_reg_num = #[hdl]
PRegNum::<_, _> { PRegNum::<_> {
unit_num: config.unit_num().from_index(unit_index), unit_num: UnitNum[config].from_index(unit_index),
unit_out_reg, unit_out_reg,
}; };
for src_index in 0..COMMON_MOP_SRC_LEN { for src_index in 0..COMMON_MOP_SRC_LEN {
#[hdl] #[hdl]
if p_reg_num.cast_to_bits().cmp_eq(src_regs[src_index]) { if p_reg_num.cmp_eq(src_regs[src_index]) {
connect( connect(
in_flight_op_next_src_ready_flags[in_flight_op_index][src_index], in_flight_op_next_src_ready_flags[in_flight_op_index][src_index],
true, true,

View file

@ -280,3 +280,33 @@ impl<T: Type, N: Size> Rotate<usize> for SimValue<ArrayType<T, N>> {
retval retval
} }
} }
#[hdl]
pub struct LFSR31 {
// MSB is always zero, 32 bits makes it easier to manipulate
state: UInt<32>,
}
impl LFSR31 {
#[hdl]
pub fn new() -> SimValue<Self> {
#[hdl(sim)]
Self { state: 1u32 }
}
}
impl LFSR31 {
pub fn next_sim(this: &mut SimValue<Self>) -> u32 {
let state = this.state.as_int();
let state = if state == 0 {
1u32
} else {
// a maximal-length 31-bit LFSR
let lsb = ((state >> 30) ^ (state >> 27)) & 1;
let msb = (state << 1) & ((1 << 31) - 1);
lsb | msb
};
*this.state = state.into();
state
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1163,13 +1163,7 @@ impl MockExecuteState {
id: &insn.id, id: &insn.id,
next_pc, next_pc,
call_stack_op: mock_insn.call_stack_op(pc), call_stack_op: mock_insn.call_stack_op(pc),
cond_br_taken: if let Some(cond_br_taken) = cond_br_taken { cond_br_taken,
#[hdl(sim)]
HdlSome(cond_br_taken)
} else {
#[hdl(sim)]
HdlNone()
},
config: self.config, config: self.config,
}, },
) )

View file

@ -1,5 +1,6 @@
// 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
#![cfg(todo)]
use cpu::{ use cpu::{
config::{CpuConfig, UnitConfig}, config::{CpuConfig, UnitConfig},

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -152,16 +152,7 @@ fn test_decode_insn() {
} in test_cases::test_cases() } in test_cases::test_cases()
{ {
sim.write(sim.io().first_input, first_input); sim.write(sim.io().first_input, first_input);
sim.write( sim.write(sim.io().second_input, second_input);
sim.io().second_input,
if let Some(v) = second_input {
#[hdl(sim)]
HdlSome(v)
} else {
#[hdl(sim)]
HdlNone()
},
);
sim.advance_time(SimDuration::from_micros(1)); sim.advance_time(SimDuration::from_micros(1));
let second_input_used = sim.read_bool(sim.io().second_input_used); let second_input_used = sim.read_bool(sim.io().second_input_used);
let is_illegal = sim.read_bool(sim.io().is_illegal); let is_illegal = sim.read_bool(sim.io().is_illegal);

View file

@ -15,7 +15,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_i( BranchMOp::branch_i(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
MOpRegNum::const_zero().value, [MOpRegNum::const_zero(); 2],
0x345678.cast_to_static::<SInt<_>>(), 0x345678.cast_to_static::<SInt<_>>(),
true, true,
false, false,
@ -28,7 +28,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_i( BranchMOp::branch_i(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
MOpRegNum::const_zero().value, [MOpRegNum::const_zero(); 2],
0x345678.cast_to_static::<SInt<_>>(), 0x345678.cast_to_static::<SInt<_>>(),
false, false,
false, false,
@ -41,7 +41,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_i( BranchMOp::branch_i(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
MOpRegNum::const_zero().value, [MOpRegNum::const_zero(); 2],
0x345678.cast_to_static::<SInt<_>>(), 0x345678.cast_to_static::<SInt<_>>(),
true, true,
true, true,
@ -54,7 +54,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_i( BranchMOp::branch_i(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
MOpRegNum::const_zero().value, [MOpRegNum::const_zero(); 2],
0x345678.cast_to_static::<SInt<_>>(), 0x345678.cast_to_static::<SInt<_>>(),
false, false,
true, true,
@ -74,10 +74,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
[ [
AddSubMOp::add_sub_i::<MOp>( AddSubMOp::add_sub_i::<MOp>(
MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []), MOpDestReg::new([MOpRegNum::power_isa_ctr_reg()], []),
[ [MOpRegNum::power_isa_ctr_reg(), MOpRegNum::const_zero()],
MOpRegNum::power_isa_ctr_reg().value,
MOpRegNum::const_zero().value,
],
(-1).cast_to_static::<SInt<_>>(), (-1).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -143,9 +140,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -163,9 +160,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -183,9 +180,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -203,9 +200,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -223,9 +220,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(2).value, MOpRegNum::power_isa_cr_reg_imm(2),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -243,9 +240,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -264,9 +261,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
@ -285,9 +282,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
false, false,
@ -305,9 +302,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::power_isa_ctr_reg(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
false, false,
@ -326,9 +323,9 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
BranchMOp::branch_cond_ctr( BranchMOp::branch_cond_ctr(
$dest, $dest,
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
$src1, $src1,
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
false, false,
@ -346,8 +343,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_ctr( BranchMOp::branch_ctr(
$dest, $dest,
$src1, [
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::const_zero(),
$src1,
MOpRegNum::power_isa_ctr_reg(),
],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
true, true,
$pc_relative, $pc_relative,
@ -361,8 +361,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_ctr( BranchMOp::branch_ctr(
$dest, $dest,
$src1, [
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::const_zero(),
$src1,
MOpRegNum::power_isa_ctr_reg(),
],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
false, false,
$pc_relative, $pc_relative,
@ -377,7 +380,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_i( BranchMOp::branch_i(
$dest, $dest,
$src1, [MOpRegNum::const_zero(), $src1],
$imm.cast_to_static::<SInt<_>>(), $imm.cast_to_static::<SInt<_>>(),
$pc_relative, $pc_relative,
$lk, $lk,
@ -392,7 +395,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
asm_last_arg = "0x1234"; asm_last_arg = "0x1234";
imm = 0x1234; imm = 0x1234;
encoding = 0x40001234; encoding = 0x40001234;
src1 = MOpRegNum::const_zero().value; src1 = MOpRegNum::const_zero();
pc_relative = true; pc_relative = true;
is_ret = false; is_ret = false;
} }
@ -402,7 +405,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
asm_last_arg = "0x1234"; asm_last_arg = "0x1234";
imm = 0x1234; imm = 0x1234;
encoding = 0x40001236; encoding = 0x40001236;
src1 = MOpRegNum::const_zero().value; src1 = MOpRegNum::const_zero();
pc_relative = false; pc_relative = false;
is_ret = false; is_ret = false;
} }
@ -412,7 +415,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
asm_last_arg = "0"; asm_last_arg = "0";
imm = 0; imm = 0;
encoding = 0x4c000020; encoding = 0x4c000020;
src1 = MOpRegNum::power_isa_lr_reg().value; src1 = MOpRegNum::power_isa_lr_reg();
pc_relative = false; pc_relative = false;
is_ret = true; is_ret = true;
} }
@ -422,7 +425,7 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
asm_last_arg = "0"; asm_last_arg = "0";
imm = 0; imm = 0;
encoding = 0x4c000420; encoding = 0x4c000420;
src1 = MOpRegNum::power_isa_ctr_reg().value; src1 = MOpRegNum::power_isa_ctr_reg();
pc_relative = false; pc_relative = false;
is_ret = false; is_ret = false;
} }
@ -434,8 +437,11 @@ pub fn test_cases_book_i_2_4_branch(retval: &mut Vec<TestCase>) {
None, None,
BranchMOp::branch_ctr( BranchMOp::branch_ctr(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
MOpRegNum::power_isa_tar_reg().value, [
MOpRegNum::power_isa_ctr_reg().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_tar_reg(),
MOpRegNum::power_isa_ctr_reg(),
],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
false, false,
false, false,

View file

@ -23,9 +23,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_cr_reg_imm(1).value, MOpRegNum::power_isa_cr_reg_imm(1),
MOpRegNum::power_isa_cr_reg_imm(5).value, MOpRegNum::power_isa_cr_reg_imm(5),
MOpRegNum::power_isa_cr_reg_imm(3).value, MOpRegNum::power_isa_cr_reg_imm(3),
], ],
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| { LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
let mut dest = src2.map(|v| Some(v.into())); let mut dest = src2.map(|v| Some(v.into()));
@ -42,9 +42,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
], ],
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| { LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
let mut dest = src2.map(|v| Some(v.into())); let mut dest = src2.map(|v| Some(v.into()));
@ -61,9 +61,9 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(0)], &[]),
[ [
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
MOpRegNum::power_isa_cr_reg_imm(0).value, MOpRegNum::power_isa_cr_reg_imm(0),
], ],
LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| { LogicalFlagsMOpImm::from_swizzle_fn::<PRegFlagsPowerISA>(|src0, src1, src2| {
let mut dest = src2.map(|v| Some(v.into())); let mut dest = src2.map(|v| Some(v.into()));
@ -91,7 +91,7 @@ pub fn test_cases_book_i_2_5_condition_register(retval: &mut Vec<TestCase>) {
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_cr_reg_imm($src).value], [MOpRegNum::power_isa_cr_reg_imm($src)],
0i8.cast_to_static::<SInt<_>>(), 0i8.cast_to_static::<SInt<_>>(),
), ),
)); ));

View file

@ -13,10 +13,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
None, None,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[ [MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
MOpRegNum::power_isa_gpr_reg_imm(4).value,
MOpRegNum::const_zero().value,
],
0x1234.cast_to_static::<SInt<_>>(), 0x1234.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -31,10 +28,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
Some(0x38646789), Some(0x38646789),
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[ [MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
MOpRegNum::power_isa_gpr_reg_imm(4).value,
MOpRegNum::const_zero().value,
],
0x123456789i64.cast_to_static::<SInt<_>>(), 0x123456789i64.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -49,7 +43,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
Some(0x38606789), Some(0x38606789),
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value, MOpRegNum::const_zero().value], [MOpRegNum::const_zero(), MOpRegNum::const_zero()],
0x123456789i64.cast_to_static::<SInt<_>>(), 0x123456789i64.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -64,10 +58,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
None, None,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[ [MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
MOpRegNum::power_isa_gpr_reg_imm(4).value,
MOpRegNum::const_zero().value,
],
0x12340000.cast_to_static::<SInt<_>>(), 0x12340000.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -82,7 +73,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
None, None,
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value; _], [MOpRegNum::const_zero(); _],
0x12340004.cast_to_static::<SInt<_>>(), 0x12340004.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -101,9 +92,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -125,10 +116,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
], ],
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
MOpRegNum::power_isa_gpr_reg_imm(4).value,
MOpRegNum::const_zero().value,
],
0x1234.cast_to_static::<SInt<_>>(), 0x1234.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
false, false,
@ -147,9 +135,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -171,10 +159,7 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
], ],
&[], &[],
), ),
[ [MOpRegNum::power_isa_gpr_reg_imm(4), MOpRegNum::const_zero()],
MOpRegNum::power_isa_gpr_reg_imm(4).value,
MOpRegNum::const_zero().value,
],
0x1234.cast_to_static::<SInt<_>>(), 0x1234.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
true, true,
@ -196,9 +181,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -221,9 +206,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -246,9 +231,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -271,9 +256,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -296,9 +281,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
(-1i8).cast_to_static::<SInt<_>>(), (-1i8).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -321,9 +306,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
(-1i8).cast_to_static::<SInt<_>>(), (-1i8).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -346,9 +331,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -371,9 +356,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -393,9 +378,9 @@ pub fn test_cases_book_i_3_3_9_fixed_point_arithmetic(retval: &mut Vec<TestCase>
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),

View file

@ -2,7 +2,7 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
use crate::test_cases::{TestCase, insn_single}; use crate::test_cases::{TestCase, insn_single};
use cpu::instruction::{CompareMOp, CompareMode, MOpDestReg, MOpRegNum, OutputIntegerMode}; use cpu::instruction::{CompareMOp, CompareMode, MOpDestReg, MOpRegNum};
use fayalite::prelude::*; use fayalite::prelude::*;
/// covers instructions in PowerISA v3.1C Book I 3.3.10 Fixed-Point Compare Instructions /// covers instructions in PowerISA v3.1C Book I 3.3.10 Fixed-Point Compare Instructions
@ -13,9 +13,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
None, None,
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(4).value], [MOpRegNum::power_isa_gpr_reg_imm(4)],
0x1234.cast_to_static::<SInt<_>>(), 0x1234.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.S32(), CompareMode.S32(),
), ),
)); ));
@ -25,9 +24,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
None, None,
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(4).value], [MOpRegNum::power_isa_gpr_reg_imm(4)],
(0x89abu16 as i16).cast_to_static::<SInt<_>>(), (0x89abu16 as i16).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.S64(), CompareMode.S64(),
), ),
)); ));
@ -38,11 +36,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.S32(), CompareMode.S32(),
), ),
)); ));
@ -53,11 +49,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.S64(), CompareMode.S64(),
), ),
)); ));
@ -67,9 +61,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
None, None,
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(4).value], [MOpRegNum::power_isa_gpr_reg_imm(4)],
0x1234.cast_to_static::<SInt<_>>(), 0x1234.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.U32(), CompareMode.U32(),
), ),
)); ));
@ -79,9 +72,8 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
None, None,
CompareMOp::compare_i( CompareMOp::compare_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(4).value], [MOpRegNum::power_isa_gpr_reg_imm(4)],
0x89ab.cast_to_static::<SInt<_>>(), 0x89ab.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.U64(), CompareMode.U64(),
), ),
)); ));
@ -92,11 +84,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.U32(), CompareMode.U32(),
), ),
)); ));
@ -107,11 +97,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.U64(), CompareMode.U64(),
), ),
)); ));
@ -122,11 +110,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.CmpRBOne(), CompareMode.CmpRBOne(),
), ),
)); ));
@ -137,11 +123,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.CmpRBTwo(), CompareMode.CmpRBTwo(),
), ),
)); ));
@ -152,11 +136,9 @@ pub fn test_cases_book_i_3_3_10_fixed_point_compare(retval: &mut Vec<TestCase>)
CompareMOp::compare( CompareMOp::compare(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm(4).value, MOpRegNum::power_isa_gpr_reg_imm(4),
MOpRegNum::power_isa_gpr_reg_imm(5).value, MOpRegNum::power_isa_gpr_reg_imm(5),
], ],
0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(),
CompareMode.CmpEqB(), CompareMode.CmpEqB(),
), ),
)); ));

View file

@ -26,11 +26,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $r != 0 || $ra == 0 { if $r != 0 || $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -41,7 +41,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
), ),
LoadMOp::load( LoadMOp::load(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_temp_reg().value], [MOpRegNum::power_isa_temp_reg()],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.$conversion(), LoadStoreConversion.$conversion(),
), ),
@ -65,11 +65,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $ra == 0 { if $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -80,7 +80,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
), ),
LoadMOp::load( LoadMOp::load(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_temp_reg().value], [MOpRegNum::power_isa_temp_reg()],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.$conversion(), LoadStoreConversion.$conversion(),
), ),
@ -103,8 +103,8 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -115,7 +115,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
), ),
LoadMOp::load( LoadMOp::load(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm($ra).value], [MOpRegNum::power_isa_gpr_reg_imm($ra)],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.$conversion(), LoadStoreConversion.$conversion(),
), ),
@ -139,11 +139,11 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $ra == 0 { if $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::power_isa_gpr_reg_imm($rb).value, MOpRegNum::power_isa_gpr_reg_imm($rb),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -154,7 +154,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
), ),
LoadMOp::load( LoadMOp::load(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_temp_reg().value], [MOpRegNum::power_isa_temp_reg()],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.$conversion(), LoadStoreConversion.$conversion(),
), ),
@ -177,8 +177,8 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::power_isa_gpr_reg_imm($rb).value, MOpRegNum::power_isa_gpr_reg_imm($rb),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -189,7 +189,7 @@ pub fn test_cases_book_i_3_3_2_fixed_point_load(retval: &mut Vec<TestCase>) {
), ),
LoadMOp::load( LoadMOp::load(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm($ra).value], [MOpRegNum::power_isa_gpr_reg_imm($ra)],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.$conversion(), LoadStoreConversion.$conversion(),
), ),

View file

@ -34,7 +34,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
&[] &[]
}, },
), ),
[MOpRegNum::power_isa_gpr_reg_imm($src).value], [MOpRegNum::power_isa_gpr_reg_imm($src)],
(($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 }) (($imm as u32) << if $mnemonic.contains('s') { 16 } else { 0 })
.cast_to_static::<SInt<_>>(), .cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -108,8 +108,8 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
}, },
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src0).value, MOpRegNum::power_isa_gpr_reg_imm($src0),
MOpRegNum::power_isa_gpr_reg_imm($src1).value, MOpRegNum::power_isa_gpr_reg_imm($src1),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -159,7 +159,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(4).value], [MOpRegNum::power_isa_gpr_reg_imm(4)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -232,7 +232,7 @@ pub fn test_cases_book_i_3_3_13_fixed_point_logical(retval: &mut Vec<TestCase>)
&[] &[]
}, },
), ),
[MOpRegNum::power_isa_gpr_reg_imm($src).value], [MOpRegNum::power_isa_gpr_reg_imm($src)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.$OutputIntegerMode(), OutputIntegerMode.$OutputIntegerMode(),
Lut4::from_fn(|a, b| a | b), Lut4::from_fn(|a, b| a | b),

View file

@ -3,8 +3,8 @@
use crate::test_cases::{TestCase, insn_single}; use crate::test_cases::{TestCase, insn_single};
use cpu::instruction::{ use cpu::instruction::{
MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftRotateDestLogicOp, ShiftRotateMOp, MOpDestReg, MOpRegNum, OutputIntegerMode, ShiftAmountOverflowBehavior, ShiftRotateDestLogicOp,
ShiftRotateMOpImm, ShiftRotateMode, ShiftRotateMOp, ShiftRotateMOpImm, ShiftRotateMode,
}; };
use fayalite::prelude::*; use fayalite::prelude::*;
@ -18,6 +18,11 @@ fn shift_imm(amount: Option<u8>, shift_right: bool) -> Expr<ShiftRotateMOpImm> {
HdlNone() HdlNone()
}, },
shift_rotate_right: shift_right, shift_rotate_right: shift_right,
shift_amount_overflow_behavior: if amount.is_some() {
ShiftAmountOverflowBehavior.WrapToWidth()
} else {
ShiftAmountOverflowBehavior.WrapToTwiceWidth()
},
dest_logic_op: HdlNone(), dest_logic_op: HdlNone(),
} }
} }
@ -30,14 +35,9 @@ fn rotate_imm(
) -> SimValue<ShiftRotateMOpImm> { ) -> SimValue<ShiftRotateMOpImm> {
#[hdl(sim)] #[hdl(sim)]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: if let Some(amount) = amount { shift_rotate_amount: amount.map(|amount| amount.cast_to_static::<UInt<_>>()),
#[hdl(sim)]
HdlSome(amount.cast_to_static::<UInt<_>>())
} else {
#[hdl(sim)]
HdlNone()
},
shift_rotate_right: false, shift_rotate_right: false,
shift_amount_overflow_behavior: ShiftAmountOverflowBehavior.WrapToWidth(),
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) = dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
rotated_output_start_and_len rotated_output_start_and_len
{ {
@ -101,9 +101,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
src2.value, src2,
], ],
&imm, &imm,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -127,9 +127,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
src2.value, src2,
], ],
imm, imm,
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -162,9 +162,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
rotate_imm(None, $rotated_output_start_and_len, false), rotate_imm(None, $rotated_output_start_and_len, false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -188,9 +188,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
rotate_imm(None, $rotated_output_start_and_len, false), rotate_imm(None, $rotated_output_start_and_len, false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -745,9 +745,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, false), shift_imm(None, false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -772,9 +772,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, false), shift_imm(None, false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -804,9 +804,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[ [
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, true), shift_imm(None, true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -831,9 +831,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, true), shift_imm(None, true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -869,9 +869,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[], &[],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, true), shift_imm(None, true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -899,9 +899,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_gpr_reg_imm($amount).value, MOpRegNum::power_isa_gpr_reg_imm($amount),
], ],
shift_imm(None, true), shift_imm(None, true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -937,9 +937,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[], &[],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
shift_imm(Some($amount), true), shift_imm(Some($amount), true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -967,9 +967,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
shift_imm(Some($amount), true), shift_imm(Some($amount), true),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -1078,9 +1078,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
ShiftRotateMOp::shift_rotate( ShiftRotateMOp::shift_rotate(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($dest)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
shift_imm(Some($amount), false), shift_imm(Some($amount), false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -1105,9 +1105,9 @@ pub fn test_cases_book_i_3_3_14_fixed_point_rotate_and_shift(retval: &mut Vec<Te
&[MOpRegNum::POWER_ISA_CR_0_REG_NUM], &[MOpRegNum::POWER_ISA_CR_0_REG_NUM],
), ),
[ [
MOpRegNum::power_isa_gpr_reg_imm($src).value, MOpRegNum::power_isa_gpr_reg_imm($src),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
shift_imm(Some($amount), false), shift_imm(Some($amount), false),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),

View file

@ -25,11 +25,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $r != 0 || $ra == 0 { if $r != 0 || $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -41,8 +41,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_temp_reg().value, MOpRegNum::power_isa_temp_reg(),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
@ -66,11 +66,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $ra == 0 { if $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -82,8 +82,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_temp_reg().value, MOpRegNum::power_isa_temp_reg(),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
@ -107,8 +107,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -120,15 +120,15 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_temp_reg().value, MOpRegNum::power_isa_temp_reg(),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
), ),
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[MOpRegNum::power_isa_temp_reg().value], [MOpRegNum::power_isa_temp_reg()],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
], ],
@ -142,8 +142,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
], ],
($disp as i64).cast_to_static::<SInt<_>>(), ($disp as i64).cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -155,8 +155,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
@ -181,11 +181,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
if $ra == 0 { if $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::power_isa_gpr_reg_imm($rb).value, MOpRegNum::power_isa_gpr_reg_imm($rb),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -197,8 +197,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_temp_reg().value, MOpRegNum::power_isa_temp_reg(),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
@ -222,8 +222,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
AddSubMOp::add_sub_i( AddSubMOp::add_sub_i(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TEMP_REG_NUM], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::power_isa_gpr_reg_imm($rb).value, MOpRegNum::power_isa_gpr_reg_imm($rb),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -235,15 +235,15 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_temp_reg().value, MOpRegNum::power_isa_temp_reg(),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),
), ),
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[MOpRegNum::power_isa_temp_reg().value], [MOpRegNum::power_isa_temp_reg()],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
], ],
@ -258,11 +258,11 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num($ra)], &[]),
[ [
if $ra == 0 { if $ra == 0 {
MOpRegNum::const_zero().value MOpRegNum::const_zero()
} else { } else {
MOpRegNum::power_isa_gpr_reg_imm($ra).value MOpRegNum::power_isa_gpr_reg_imm($ra)
}, },
MOpRegNum::power_isa_gpr_reg_imm($rb).value, MOpRegNum::power_isa_gpr_reg_imm($rb),
], ],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
OutputIntegerMode.Full64(), OutputIntegerMode.Full64(),
@ -274,8 +274,8 @@ pub fn test_cases_book_i_3_3_3_fixed_point_store(retval: &mut Vec<TestCase>) {
StoreMOp::store( StoreMOp::store(
MOpDestReg::new_sim(&[], &[]), MOpDestReg::new_sim(&[], &[]),
[ [
MOpRegNum::power_isa_gpr_reg_imm($ra).value, MOpRegNum::power_isa_gpr_reg_imm($ra),
MOpRegNum::power_isa_gpr_reg_imm($rs).value, MOpRegNum::power_isa_gpr_reg_imm($rs),
], ],
LoadStoreWidth.$width(), LoadStoreWidth.$width(),
LoadStoreConversion.ZeroExt(), LoadStoreConversion.ZeroExt(),

View file

@ -30,9 +30,9 @@ pub fn test_cases_book_i_3_3_19_move_to_from_system_register(retval: &mut Vec<Te
LogicalFlagsMOp::logical_flags( LogicalFlagsMOp::logical_flags(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_cr_reg_num(3)], &[]),
[ [
MOpRegNum::power_isa_xer_ca_ca32_reg().value, MOpRegNum::power_isa_xer_ca_ca32_reg(),
MOpRegNum::const_zero().value, MOpRegNum::const_zero(),
MOpRegNum::power_isa_xer_so_ov_ov32_reg().value, MOpRegNum::power_isa_xer_so_ov_ov32_reg(),
], ],
mcrxrx_imm(), mcrxrx_imm(),
Lut4::from_fn(|a, b| a | b), Lut4::from_fn(|a, b| a | b),
@ -48,7 +48,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::power_isa_lr_reg().value], [MOpRegNum::power_isa_lr_reg()],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -58,7 +58,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_LR_REG_NUM], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(3).value], [MOpRegNum::power_isa_gpr_reg_imm(3)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -68,7 +68,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::power_isa_ctr_reg().value], [MOpRegNum::power_isa_ctr_reg()],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -78,7 +78,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_CTR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_CTR_REG_NUM], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(3).value], [MOpRegNum::power_isa_gpr_reg_imm(3)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -88,7 +88,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::power_isa_tar_reg().value], [MOpRegNum::power_isa_tar_reg()],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -98,7 +98,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
MoveRegMOp::move_reg( MoveRegMOp::move_reg(
MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]), MOpDestReg::new_sim(&[MOpRegNum::POWER_ISA_TAR_REG_NUM], &[]),
[MOpRegNum::power_isa_gpr_reg_imm(3).value], [MOpRegNum::power_isa_gpr_reg_imm(3)],
0.cast_to_static::<SInt<_>>(), 0.cast_to_static::<SInt<_>>(),
), ),
)); ));
@ -109,7 +109,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
ReadSpecialMOp::read_special( ReadSpecialMOp::read_special(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value; 0], [MOpRegNum::const_zero(); 0],
ReadSpecialMOpImm.PowerIsaTimeBase(), ReadSpecialMOpImm.PowerIsaTimeBase(),
), ),
)); ));
@ -120,7 +120,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
ReadSpecialMOp::read_special( ReadSpecialMOp::read_special(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value; 0], [MOpRegNum::const_zero(); 0],
ReadSpecialMOpImm.PowerIsaTimeBaseU(), ReadSpecialMOpImm.PowerIsaTimeBaseU(),
), ),
)); ));
@ -131,7 +131,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
ReadSpecialMOp::read_special( ReadSpecialMOp::read_special(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value; 0], [MOpRegNum::const_zero(); 0],
ReadSpecialMOpImm.PowerIsaTimeBase(), ReadSpecialMOpImm.PowerIsaTimeBase(),
), ),
)); ));
@ -142,7 +142,7 @@ pub fn test_cases_book_iii_5_4_4_move_to_from_system_register(retval: &mut Vec<T
None, None,
ReadSpecialMOp::read_special( ReadSpecialMOp::read_special(
MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]), MOpDestReg::new_sim(&[MOpRegNum::power_isa_gpr_reg_num(3)], &[]),
[MOpRegNum::const_zero().value; 0], [MOpRegNum::const_zero(); 0],
ReadSpecialMOpImm.PowerIsaTimeBaseU(), ReadSpecialMOpImm.PowerIsaTimeBaseU(),
), ),
)); ));