fix & clean up MOp definitions and ensure_reg_fields_are_in_the_same_place
All checks were successful
/ test (pull_request) Successful in 28m22s
All checks were successful
/ test (pull_request) Successful in 28m22s
This commit is contained in:
parent
9b8d99e9af
commit
e6f876f9af
3 changed files with 4561 additions and 5933 deletions
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7948
crates/cpu/tests/expected/decode_one_insn.vcd
generated
7948
crates/cpu/tests/expected/decode_one_insn.vcd
generated
File diff suppressed because it is too large
Load diff
2435
crates/cpu/tests/expected/reg_alloc.vcd
generated
2435
crates/cpu/tests/expected/reg_alloc.vcd
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue