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