sim: WIP adding memory support
This commit is contained in:
parent
e504cfebfe
commit
3ed7827485
|
@ -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…
Reference in a new issue