fix & clean up MOp definitions and ensure_reg_fields_are_in_the_same_place
All checks were successful
/ test (pull_request) Successful in 28m22s

This commit is contained in:
Jacob Lifshay 2026-01-22 08:28:02 -08:00
parent 9b8d99e9af
commit e6f876f9af
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 4561 additions and 5933 deletions

View file

@ -1919,7 +1919,7 @@ common_mop_struct! {
#[hdl(cmp_eq)]
pub struct ReadL2RegMOp<DestReg: Type, SrcRegWidth: Size> {
#[common]
pub common: CommonMOp<ConstUsize<1>, DestReg, SrcRegWidth, ConstUsize<0>>,
pub common: CommonMOp<ConstUsize<3>, DestReg, SrcRegWidth, ConstUsize<0>>,
}
}
@ -1928,7 +1928,7 @@ common_mop_struct! {
#[hdl(cmp_eq)]
pub struct WriteL2RegMOp<DestReg: Type, SrcRegWidth: Size> {
#[common]
pub common: CommonMOp<ConstUsize<1>, DestReg, SrcRegWidth, ConstUsize<1>>,
pub common: CommonMOp<ConstUsize<3>, DestReg, SrcRegWidth, ConstUsize<1>>,
}
}
@ -1946,7 +1946,7 @@ common_mop_struct! {
#[hdl(cmp_eq)]
pub struct LoadStoreCommonMOp<DestReg: Type, SrcRegWidth: Size, SrcCount: KnownSize> {
#[common]
pub common: CommonMOp<ConstUsize<1>, DestReg, SrcRegWidth, SrcCount>,
pub common: CommonMOp<ConstUsize<3>, DestReg, SrcRegWidth, SrcCount>,
}
}
@ -1972,8 +1972,8 @@ mop_enum! {
#[impl_mop_into = true]
#[hdl]
pub enum LoadStoreMOp<DestReg: Type, SrcRegWidth: Size> {
Load(CommonMOp<ConstUsize<2>, DestReg, SrcRegWidth, ConstUsize<0>>),
Store(CommonMOp<ConstUsize<2>, DestReg, SrcRegWidth, ConstUsize<1>>),
Load(LoadMOp<DestReg, SrcRegWidth>),
Store(StoreMOp<DestReg, SrcRegWidth>),
}
}
@ -1982,7 +1982,7 @@ common_mop_struct! {
#[hdl(cmp_eq)]
pub struct MoveRegMOp<DestReg: Type, SrcRegWidth: Size> {
#[common]
pub common: CommonMOp<ConstUsize<3>, DestReg, SrcRegWidth, ConstUsize<1>>,
pub common: CommonMOp<ConstUsize<4>, DestReg, SrcRegWidth, ConstUsize<1>>,
}
}
@ -2440,16 +2440,23 @@ mod tests {
#[test]
fn ensure_reg_fields_are_in_the_same_place() {
struct Error {
dest_reg_offset: usize,
prefix_pad: usize,
path: Vec<&'static str>,
loc: SourceLocation,
variant: String,
}
struct Visitor {
dest_reg_offset: Option<(usize, String)>,
max_dest_reg_offset: usize,
min_prefix_pad: usize,
errors: Option<String>,
errors: Vec<Error>,
}
impl MOpVariantVisitor<MOp> for Visitor {
impl<T: MOpTrait> MOpVariantVisitor<T> for Visitor {
type Break = Infallible;
fn visit_variant<
VisitOps: ?Sized + MOpVariantVisitOps<Target = MOp, MOp: CommonMOpTrait>,
VisitOps: ?Sized + MOpVariantVisitOps<Target = T, MOp: CommonMOpTrait>,
>(
&mut self,
visit_ops: &VisitOps,
@ -2497,15 +2504,13 @@ mod tests {
self.max_dest_reg_offset = self.max_dest_reg_offset.max(dest_reg_offset);
if let Some((first_dest_reg_offset, _)) = self.dest_reg_offset {
if first_dest_reg_offset != dest_reg_offset {
writeln!(
self.errors.get_or_insert_default(),
"dest_reg_offset {dest_reg_offset} doesn't match first \
variant's dest_reg_offset {first_dest_reg_offset}\n\
variant's path: {:?}\n\
variant: {variant:#?}\n",
VisitOps::path(),
)
.unwrap();
self.errors.push(Error {
dest_reg_offset,
prefix_pad: <VisitOps::MOp as CommonMOpTrait>::PrefixPad::VALUE,
path: VisitOps::path(),
loc: VisitOps::MOp::source_location(),
variant: format!("{variant:#?}"),
});
}
} else {
self.dest_reg_offset = Some((
@ -2519,28 +2524,54 @@ mod tests {
ControlFlow::Continue(())
}
}
let mut visitor = Visitor {
dest_reg_offset: None,
max_dest_reg_offset: 0,
min_prefix_pad: usize::MAX,
errors: None,
};
let ControlFlow::Continue(()) = MOp::visit_variants(&mut visitor, &MOp);
let Visitor {
dest_reg_offset: Some((_, first_variant)),
max_dest_reg_offset,
min_prefix_pad,
errors,
} = visitor
else {
panic!("no variants");
};
println!("max_dest_reg_offset: {max_dest_reg_offset}");
println!("min_prefix_pad: {min_prefix_pad}");
println!("{first_variant}");
if let Some(errors) = errors {
panic!("{errors}");
#[track_caller]
fn check<T: MOpVisitVariants>(mop: T) {
let mut visitor = Visitor {
dest_reg_offset: None,
max_dest_reg_offset: 0,
min_prefix_pad: usize::MAX,
errors: Vec::new(),
};
let ControlFlow::Continue(()) = T::visit_variants(&mut visitor, &mop);
let Visitor {
dest_reg_offset: Some((_, first_variant)),
max_dest_reg_offset,
min_prefix_pad,
errors,
} = visitor
else {
panic!("no variants");
};
println!("max_dest_reg_offset: {max_dest_reg_offset}");
println!("min_prefix_pad: {min_prefix_pad}");
println!("{first_variant}");
if !errors.is_empty() {
let mut text = String::new();
for Error {
dest_reg_offset,
prefix_pad,
path,
loc,
variant,
} in errors
{
let expected_dest_reg_offset = max_dest_reg_offset - min_prefix_pad;
let fixed_prefix_pad = expected_dest_reg_offset + prefix_pad - dest_reg_offset;
writeln!(
text,
"at: {loc}\n\
dest_reg_offset {dest_reg_offset} doesn't match expected {expected_dest_reg_offset}\n\
change the prefix pad to: {fixed_prefix_pad}\n\
variant's path: {path:?}\n\
variant: {variant}\n",
)
.unwrap();
}
panic!("{text}");
}
assert_eq!(min_prefix_pad, 0);
}
assert_eq!(min_prefix_pad, 0);
check(MOp);
check(RenamedMOp[UInt[8]][8]);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff