1
0
Fork 0

fayalite::sim::compiler: fix compiling StructuralEq work properly on enums where the padding isn't known to be zero

This commit is contained in:
Jacob Lifshay 2026-06-11 17:03:56 -07:00
parent 30ffd009f6
commit e2ca80af97
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 910 additions and 5 deletions

View file

@ -3145,6 +3145,144 @@ impl Compiler {
insns
})
}
fn compile_structural_eq(
&mut self,
instantiated_module_or_global: InstantiatedModuleOrGlobal,
expr: ops::StructuralEq,
) -> CompiledExpr<CanonicalType> {
if expr.flags().assume_padding_is_zeroed {
return self.compile_expr(
instantiated_module_or_global,
Expr::canonical(expr.lhs().cast_to_bits().cmp_eq(expr.rhs().cast_to_bits())),
);
}
let source_location = instantiated_module_or_global.leaf_module_source_location();
match expr.lhs().ty() {
CanonicalType::UInt(_)
| CanonicalType::SInt(_)
| CanonicalType::Bool(_)
| CanonicalType::AsyncReset(_)
| CanonicalType::SyncReset(_)
| CanonicalType::Reset(_)
| CanonicalType::Clock(_)
| CanonicalType::PhantomConst(_) => self.compile_expr(
instantiated_module_or_global,
Expr::canonical(expr.lhs().cast_to_bits().cmp_eq(expr.rhs().cast_to_bits())),
),
CanonicalType::Array(_) => {
let lhs = Expr::<Array>::from_canonical(expr.lhs());
let rhs = Expr::<Array>::from_canonical(expr.rhs());
self.compile_expr(
instantiated_module_or_global,
Expr::canonical(
lhs.into_iter()
.zip(rhs)
.map(|(l, r)| {
ops::StructuralEq::with_flags(l, r, expr.flags()).to_expr()
})
.reduce(|a, b| a & b)
.unwrap_or_else(|| true.to_expr()),
),
)
}
CanonicalType::Enum(ty) => {
let lhs = self.compile_expr(instantiated_module_or_global, expr.lhs());
let lhs = self
.compiled_expr_to_value(lhs, source_location)
.map_ty(Enum::from_canonical);
let rhs = self.compile_expr(instantiated_module_or_global, expr.rhs());
let rhs = self
.compiled_expr_to_value(rhs, source_location)
.map_ty(Enum::from_canonical);
let lhs_discriminant = self.compile_enum_discriminant(lhs, source_location);
let rhs_discriminant = self.compile_enum_discriminant(rhs, source_location);
let retval = self.simple_nary_big_expr(
instantiated_module_or_global,
Bool.canonical(),
[],
|dest, []| {
vec![Insn::Const {
dest,
value: BigInt::ZERO.intern_sized(),
}]
},
);
for variant_index in 0..ty.variants().len() {
let variant_eq = self.compile_structural_eq(
instantiated_module_or_global,
ops::StructuralEq::with_flags(
ops::VariantAccess::new_by_index(
Expr::from_canonical(expr.lhs()),
variant_index,
)
.to_expr(),
ops::VariantAccess::new_by_index(
Expr::from_canonical(expr.rhs()),
variant_index,
)
.to_expr(),
expr.flags(),
),
);
let variant_eq = self.compiled_expr_to_value(variant_eq, source_location);
self.compile_simple_connect(
[
Cond {
body: CondBody::MatchArm {
discriminant: lhs_discriminant,
variant_index,
},
source_location,
},
Cond {
body: CondBody::MatchArm {
discriminant: rhs_discriminant,
variant_index,
},
source_location,
},
]
.intern_slice(),
retval.into(),
variant_eq,
source_location,
);
}
retval.into()
}
CanonicalType::Bundle(ty) => {
let lhs = Expr::<Bundle>::from_canonical(expr.lhs());
let rhs = Expr::<Bundle>::from_canonical(expr.rhs());
self.compile_expr(
instantiated_module_or_global,
Expr::canonical(
(0..ty.fields().len())
.map(|field_index| {
ops::StructuralEq::with_flags(
ops::FieldAccess::new_by_index(lhs, field_index).to_expr(),
ops::FieldAccess::new_by_index(rhs, field_index).to_expr(),
expr.flags(),
)
.to_expr()
})
.reduce(|a, b| a & b)
.unwrap_or_else(|| true.to_expr()),
),
)
}
CanonicalType::DynSimOnly(_) => {
unreachable!("StructuralEq is known to not have SimOnly in its inputs' types")
}
CanonicalType::TraceAsString(_) => {
let lhs = Expr::<TraceAsString>::from_canonical(expr.lhs());
let rhs = Expr::<TraceAsString>::from_canonical(expr.rhs());
self.compile_structural_eq(
instantiated_module_or_global,
ops::StructuralEq::with_flags(*lhs, *rhs, expr.flags()),
)
}
}
}
fn compile_expr(
&mut self,
instantiated_module_or_global: impl Into<InstantiatedModuleOrGlobal>,
@ -3975,11 +4113,7 @@ impl Compiler {
.map_ty(TraceAsString::from_canonical)
.inner(),
ExprEnum::StructuralEq(expr) => {
// FIXME: actually ignore enum padding
self.compile_expr(
instantiated_module_or_global,
Expr::canonical(expr.lhs().cast_to_bits().cmp_eq(expr.rhs().cast_to_bits())),
)
self.compile_structural_eq(instantiated_module_or_global, expr)
}
ExprEnum::ModuleIO(expr) => self
.compile_value(TargetInInstantiatedModuleOrGlobal::from_target(

View file

@ -0,0 +1,522 @@
Simulation {
state: State {
insns: Insns {
state_layout: StateLayout {
ty: TypeLayout {
small_slots: StatePartLayout<SmallSlots> {
len: 2,
debug_data: [
SlotDebugData {
name: "",
ty: Enum {
HdlNone,
HdlSome,
},
},
SlotDebugData {
name: "",
ty: Enum {
HdlNone,
HdlSome,
},
},
],
..
},
big_slots: StatePartLayout<BigSlots> {
len: 13,
debug_data: [
SlotDebugData {
name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::a",
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
},
SlotDebugData {
name: "",
ty: UInt<3>,
},
SlotDebugData {
name: "",
ty: UInt<2>,
},
SlotDebugData {
name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::b",
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
},
SlotDebugData {
name: "",
ty: UInt<3>,
},
SlotDebugData {
name: "",
ty: UInt<2>,
},
SlotDebugData {
name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::eq",
ty: Bool,
},
SlotDebugData {
name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::structural_eq",
ty: Bool,
},
SlotDebugData {
name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::bit_eq",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
SlotDebugData {
name: "",
ty: Bool,
},
],
..
},
sim_only_slots: StatePartLayout<SimOnlySlots> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
memories: StatePartLayout<Memories> {
len: 0,
debug_data: [],
layout_data: [],
..
},
},
insns: [
// at: module-XXXXXXXXXX.rs:1:1
0: Const {
dest: StatePartIndex<BigSlots>(10), // (0x1) SlotDebugData { name: "", ty: Bool },
value: 0x1,
},
1: Const {
dest: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: Bool },
value: 0x0,
},
2: Copy {
dest: StatePartIndex<BigSlots>(4), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
src: StatePartIndex<BigSlots>(3), // (0x7) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::b", ty: Enum {HdlNone, HdlSome(UInt<2>)} },
},
3: SliceInt {
dest: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<2> },
src: StatePartIndex<BigSlots>(4), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
start: 1,
len: 2,
},
// at: module-XXXXXXXXXX.rs:3:1
4: AndBigWithSmallImmediate {
dest: StatePartIndex<SmallSlots>(1), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
lhs: StatePartIndex<BigSlots>(3), // (0x7) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::b", ty: Enum {HdlNone, HdlSome(UInt<2>)} },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
5: Copy {
dest: StatePartIndex<BigSlots>(1), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
src: StatePartIndex<BigSlots>(0), // (0x7) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::a", ty: Enum {HdlNone, HdlSome(UInt<2>)} },
},
6: SliceInt {
dest: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "", ty: UInt<2> },
src: StatePartIndex<BigSlots>(1), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
start: 1,
len: 2,
},
7: CmpEq {
dest: StatePartIndex<BigSlots>(11), // (0x1) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<BigSlots>(2), // (0x3) SlotDebugData { name: "", ty: UInt<2> },
rhs: StatePartIndex<BigSlots>(5), // (0x3) SlotDebugData { name: "", ty: UInt<2> },
},
8: CmpEq {
dest: StatePartIndex<BigSlots>(12), // (0x1) SlotDebugData { name: "", ty: Bool },
lhs: StatePartIndex<BigSlots>(1), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
rhs: StatePartIndex<BigSlots>(4), // (0x7) SlotDebugData { name: "", ty: UInt<3> },
},
// at: module-XXXXXXXXXX.rs:9:1
9: Copy {
dest: StatePartIndex<BigSlots>(8), // (0x1) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::bit_eq", ty: Bool },
src: StatePartIndex<BigSlots>(12), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:2:1
10: AndBigWithSmallImmediate {
dest: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
lhs: StatePartIndex<BigSlots>(0), // (0x7) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::a", ty: Enum {HdlNone, HdlSome(UInt<2>)} },
rhs: 0x1,
},
// at: module-XXXXXXXXXX.rs:1:1
11: BranchIfSmallNeImmediate {
target: 14,
lhs: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
rhs: 0x0,
},
12: BranchIfSmallNeImmediate {
target: 14,
lhs: StatePartIndex<SmallSlots>(1), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
rhs: 0x0,
},
13: Copy {
dest: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(10), // (0x1) SlotDebugData { name: "", ty: Bool },
},
14: BranchIfSmallNeImmediate {
target: 17,
lhs: StatePartIndex<SmallSlots>(0), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
rhs: 0x1,
},
15: BranchIfSmallNeImmediate {
target: 17,
lhs: StatePartIndex<SmallSlots>(1), // (0x1 1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} },
rhs: 0x1,
},
16: Copy {
dest: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: Bool },
src: StatePartIndex<BigSlots>(11), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:7:1
17: Copy {
dest: StatePartIndex<BigSlots>(6), // (0x1) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::eq", ty: Bool },
src: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:8:1
18: Copy {
dest: StatePartIndex<BigSlots>(7), // (0x1) SlotDebugData { name: "InstantiatedModule(enum_structural_eq: enum_structural_eq).enum_structural_eq::structural_eq", ty: Bool },
src: StatePartIndex<BigSlots>(9), // (0x1) SlotDebugData { name: "", ty: Bool },
},
// at: module-XXXXXXXXXX.rs:1:1
19: Return,
],
..
},
pc: 19,
memory_write_log: [],
assert_failed_log: [],
memories: StatePart {
value: [],
},
small_slots: StatePart {
value: [
1,
1,
],
},
big_slots: StatePart {
value: [
7,
7,
3,
7,
7,
3,
1,
1,
1,
1,
1,
1,
1,
],
},
sim_only_slots: StatePart {
value: [],
},
},
io: Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
},
global_io: {},
main_module: SimulationModuleState {
base_targets: [
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.a,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.b,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.eq,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.structural_eq,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.bit_eq,
],
uninitialized_ios: {},
io_targets: {
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.a,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.b,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.bit_eq,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.eq,
Instance {
name: <simulator>::enum_structural_eq,
instantiated: Module {
name: enum_structural_eq,
..
},
}.structural_eq,
},
did_initial_settle: true,
clocks_for_past: {},
},
extern_modules: [],
trace_decls: TraceModule {
name: "enum_structural_eq",
children: [
TraceModuleIO {
name: "a",
child: TraceEnumWithFields {
name: "a",
discriminant: TraceEnumDiscriminant {
location: TraceScalarId(0),
name: "$tag",
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
non_empty_fields: [
TraceUInt {
location: TraceScalarId(1),
name: "HdlSome",
ty: UInt<2>,
flow: Source,
},
],
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
TraceModuleIO {
name: "b",
child: TraceEnumWithFields {
name: "b",
discriminant: TraceEnumDiscriminant {
location: TraceScalarId(2),
name: "$tag",
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
non_empty_fields: [
TraceUInt {
location: TraceScalarId(3),
name: "HdlSome",
ty: UInt<2>,
flow: Source,
},
],
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
flow: Source,
},
TraceModuleIO {
name: "eq",
child: TraceBool {
location: TraceScalarId(4),
name: "eq",
flow: Sink,
},
ty: Bool,
flow: Sink,
},
TraceModuleIO {
name: "structural_eq",
child: TraceBool {
location: TraceScalarId(5),
name: "structural_eq",
flow: Sink,
},
ty: Bool,
flow: Sink,
},
TraceModuleIO {
name: "bit_eq",
child: TraceBool {
location: TraceScalarId(6),
name: "bit_eq",
flow: Sink,
},
ty: Bool,
flow: Sink,
},
],
},
traces: [
SimTrace {
id: TraceScalarId(0),
kind: EnumDiscriminant {
index: StatePartIndex<SmallSlots>(0),
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
},
maybe_changed: true,
state: 0x1,
last_state: 0x1,
},
SimTrace {
id: TraceScalarId(1),
kind: BigUInt {
index: StatePartIndex<BigSlots>(2),
ty: UInt<2>,
},
maybe_changed: true,
state: 0x3,
last_state: 0x3,
},
SimTrace {
id: TraceScalarId(2),
kind: EnumDiscriminant {
index: StatePartIndex<SmallSlots>(1),
ty: Enum {
HdlNone,
HdlSome(UInt<2>),
},
},
maybe_changed: true,
state: 0x1,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(3),
kind: BigUInt {
index: StatePartIndex<BigSlots>(5),
ty: UInt<2>,
},
maybe_changed: true,
state: 0x3,
last_state: 0x3,
},
SimTrace {
id: TraceScalarId(4),
kind: BigBool {
index: StatePartIndex<BigSlots>(6),
},
maybe_changed: true,
state: 0x1,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(5),
kind: BigBool {
index: StatePartIndex<BigSlots>(7),
},
maybe_changed: true,
state: 0x1,
last_state: 0x0,
},
SimTrace {
id: TraceScalarId(6),
kind: BigBool {
index: StatePartIndex<BigSlots>(8),
},
maybe_changed: true,
state: 0x1,
last_state: 0x0,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {
finished_init: true,
timescale: 1 ps,
..
},
),
],
clocks_triggered: [],
event_queue: EventQueue(EventQueueData {
instant: 64 μs,
events: {},
}),
waiting_sensitivity_sets_by_address: {},
waiting_sensitivity_sets_by_compiled_value: {},
asserts: [],
..
}

View file

@ -30,4 +30,253 @@ sHdlSome\x20(1) O%@#"
#2000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
1Yp4xI
1>R/<6
#3000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#4000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
1Yp4xI
1>R/<6
#5000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#6000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
1Yp4xI
1>R/<6
#7000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#8000000
sHdlSome\x20(1) +LxwI
sHdlNone\x20(0) O%@#"
b0 ]xpB,
#9000000
sHdlSome\x20(1) O%@#"
1Yp4xI
1>R/<6
1,}=e]
#10000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
0Yp4xI
0>R/<6
0,}=e]
#11000000
sHdlSome\x20(1) O%@#"
#12000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
#13000000
sHdlSome\x20(1) O%@#"
#14000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
#15000000
sHdlSome\x20(1) O%@#"
#16000000
sHdlNone\x20(0) +LxwI
b1 {bf!u
sHdlNone\x20(0) O%@#"
b0 ]xpB,
1Yp4xI
1>R/<6
#17000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#18000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
1Yp4xI
1>R/<6
1,}=e]
#19000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
0,}=e]
#20000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
1Yp4xI
1>R/<6
#21000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#22000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
1Yp4xI
1>R/<6
#23000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#24000000
sHdlSome\x20(1) +LxwI
sHdlNone\x20(0) O%@#"
b0 ]xpB,
#25000000
sHdlSome\x20(1) O%@#"
#26000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
#27000000
sHdlSome\x20(1) O%@#"
1Yp4xI
1>R/<6
1,}=e]
#28000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
0Yp4xI
0>R/<6
0,}=e]
#29000000
sHdlSome\x20(1) O%@#"
#30000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
#31000000
sHdlSome\x20(1) O%@#"
#32000000
sHdlNone\x20(0) +LxwI
b10 {bf!u
sHdlNone\x20(0) O%@#"
b0 ]xpB,
1Yp4xI
1>R/<6
#33000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#34000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
1Yp4xI
1>R/<6
#35000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#36000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
1Yp4xI
1>R/<6
1,}=e]
#37000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
0,}=e]
#38000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
1Yp4xI
1>R/<6
#39000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#40000000
sHdlSome\x20(1) +LxwI
sHdlNone\x20(0) O%@#"
b0 ]xpB,
#41000000
sHdlSome\x20(1) O%@#"
#42000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
#43000000
sHdlSome\x20(1) O%@#"
#44000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
#45000000
sHdlSome\x20(1) O%@#"
1Yp4xI
1>R/<6
1,}=e]
#46000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
0Yp4xI
0>R/<6
0,}=e]
#47000000
sHdlSome\x20(1) O%@#"
#48000000
sHdlNone\x20(0) +LxwI
b11 {bf!u
sHdlNone\x20(0) O%@#"
b0 ]xpB,
1Yp4xI
1>R/<6
#49000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#50000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
1Yp4xI
1>R/<6
#51000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#52000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
1Yp4xI
1>R/<6
#53000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
#54000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
1Yp4xI
1>R/<6
1,}=e]
#55000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
0,}=e]
#56000000
sHdlSome\x20(1) +LxwI
sHdlNone\x20(0) O%@#"
b0 ]xpB,
#57000000
sHdlSome\x20(1) O%@#"
#58000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
#59000000
sHdlSome\x20(1) O%@#"
#60000000
sHdlNone\x20(0) O%@#"
b10 ]xpB,
#61000000
sHdlSome\x20(1) O%@#"
#62000000
sHdlNone\x20(0) O%@#"
b11 ]xpB,
#63000000
sHdlSome\x20(1) O%@#"
1Yp4xI
1>R/<6
1,}=e]
#64000000