sim: WIP adding memory support
This commit is contained in:
		
							parent
							
								
									e504cfebfe
								
							
						
					
					
						commit
						3ed7827485
					
				
					 8 changed files with 335 additions and 38 deletions
				
			
		| 
						 | 
					@ -16,6 +16,7 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    int::BoolOrIntType,
 | 
					    int::BoolOrIntType,
 | 
				
			||||||
    intern::{Intern, Interned, Memoize},
 | 
					    intern::{Intern, Interned, Memoize},
 | 
				
			||||||
 | 
					    memory::PortKind,
 | 
				
			||||||
    module::{
 | 
					    module::{
 | 
				
			||||||
        transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, Id, InstantiatedModule,
 | 
					        transform::deduce_resets::deduce_resets, AnnotatedModuleIO, Block, Id, InstantiatedModule,
 | 
				
			||||||
        ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration,
 | 
					        ModuleBody, NameId, NormalModuleBody, ScopedNameId, Stmt, StmtConnect, StmtDeclaration,
 | 
				
			||||||
| 
						 | 
					@ -28,9 +29,9 @@ use crate::{
 | 
				
			||||||
            Insn, InsnField, InsnFieldKind, InsnFieldType, Insns, InsnsBuilding, InsnsBuildingDone,
 | 
					            Insn, InsnField, InsnFieldKind, InsnFieldType, Insns, InsnsBuilding, InsnsBuildingDone,
 | 
				
			||||||
            SlotDebugData, SmallUInt, State, StatePartArrayIndex, StatePartArrayIndexed,
 | 
					            SlotDebugData, SmallUInt, State, StatePartArrayIndex, StatePartArrayIndexed,
 | 
				
			||||||
            StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots,
 | 
					            StatePartIndex, StatePartIndexRange, StatePartKind, StatePartKindBigSlots,
 | 
				
			||||||
            StatePartKindSmallSlots, StatePartLayout, StatePartLen, StatePartsValue,
 | 
					            StatePartKindMemories, StatePartKindSmallSlots, StatePartLayout, StatePartLen,
 | 
				
			||||||
            TypeArrayIndex, TypeArrayIndexes, TypeIndex, TypeIndexRange, TypeLayout, TypeLen,
 | 
					            StatePartsValue, TypeArrayIndex, TypeArrayIndexes, TypeIndex, TypeIndexRange,
 | 
				
			||||||
            TypeParts,
 | 
					            TypeLayout, TypeLen, TypeParts,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        time::{SimDuration, SimInstant},
 | 
					        time::{SimDuration, SimInstant},
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -136,7 +137,7 @@ impl<T: Type> CompiledTypeLayout<T> {
 | 
				
			||||||
                            name: Interned::default(),
 | 
					                            name: Interned::default(),
 | 
				
			||||||
                            ty: *input,
 | 
					                            ty: *input,
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
                        layout.big_slots = StatePartLayout::scalar(debug_data);
 | 
					                        layout.big_slots = StatePartLayout::scalar(debug_data, ());
 | 
				
			||||||
                        CompiledTypeLayout {
 | 
					                        CompiledTypeLayout {
 | 
				
			||||||
                            ty: *input,
 | 
					                            ty: *input,
 | 
				
			||||||
                            layout: layout.into(),
 | 
					                            layout: layout.into(),
 | 
				
			||||||
| 
						 | 
					@ -1163,14 +1164,20 @@ impl Assignment {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    (
 | 
					                    (
 | 
				
			||||||
                        _,
 | 
					                        _,
 | 
				
			||||||
                        InsnFieldType::SmallUInt(_)
 | 
					                        InsnFieldType::Memory(_)
 | 
				
			||||||
 | 
					                        | InsnFieldType::SmallUInt(_)
 | 
				
			||||||
                        | InsnFieldType::SmallSInt(_)
 | 
					                        | InsnFieldType::SmallSInt(_)
 | 
				
			||||||
                        | InsnFieldType::InternedBigInt(_)
 | 
					                        | InsnFieldType::InternedBigInt(_)
 | 
				
			||||||
                        | InsnFieldType::U8(_)
 | 
					                        | InsnFieldType::U8(_)
 | 
				
			||||||
                        | InsnFieldType::USize(_)
 | 
					                        | InsnFieldType::USize(_)
 | 
				
			||||||
                        | InsnFieldType::Empty(_),
 | 
					                        | InsnFieldType::Empty(_),
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    | (InsnFieldKind::Immediate | InsnFieldKind::BranchTarget, _) => {}
 | 
					                    | (
 | 
				
			||||||
 | 
					                        InsnFieldKind::Immediate
 | 
				
			||||||
 | 
					                        | InsnFieldKind::Memory
 | 
				
			||||||
 | 
					                        | InsnFieldKind::BranchTarget,
 | 
				
			||||||
 | 
					                        _,
 | 
				
			||||||
 | 
					                    ) => {}
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -1207,6 +1214,20 @@ struct Register {
 | 
				
			||||||
    source_location: SourceLocation,
 | 
					    source_location: SourceLocation,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					enum MemoryPort {
 | 
				
			||||||
 | 
					    ReadOnly {},
 | 
				
			||||||
 | 
					    WriteOnly {},
 | 
				
			||||||
 | 
					    ReadWrite {},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					struct Memory {
 | 
				
			||||||
 | 
					    mem: Mem,
 | 
				
			||||||
 | 
					    memory: StatePartIndex<StatePartKindMemories>,
 | 
				
			||||||
 | 
					    ports: Vec<MemoryPort>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct Compiler {
 | 
					pub struct Compiler {
 | 
				
			||||||
    insns: Insns<InsnsBuilding>,
 | 
					    insns: Insns<InsnsBuilding>,
 | 
				
			||||||
| 
						 | 
					@ -1227,6 +1248,7 @@ pub struct Compiler {
 | 
				
			||||||
    enum_discriminants: HashMap<CompiledValue<Enum>, StatePartIndex<StatePartKindSmallSlots>>,
 | 
					    enum_discriminants: HashMap<CompiledValue<Enum>, StatePartIndex<StatePartKindSmallSlots>>,
 | 
				
			||||||
    registers: Vec<Register>,
 | 
					    registers: Vec<Register>,
 | 
				
			||||||
    traces: Vec<SimTrace<()>>,
 | 
					    traces: Vec<SimTrace<()>>,
 | 
				
			||||||
 | 
					    memories: Vec<Memory>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Compiler {
 | 
					impl Compiler {
 | 
				
			||||||
| 
						 | 
					@ -1251,6 +1273,7 @@ impl Compiler {
 | 
				
			||||||
            enum_discriminants: HashMap::new(),
 | 
					            enum_discriminants: HashMap::new(),
 | 
				
			||||||
            registers: Vec::new(),
 | 
					            registers: Vec::new(),
 | 
				
			||||||
            traces: Vec::new(),
 | 
					            traces: Vec::new(),
 | 
				
			||||||
 | 
					            memories: Vec::new(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn new_sim_trace(&mut self, kind: SimTraceKind) -> TraceScalarId {
 | 
					    fn new_sim_trace(&mut self, kind: SimTraceKind) -> TraceScalarId {
 | 
				
			||||||
| 
						 | 
					@ -1809,7 +1832,7 @@ impl Compiler {
 | 
				
			||||||
                let dest = self
 | 
					                let dest = self
 | 
				
			||||||
                    .insns
 | 
					                    .insns
 | 
				
			||||||
                    .allocate_variable(&TypeLayout {
 | 
					                    .allocate_variable(&TypeLayout {
 | 
				
			||||||
                        small_slots: StatePartLayout::scalar(debug_data),
 | 
					                        small_slots: StatePartLayout::scalar(debug_data, ()),
 | 
				
			||||||
                        big_slots: StatePartLayout::empty(),
 | 
					                        big_slots: StatePartLayout::empty(),
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    .small_slots
 | 
					                    .small_slots
 | 
				
			||||||
| 
						 | 
					@ -1851,7 +1874,7 @@ impl Compiler {
 | 
				
			||||||
                let dest = self
 | 
					                let dest = self
 | 
				
			||||||
                    .insns
 | 
					                    .insns
 | 
				
			||||||
                    .allocate_variable(&TypeLayout {
 | 
					                    .allocate_variable(&TypeLayout {
 | 
				
			||||||
                        small_slots: StatePartLayout::scalar(debug_data),
 | 
					                        small_slots: StatePartLayout::scalar(debug_data, ()),
 | 
				
			||||||
                        big_slots: StatePartLayout::empty(),
 | 
					                        big_slots: StatePartLayout::empty(),
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    .small_slots
 | 
					                    .small_slots
 | 
				
			||||||
| 
						 | 
					@ -3038,10 +3061,13 @@ impl Compiler {
 | 
				
			||||||
                .state_layout
 | 
					                .state_layout
 | 
				
			||||||
                .ty
 | 
					                .ty
 | 
				
			||||||
                .small_slots
 | 
					                .small_slots
 | 
				
			||||||
                .allocate(&StatePartLayout::scalar(SlotDebugData {
 | 
					                .allocate(&StatePartLayout::scalar(
 | 
				
			||||||
                    name: Interned::default(),
 | 
					                    SlotDebugData {
 | 
				
			||||||
                    ty: Bool.canonical(),
 | 
					                        name: Interned::default(),
 | 
				
			||||||
                }))
 | 
					                        ty: Bool.canonical(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    (),
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
                .start
 | 
					                .start
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let last_clk_was_low = alloc_small_slot("last_clk_was_low");
 | 
					        let last_clk_was_low = alloc_small_slot("last_clk_was_low");
 | 
				
			||||||
| 
						 | 
					@ -3098,10 +3124,13 @@ impl Compiler {
 | 
				
			||||||
                .state_layout
 | 
					                .state_layout
 | 
				
			||||||
                .ty
 | 
					                .ty
 | 
				
			||||||
                .small_slots
 | 
					                .small_slots
 | 
				
			||||||
                .allocate(&StatePartLayout::scalar(SlotDebugData {
 | 
					                .allocate(&StatePartLayout::scalar(
 | 
				
			||||||
                    name: Interned::default(),
 | 
					                    SlotDebugData {
 | 
				
			||||||
                    ty: retval_ty.canonical(),
 | 
					                        name: Interned::default(),
 | 
				
			||||||
                }))
 | 
					                        ty: retval_ty.canonical(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    (),
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
                .start;
 | 
					                .start;
 | 
				
			||||||
            let discriminant_bit_width = enum_value.layout.ty.discriminant_bit_width();
 | 
					            let discriminant_bit_width = enum_value.layout.ty.discriminant_bit_width();
 | 
				
			||||||
            let discriminant_mask = !(!0u64 << discriminant_bit_width);
 | 
					            let discriminant_mask = !(!0u64 << discriminant_bit_width);
 | 
				
			||||||
| 
						 | 
					@ -3289,6 +3318,49 @@ impl Compiler {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.make_trace_decl(*parent_module, target_base)
 | 
					        self.make_trace_decl(*parent_module, target_base)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn compile_memory(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        mem: Mem,
 | 
				
			||||||
 | 
					        instantiated_module: InstantiatedModule,
 | 
				
			||||||
 | 
					        conditions: Interned<[Cond]>,
 | 
				
			||||||
 | 
					        trace_decls: &mut Vec<TraceDecl>,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        let memory = self
 | 
				
			||||||
 | 
					            .insns
 | 
				
			||||||
 | 
					            .state_layout
 | 
				
			||||||
 | 
					            .memories
 | 
				
			||||||
 | 
					            .allocate(&StatePartLayout::scalar(
 | 
				
			||||||
 | 
					                (),
 | 
				
			||||||
 | 
					                mem.initial_value().unwrap_or_else(|| {
 | 
				
			||||||
 | 
					                    Intern::intern_owned(BitVec::repeat(
 | 
				
			||||||
 | 
					                        false,
 | 
				
			||||||
 | 
					                        mem.array_type().type_properties().bit_width,
 | 
				
			||||||
 | 
					                    ))
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					            .start;
 | 
				
			||||||
 | 
					        let ports = mem
 | 
				
			||||||
 | 
					            .ports()
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .map(|&port| {
 | 
				
			||||||
 | 
					                let target_base = TargetBase::MemPort(port);
 | 
				
			||||||
 | 
					                let target = TargetInInstantiatedModule {
 | 
				
			||||||
 | 
					                    instantiated_module,
 | 
				
			||||||
 | 
					                    target: target_base.into(),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                self.decl_conditions.insert(target, conditions);
 | 
				
			||||||
 | 
					                trace_decls.push(self.make_trace_decl(instantiated_module, target_base));
 | 
				
			||||||
 | 
					                todo!("handle read/write");
 | 
				
			||||||
 | 
					                match port.port_kind() {
 | 
				
			||||||
 | 
					                    PortKind::ReadOnly => MemoryPort::ReadOnly {},
 | 
				
			||||||
 | 
					                    PortKind::WriteOnly => MemoryPort::WriteOnly {},
 | 
				
			||||||
 | 
					                    PortKind::ReadWrite => MemoryPort::ReadWrite {},
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					        self.memories.push(Memory { mem, memory, ports });
 | 
				
			||||||
 | 
					        todo!("implement memory");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    fn compile_block(
 | 
					    fn compile_block(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        parent_module: Interned<InstantiatedModule>,
 | 
					        parent_module: Interned<InstantiatedModule>,
 | 
				
			||||||
| 
						 | 
					@ -3298,7 +3370,7 @@ impl Compiler {
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        let Block { memories, stmts } = block;
 | 
					        let Block { memories, stmts } = block;
 | 
				
			||||||
        for memory in memories {
 | 
					        for memory in memories {
 | 
				
			||||||
            todo!("implement memory");
 | 
					            self.compile_memory(memory, *parent_module, conditions, trace_decls);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for stmt in stmts {
 | 
					        for stmt in stmts {
 | 
				
			||||||
            match stmt {
 | 
					            match stmt {
 | 
				
			||||||
| 
						 | 
					@ -3613,11 +3685,17 @@ impl Compiler {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn process_memories(&mut self) {
 | 
				
			||||||
 | 
					        for memory in mem::take(&mut self.memories) {
 | 
				
			||||||
 | 
					            todo!();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    pub fn compile(mut self) -> Compiled<Bundle> {
 | 
					    pub fn compile(mut self) -> Compiled<Bundle> {
 | 
				
			||||||
        let base_module =
 | 
					        let base_module =
 | 
				
			||||||
            *self.compile_module(InstantiatedModule::Base(self.base_module).intern_sized());
 | 
					            *self.compile_module(InstantiatedModule::Base(self.base_module).intern_sized());
 | 
				
			||||||
        self.process_assignments();
 | 
					        self.process_assignments();
 | 
				
			||||||
        self.process_registers();
 | 
					        self.process_registers();
 | 
				
			||||||
 | 
					        self.process_memories();
 | 
				
			||||||
        let clocks_triggered = self.process_clocks();
 | 
					        let clocks_triggered = self.process_clocks();
 | 
				
			||||||
        self.insns
 | 
					        self.insns
 | 
				
			||||||
            .push(Insn::Return, self.base_module.source_location());
 | 
					            .push(Insn::Return, self.base_module.source_location());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,15 +2,18 @@
 | 
				
			||||||
// See Notices.txt for copyright information
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
 | 
					    int::{BoolOrIntType, SInt, UInt},
 | 
				
			||||||
    intern::{Intern, Interned, Memoize},
 | 
					    intern::{Intern, Interned, Memoize},
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::CanonicalType,
 | 
					    ty::CanonicalType,
 | 
				
			||||||
    util::get_many_mut,
 | 
					    util::get_many_mut,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					use bitvec::{boxed::BitBox, slice::BitSlice};
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					use hashbrown::HashMap;
 | 
				
			||||||
use num_bigint::BigInt;
 | 
					use num_bigint::BigInt;
 | 
				
			||||||
use num_traits::{One, Signed, ToPrimitive, Zero};
 | 
					use num_traits::{One, Signed, ToPrimitive, Zero};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
 | 
					    any::TypeId,
 | 
				
			||||||
    borrow::BorrowMut,
 | 
					    borrow::BorrowMut,
 | 
				
			||||||
    convert::Infallible,
 | 
					    convert::Infallible,
 | 
				
			||||||
    fmt,
 | 
					    fmt,
 | 
				
			||||||
| 
						 | 
					@ -28,6 +31,7 @@ pub(crate) const MIN_BITS_FOR_NEEDING_BIG: usize = SmallUInt::BITS as usize + 1;
 | 
				
			||||||
pub(crate) enum InsnFieldKind {
 | 
					pub(crate) enum InsnFieldKind {
 | 
				
			||||||
    Input,
 | 
					    Input,
 | 
				
			||||||
    Output,
 | 
					    Output,
 | 
				
			||||||
 | 
					    Memory,
 | 
				
			||||||
    Immediate,
 | 
					    Immediate,
 | 
				
			||||||
    BranchTarget,
 | 
					    BranchTarget,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -108,6 +112,7 @@ macro_rules! insn_field_enum {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
insn_field_enum! {
 | 
					insn_field_enum! {
 | 
				
			||||||
    pub(crate) enum InsnFieldType<Transform: InsnFieldTypeTransform> {
 | 
					    pub(crate) enum InsnFieldType<Transform: InsnFieldTypeTransform> {
 | 
				
			||||||
 | 
					        Memory(Transform::Type<StatePartIndex<StatePartKindMemories>>),
 | 
				
			||||||
        SmallSlot(Transform::Type<StatePartIndex<StatePartKindSmallSlots>>),
 | 
					        SmallSlot(Transform::Type<StatePartIndex<StatePartKindSmallSlots>>),
 | 
				
			||||||
        BigSlot(Transform::Type<StatePartIndex<StatePartKindBigSlots>>),
 | 
					        BigSlot(Transform::Type<StatePartIndex<StatePartKindBigSlots>>),
 | 
				
			||||||
        SmallSlotArrayIndexed(Transform::Type<StatePartArrayIndexed<StatePartKindSmallSlots>>),
 | 
					        SmallSlotArrayIndexed(Transform::Type<StatePartArrayIndexed<StatePartKindSmallSlots>>),
 | 
				
			||||||
| 
						 | 
					@ -206,7 +211,8 @@ impl Insn {
 | 
				
			||||||
                            continue;
 | 
					                            continue;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    InsnFieldType::SmallSlot(_)
 | 
					                    InsnFieldType::Memory(_)
 | 
				
			||||||
 | 
					                    | InsnFieldType::SmallSlot(_)
 | 
				
			||||||
                    | InsnFieldType::BigSlot(_)
 | 
					                    | InsnFieldType::BigSlot(_)
 | 
				
			||||||
                    | InsnFieldType::SmallSlotArrayIndexed(_)
 | 
					                    | InsnFieldType::SmallSlotArrayIndexed(_)
 | 
				
			||||||
                    | InsnFieldType::BigSlotArrayIndexed(_)
 | 
					                    | InsnFieldType::BigSlotArrayIndexed(_)
 | 
				
			||||||
| 
						 | 
					@ -216,9 +222,15 @@ impl Insn {
 | 
				
			||||||
                    | InsnFieldType::U8(_)
 | 
					                    | InsnFieldType::U8(_)
 | 
				
			||||||
                    | InsnFieldType::Empty(_) => {}
 | 
					                    | InsnFieldType::Empty(_) => {}
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                InsnFieldKind::Input | InsnFieldKind::Output | InsnFieldKind::Immediate => {}
 | 
					                InsnFieldKind::Input
 | 
				
			||||||
 | 
					                | InsnFieldKind::Memory
 | 
				
			||||||
 | 
					                | InsnFieldKind::Output
 | 
				
			||||||
 | 
					                | InsnFieldKind::Immediate => {}
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            match field.ty {
 | 
					            match field.ty {
 | 
				
			||||||
 | 
					                InsnFieldType::Memory(v) => {
 | 
				
			||||||
 | 
					                    v.debug_fmt(f, ",", " // ", "", state_layout)?;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                InsnFieldType::SmallSlot(v) => {
 | 
					                InsnFieldType::SmallSlot(v) => {
 | 
				
			||||||
                    v.debug_fmt(f, ",", " // ", "", state_layout)?;
 | 
					                    v.debug_fmt(f, ",", " // ", "", state_layout)?;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -577,9 +589,10 @@ pub(crate) trait StatePartKind:
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const NAME: &'static str;
 | 
					    const NAME: &'static str;
 | 
				
			||||||
    type DebugData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy;
 | 
					    type DebugData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy;
 | 
				
			||||||
 | 
					    type LayoutData: Send + Sync + Eq + Hash + fmt::Debug + 'static + Copy;
 | 
				
			||||||
    type State: fmt::Debug + 'static + Clone;
 | 
					    type State: fmt::Debug + 'static + Clone;
 | 
				
			||||||
    type BorrowedState<'a>: 'a;
 | 
					    type BorrowedState<'a>: 'a;
 | 
				
			||||||
    fn new_state(len: StatePartLen<Self>) -> Self::State;
 | 
					    fn new_state(layout_data: &[Self::LayoutData]) -> Self::State;
 | 
				
			||||||
    fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>;
 | 
					    fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a>;
 | 
				
			||||||
    fn part_debug_data<BK: InsnsBuildingKind>(
 | 
					    fn part_debug_data<BK: InsnsBuildingKind>(
 | 
				
			||||||
        state_layout: &StateLayout<BK>,
 | 
					        state_layout: &StateLayout<BK>,
 | 
				
			||||||
| 
						 | 
					@ -950,8 +963,8 @@ macro_rules! make_state_part_kinds {
 | 
				
			||||||
                Self {
 | 
					                Self {
 | 
				
			||||||
                    insns,
 | 
					                    insns,
 | 
				
			||||||
                    pc: 0,
 | 
					                    pc: 0,
 | 
				
			||||||
                    $($state_field: StatePart::new(insns.state_layout.$state_field.len()),)*
 | 
					                    $($state_field: StatePart::new(&insns.state_layout.$state_field.layout_data),)*
 | 
				
			||||||
                    $($type_field: StatePart::new(insns.state_layout.ty.$type_field.len()),)*
 | 
					                    $($type_field: StatePart::new(&insns.state_layout.ty.$type_field.layout_data),)*
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            pub(crate) fn borrow(&mut self) -> BorrowedState<'_> {
 | 
					            pub(crate) fn borrow(&mut self) -> BorrowedState<'_> {
 | 
				
			||||||
| 
						 | 
					@ -1150,10 +1163,11 @@ make_state_part_kinds! {
 | 
				
			||||||
    impl StatePartKind for StatePartKindSmallStack {
 | 
					    impl StatePartKind for StatePartKindSmallStack {
 | 
				
			||||||
        const NAME: &'static str = "SmallStack";
 | 
					        const NAME: &'static str = "SmallStack";
 | 
				
			||||||
        type DebugData = ();
 | 
					        type DebugData = ();
 | 
				
			||||||
 | 
					        type LayoutData = ();
 | 
				
			||||||
        type State = Stack<SmallUInt>;
 | 
					        type State = Stack<SmallUInt>;
 | 
				
			||||||
        type BorrowedState<'a> = BorrowedStack<'a, SmallUInt>;
 | 
					        type BorrowedState<'a> = BorrowedStack<'a, SmallUInt>;
 | 
				
			||||||
        fn new_state(len: StatePartLen<Self>) -> Self::State {
 | 
					        fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
 | 
				
			||||||
            Stack::new(len.value.try_into().expect("state is too big"))
 | 
					            Stack::new(layout_data.len())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
					        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
				
			||||||
            state.borrow()
 | 
					            state.borrow()
 | 
				
			||||||
| 
						 | 
					@ -1169,10 +1183,11 @@ make_state_part_kinds! {
 | 
				
			||||||
    impl StatePartKind for StatePartKindBigStack {
 | 
					    impl StatePartKind for StatePartKindBigStack {
 | 
				
			||||||
        const NAME: &'static str = "BigStack";
 | 
					        const NAME: &'static str = "BigStack";
 | 
				
			||||||
        type DebugData = ();
 | 
					        type DebugData = ();
 | 
				
			||||||
 | 
					        type LayoutData = ();
 | 
				
			||||||
        type State = Stack<BigInt>;
 | 
					        type State = Stack<BigInt>;
 | 
				
			||||||
        type BorrowedState<'a> = BorrowedStack<'a, BigInt>;
 | 
					        type BorrowedState<'a> = BorrowedStack<'a, BigInt>;
 | 
				
			||||||
        fn new_state(len: StatePartLen<Self>) -> Self::State {
 | 
					        fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
 | 
				
			||||||
            Stack::new(len.value.try_into().expect("state is too big"))
 | 
					            Stack::new(layout_data.len())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
					        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
				
			||||||
            state.borrow()
 | 
					            state.borrow()
 | 
				
			||||||
| 
						 | 
					@ -1184,14 +1199,35 @@ make_state_part_kinds! {
 | 
				
			||||||
            state_layout.big_stack.debug_data.get(part_index.as_usize())
 | 
					            state_layout.big_stack.debug_data.get(part_index.as_usize())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }*/
 | 
					    }*/
 | 
				
			||||||
 | 
					    #[state, field = memories]
 | 
				
			||||||
 | 
					    impl StatePartKind for StatePartKindMemories {
 | 
				
			||||||
 | 
					        const NAME: &'static str = "Memories";
 | 
				
			||||||
 | 
					        type DebugData = ();
 | 
				
			||||||
 | 
					        type LayoutData = Interned<BitSlice>;
 | 
				
			||||||
 | 
					        type State = Box<[BitBox]>;
 | 
				
			||||||
 | 
					        type BorrowedState<'a> = &'a mut [BitBox];
 | 
				
			||||||
 | 
					        fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
 | 
				
			||||||
 | 
					            layout_data.iter().map(|initial_data| BitBox::from_bitslice(initial_data)).collect()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
				
			||||||
 | 
					            state
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        fn part_debug_data<BK: InsnsBuildingKind>(
 | 
				
			||||||
 | 
					            state_layout: &StateLayout<BK>,
 | 
				
			||||||
 | 
					            part_index: StatePartIndex<Self>,
 | 
				
			||||||
 | 
					        ) -> Option<&Self::DebugData> {
 | 
				
			||||||
 | 
					            state_layout.memories.debug_data.get(part_index.as_usize())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    #[type, field = small_slots]
 | 
					    #[type, field = small_slots]
 | 
				
			||||||
    impl StatePartKind for StatePartKindSmallSlots {
 | 
					    impl StatePartKind for StatePartKindSmallSlots {
 | 
				
			||||||
        const NAME: &'static str = "SmallSlots";
 | 
					        const NAME: &'static str = "SmallSlots";
 | 
				
			||||||
        type DebugData = SlotDebugData;
 | 
					        type DebugData = SlotDebugData;
 | 
				
			||||||
 | 
					        type LayoutData = ();
 | 
				
			||||||
        type State = Box<[SmallUInt]>;
 | 
					        type State = Box<[SmallUInt]>;
 | 
				
			||||||
        type BorrowedState<'a> = &'a mut [SmallUInt];
 | 
					        type BorrowedState<'a> = &'a mut [SmallUInt];
 | 
				
			||||||
        fn new_state(len: StatePartLen<Self>) -> Self::State {
 | 
					        fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
 | 
				
			||||||
            vec![0; len.value.try_into().expect("state is too big")].into_boxed_slice()
 | 
					            vec![0; layout_data.len()].into_boxed_slice()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
					        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
				
			||||||
            state
 | 
					            state
 | 
				
			||||||
| 
						 | 
					@ -1207,10 +1243,11 @@ make_state_part_kinds! {
 | 
				
			||||||
    impl StatePartKind for StatePartKindBigSlots {
 | 
					    impl StatePartKind for StatePartKindBigSlots {
 | 
				
			||||||
        const NAME: &'static str = "BigSlots";
 | 
					        const NAME: &'static str = "BigSlots";
 | 
				
			||||||
        type DebugData = SlotDebugData;
 | 
					        type DebugData = SlotDebugData;
 | 
				
			||||||
 | 
					        type LayoutData = ();
 | 
				
			||||||
        type State = Box<[BigInt]>;
 | 
					        type State = Box<[BigInt]>;
 | 
				
			||||||
        type BorrowedState<'a> = &'a mut [BigInt];
 | 
					        type BorrowedState<'a> = &'a mut [BigInt];
 | 
				
			||||||
        fn new_state(len: StatePartLen<Self>) -> Self::State {
 | 
					        fn new_state(layout_data: &[Self::LayoutData]) -> Self::State {
 | 
				
			||||||
            std::iter::repeat_with(BigInt::default).take(len.value.try_into().expect("state is too big")).collect()
 | 
					            layout_data.iter().map(|_| BigInt::default()).collect()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
					        fn borrow_state<'a>(state: &'a mut Self::State) -> Self::BorrowedState<'a> {
 | 
				
			||||||
            state
 | 
					            state
 | 
				
			||||||
| 
						 | 
					@ -1348,6 +1385,7 @@ impl<K: StatePartKind<DebugData = SlotDebugData>, BK: InsnsBuildingKind> StatePa
 | 
				
			||||||
                .iter()
 | 
					                .iter()
 | 
				
			||||||
                .map(|v| v.with_prefixed_debug_names(prefix))
 | 
					                .map(|v| v.with_prefixed_debug_names(prefix))
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
 | 
					            layout_data: self.layout_data.clone(),
 | 
				
			||||||
            _phantom: PhantomData,
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1358,6 +1396,7 @@ impl<K: StatePartKind<DebugData = SlotDebugData>, BK: InsnsBuildingKind> StatePa
 | 
				
			||||||
                .iter()
 | 
					                .iter()
 | 
				
			||||||
                .map(|v| v.with_anonymized_debug_info())
 | 
					                .map(|v| v.with_anonymized_debug_info())
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
 | 
					            layout_data: self.layout_data.clone(),
 | 
				
			||||||
            _phantom: PhantomData,
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1552,6 +1591,7 @@ impl<K: StatePartKind> fmt::Debug for StatePartLen<K> {
 | 
				
			||||||
#[derive(Clone, PartialEq, Eq, Hash)]
 | 
					#[derive(Clone, PartialEq, Eq, Hash)]
 | 
				
			||||||
pub(crate) struct StatePartLayout<K: StatePartKind, BK: InsnsBuildingKind> {
 | 
					pub(crate) struct StatePartLayout<K: StatePartKind, BK: InsnsBuildingKind> {
 | 
				
			||||||
    pub(crate) debug_data: BK::Vec<K::DebugData>,
 | 
					    pub(crate) debug_data: BK::Vec<K::DebugData>,
 | 
				
			||||||
 | 
					    pub(crate) layout_data: BK::Vec<K::LayoutData>,
 | 
				
			||||||
    pub(crate) _phantom: PhantomData<K>,
 | 
					    pub(crate) _phantom: PhantomData<K>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1572,6 +1612,7 @@ impl<K: StatePartKind, BK: InsnsBuildingKind> StatePartLayout<K, BK> {
 | 
				
			||||||
    pub(crate) fn empty() -> Self {
 | 
					    pub(crate) fn empty() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            debug_data: Default::default(),
 | 
					            debug_data: Default::default(),
 | 
				
			||||||
 | 
					            layout_data: Default::default(),
 | 
				
			||||||
            _phantom: PhantomData,
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1583,15 +1624,17 @@ impl<K: StatePartKind> From<StatePartLayout<K, InsnsBuilding>>
 | 
				
			||||||
    fn from(value: StatePartLayout<K, InsnsBuilding>) -> Self {
 | 
					    fn from(value: StatePartLayout<K, InsnsBuilding>) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            debug_data: Intern::intern_owned(value.debug_data),
 | 
					            debug_data: Intern::intern_owned(value.debug_data),
 | 
				
			||||||
 | 
					            layout_data: Intern::intern_owned(value.layout_data),
 | 
				
			||||||
            _phantom: PhantomData,
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<K: StatePartKind> StatePartLayout<K, InsnsBuilding> {
 | 
					impl<K: StatePartKind> StatePartLayout<K, InsnsBuilding> {
 | 
				
			||||||
    pub(crate) fn scalar(debug_data: K::DebugData) -> Self {
 | 
					    pub(crate) fn scalar(debug_data: K::DebugData, layout_data: K::LayoutData) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            debug_data: vec![debug_data],
 | 
					            debug_data: vec![debug_data],
 | 
				
			||||||
 | 
					            layout_data: vec![layout_data],
 | 
				
			||||||
            _phantom: PhantomData,
 | 
					            _phantom: PhantomData,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1609,9 +1652,11 @@ impl<K: StatePartKind> StatePartLayout<K, InsnsBuilding> {
 | 
				
			||||||
        let len = layout.len();
 | 
					        let len = layout.len();
 | 
				
			||||||
        let Self {
 | 
					        let Self {
 | 
				
			||||||
            debug_data,
 | 
					            debug_data,
 | 
				
			||||||
 | 
					            layout_data,
 | 
				
			||||||
            _phantom: _,
 | 
					            _phantom: _,
 | 
				
			||||||
        } = self;
 | 
					        } = self;
 | 
				
			||||||
        debug_data.extend_from_slice(&layout.debug_data);
 | 
					        debug_data.extend_from_slice(&layout.debug_data);
 | 
				
			||||||
 | 
					        layout_data.extend_from_slice(&layout.layout_data);
 | 
				
			||||||
        StatePartIndexRange { start, len }
 | 
					        StatePartIndexRange { start, len }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1620,13 +1665,18 @@ impl<K: StatePartKind, BK: InsnsBuildingKind> fmt::Debug for StatePartLayout<K,
 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
					    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
				
			||||||
        let Self {
 | 
					        let Self {
 | 
				
			||||||
            debug_data,
 | 
					            debug_data,
 | 
				
			||||||
 | 
					            layout_data,
 | 
				
			||||||
            _phantom: _,
 | 
					            _phantom: _,
 | 
				
			||||||
        } = self;
 | 
					        } = self;
 | 
				
			||||||
        write!(f, "StatePartAllocationLayout<{}>", K::NAME)?;
 | 
					        write!(f, "StatePartAllocationLayout<{}>", K::NAME)?;
 | 
				
			||||||
        f.debug_struct("")
 | 
					        let mut debug_struct = f.debug_struct("");
 | 
				
			||||||
 | 
					        debug_struct
 | 
				
			||||||
            .field("len", &debug_data.len())
 | 
					            .field("len", &debug_data.len())
 | 
				
			||||||
            .field("debug_data", debug_data)
 | 
					            .field("debug_data", debug_data);
 | 
				
			||||||
            .finish_non_exhaustive()
 | 
					        if TypeId::of::<K::LayoutData>() != TypeId::of::<()>() {
 | 
				
			||||||
 | 
					            debug_struct.field("layout_data", layout_data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        debug_struct.finish_non_exhaustive()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1723,9 +1773,9 @@ pub(crate) struct StatePart<K: StatePartKind> {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<K: StatePartKind> StatePart<K> {
 | 
					impl<K: StatePartKind> StatePart<K> {
 | 
				
			||||||
    pub(crate) fn new(len: StatePartLen<K>) -> Self {
 | 
					    pub(crate) fn new(layout_data: &[K::LayoutData]) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            value: K::new_state(len),
 | 
					            value: K::new_state(layout_data),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pub(crate) fn borrow<'a>(&'a mut self) -> BorrowedStatePart<'a, K> {
 | 
					    pub(crate) fn borrow<'a>(&'a mut self) -> BorrowedStatePart<'a, K> {
 | 
				
			||||||
| 
						 | 
					@ -2020,7 +2070,8 @@ impl From<Insns<InsnsBuilding>> for Insns<InsnsBuildingDone> {
 | 
				
			||||||
                                .address
 | 
					                                .address
 | 
				
			||||||
                                .expect("label address not set");
 | 
					                                .expect("label address not set");
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        InsnFieldType::SmallSlot(_)
 | 
					                        InsnFieldType::Memory(_)
 | 
				
			||||||
 | 
					                        | InsnFieldType::SmallSlot(_)
 | 
				
			||||||
                        | InsnFieldType::BigSlot(_)
 | 
					                        | InsnFieldType::BigSlot(_)
 | 
				
			||||||
                        | InsnFieldType::SmallSlotArrayIndexed(_)
 | 
					                        | InsnFieldType::SmallSlotArrayIndexed(_)
 | 
				
			||||||
                        | InsnFieldType::BigSlotArrayIndexed(_)
 | 
					                        | InsnFieldType::BigSlotArrayIndexed(_)
 | 
				
			||||||
| 
						 | 
					@ -2032,7 +2083,10 @@ impl From<Insns<InsnsBuilding>> for Insns<InsnsBuildingDone> {
 | 
				
			||||||
                            unreachable!()
 | 
					                            unreachable!()
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    InsnFieldKind::Input | InsnFieldKind::Output | InsnFieldKind::Immediate => {}
 | 
					                    InsnFieldKind::Input
 | 
				
			||||||
 | 
					                    | InsnFieldKind::Memory
 | 
				
			||||||
 | 
					                    | InsnFieldKind::Output
 | 
				
			||||||
 | 
					                    | InsnFieldKind::Immediate => {}
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -2050,6 +2104,7 @@ impl State {
 | 
				
			||||||
        let Self {
 | 
					        let Self {
 | 
				
			||||||
            insns: _,
 | 
					            insns: _,
 | 
				
			||||||
            pc,
 | 
					            pc,
 | 
				
			||||||
 | 
					            memories: _,
 | 
				
			||||||
            small_slots: _,
 | 
					            small_slots: _,
 | 
				
			||||||
            big_slots: _,
 | 
					            big_slots: _,
 | 
				
			||||||
        } = self;
 | 
					        } = self;
 | 
				
			||||||
| 
						 | 
					@ -2161,6 +2216,44 @@ fn cast_bigint_to_uint(src: &BigInt, dest_width: usize) -> BigInt {
 | 
				
			||||||
    src & &*bigint_mask(dest_width)
 | 
					    src & &*bigint_mask(dest_width)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn memory_get_mut(
 | 
				
			||||||
 | 
					    memory: &mut BitSlice,
 | 
				
			||||||
 | 
					    addr: SmallUInt,
 | 
				
			||||||
 | 
					    stride: usize,
 | 
				
			||||||
 | 
					    start: usize,
 | 
				
			||||||
 | 
					    width: usize,
 | 
				
			||||||
 | 
					) -> Option<&mut BitSlice> {
 | 
				
			||||||
 | 
					    let start = usize::try_from(addr)
 | 
				
			||||||
 | 
					        .ok()?
 | 
				
			||||||
 | 
					        .checked_mul(stride)?
 | 
				
			||||||
 | 
					        .checked_add(start)?;
 | 
				
			||||||
 | 
					    memory.get_mut(start..start.checked_add(width)?)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn memory_read_big<T: BoolOrIntType>(
 | 
				
			||||||
 | 
					    memory: &mut BitSlice,
 | 
				
			||||||
 | 
					    addr: SmallUInt,
 | 
				
			||||||
 | 
					    stride: usize,
 | 
				
			||||||
 | 
					    start: usize,
 | 
				
			||||||
 | 
					    width: usize,
 | 
				
			||||||
 | 
					) -> Option<BigInt> {
 | 
				
			||||||
 | 
					    let bits = memory_get_mut(memory, addr, stride, start, width)?;
 | 
				
			||||||
 | 
					    Some(T::bits_to_bigint(bits))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn memory_write_big<T: BoolOrIntType>(
 | 
				
			||||||
 | 
					    memory: &mut BitSlice,
 | 
				
			||||||
 | 
					    addr: SmallUInt,
 | 
				
			||||||
 | 
					    stride: usize,
 | 
				
			||||||
 | 
					    start: usize,
 | 
				
			||||||
 | 
					    width: usize,
 | 
				
			||||||
 | 
					    value: &BigInt,
 | 
				
			||||||
 | 
					) -> Option<()> {
 | 
				
			||||||
 | 
					    let bits = memory_get_mut(memory, addr, stride, start, width)?;
 | 
				
			||||||
 | 
					    T::copy_bits_from_bigint_wrapping(value, bits);
 | 
				
			||||||
 | 
					    Some(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl_insns! {
 | 
					impl_insns! {
 | 
				
			||||||
    #[insn = Insn, next_macro = next, branch_macro = branch]
 | 
					    #[insn = Insn, next_macro = next, branch_macro = branch]
 | 
				
			||||||
    pub(crate) fn State::run(&mut self) -> () {
 | 
					    pub(crate) fn State::run(&mut self) -> () {
 | 
				
			||||||
| 
						 | 
					@ -2702,6 +2795,78 @@ impl_insns! {
 | 
				
			||||||
            next!();
 | 
					            next!();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    MemoryReadUInt {
 | 
				
			||||||
 | 
					        #[kind = Output]
 | 
				
			||||||
 | 
					        dest: StatePartIndex<StatePartKindBigSlots>,
 | 
				
			||||||
 | 
					        #[kind = Memory]
 | 
				
			||||||
 | 
					        memory: StatePartIndex<StatePartKindMemories>,
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        addr: StatePartIndex<StatePartKindSmallSlots>,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        stride: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        start: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        width: usize,
 | 
				
			||||||
 | 
					    } => {
 | 
				
			||||||
 | 
					        let addr = state.small_slots[addr];
 | 
				
			||||||
 | 
					        state.big_slots[dest] = memory_read_big::<UInt>(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default();
 | 
				
			||||||
 | 
					        next!();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    MemoryReadSInt {
 | 
				
			||||||
 | 
					        #[kind = Output]
 | 
				
			||||||
 | 
					        dest: StatePartIndex<StatePartKindBigSlots>,
 | 
				
			||||||
 | 
					        #[kind = Memory]
 | 
				
			||||||
 | 
					        memory: StatePartIndex<StatePartKindMemories>,
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        addr: StatePartIndex<StatePartKindSmallSlots>,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        stride: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        start: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        width: usize,
 | 
				
			||||||
 | 
					    } => {
 | 
				
			||||||
 | 
					        let addr = state.small_slots[addr];
 | 
				
			||||||
 | 
					        state.big_slots[dest] = memory_read_big::<SInt>(&mut state.memories[memory], addr, stride, start, width).unwrap_or_default();
 | 
				
			||||||
 | 
					        next!();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    MemoryWriteUInt {
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        value: StatePartIndex<StatePartKindBigSlots>,
 | 
				
			||||||
 | 
					        #[kind = Memory]
 | 
				
			||||||
 | 
					        memory: StatePartIndex<StatePartKindMemories>,
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        addr: StatePartIndex<StatePartKindSmallSlots>,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        stride: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        start: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        width: usize,
 | 
				
			||||||
 | 
					    } => {
 | 
				
			||||||
 | 
					        let addr = state.small_slots[addr];
 | 
				
			||||||
 | 
					        memory_write_big::<UInt>(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]);
 | 
				
			||||||
 | 
					        next!();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    MemoryWriteSInt {
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        value: StatePartIndex<StatePartKindBigSlots>,
 | 
				
			||||||
 | 
					        #[kind = Memory]
 | 
				
			||||||
 | 
					        memory: StatePartIndex<StatePartKindMemories>,
 | 
				
			||||||
 | 
					        #[kind = Input]
 | 
				
			||||||
 | 
					        addr: StatePartIndex<StatePartKindSmallSlots>,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        stride: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        start: usize,
 | 
				
			||||||
 | 
					        #[kind = Immediate]
 | 
				
			||||||
 | 
					        width: usize,
 | 
				
			||||||
 | 
					    } => {
 | 
				
			||||||
 | 
					        let addr = state.small_slots[addr];
 | 
				
			||||||
 | 
					        memory_write_big::<SInt>(&mut state.memories[memory], addr, stride, start, width, &mut state.big_slots[value]);
 | 
				
			||||||
 | 
					        next!();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    Return => {
 | 
					    Return => {
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:1:1
 | 
					                // at: module-XXXXXXXXXX.rs:1:1
 | 
				
			||||||
| 
						 | 
					@ -41,6 +47,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 2,
 | 
					        pc: 2,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [],
 | 
					            value: [],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:1:1
 | 
					                // at: module-XXXXXXXXXX.rs:1:1
 | 
				
			||||||
| 
						 | 
					@ -67,6 +73,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 5,
 | 
					        pc: 5,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [],
 | 
					            value: [],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:1:1
 | 
					                // at: module-XXXXXXXXXX.rs:1:1
 | 
				
			||||||
| 
						 | 
					@ -162,6 +168,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 18,
 | 
					        pc: 18,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [
 | 
					            value: [
 | 
				
			||||||
                18446744073709551614,
 | 
					                18446744073709551614,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:6:1
 | 
					                // at: module-XXXXXXXXXX.rs:6:1
 | 
				
			||||||
| 
						 | 
					@ -144,6 +150,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 15,
 | 
					        pc: 15,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [
 | 
					            value: [
 | 
				
			||||||
                18446744073709551614,
 | 
					                18446744073709551614,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:4:1
 | 
					                // at: module-XXXXXXXXXX.rs:4:1
 | 
				
			||||||
| 
						 | 
					@ -174,6 +180,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 17,
 | 
					        pc: 17,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [],
 | 
					            value: [],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,12 @@ Simulation {
 | 
				
			||||||
                        ..
 | 
					                        ..
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                memories: StatePartAllocationLayout<Memories> {
 | 
				
			||||||
 | 
					                    len: 0,
 | 
				
			||||||
 | 
					                    debug_data: [],
 | 
				
			||||||
 | 
					                    layout_data: [],
 | 
				
			||||||
 | 
					                    ..
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            insns: [
 | 
					            insns: [
 | 
				
			||||||
                // at: module-XXXXXXXXXX.rs:13:1
 | 
					                // at: module-XXXXXXXXXX.rs:13:1
 | 
				
			||||||
| 
						 | 
					@ -221,6 +227,9 @@ Simulation {
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        pc: 30,
 | 
					        pc: 30,
 | 
				
			||||||
 | 
					        memories: StatePart {
 | 
				
			||||||
 | 
					            value: [],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        small_slots: StatePart {
 | 
					        small_slots: StatePart {
 | 
				
			||||||
            value: [
 | 
					            value: [
 | 
				
			||||||
                18446744073709551614,
 | 
					                18446744073709551614,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue