working on simulator...
This commit is contained in:
parent
5b2abd3fca
commit
f780e31622
File diff suppressed because it is too large
Load diff
|
@ -109,6 +109,8 @@ insn_field_enum! {
|
|||
pub(crate) enum InsnFieldType<Transform: InsnFieldTypeTransform> {
|
||||
SmallSlot(Transform::Type<StatePartIndex<StatePartKindSmallSlots>>),
|
||||
BigSlot(Transform::Type<StatePartIndex<StatePartKindBigSlots>>),
|
||||
SmallSlotArrayIndexed(Transform::Type<StatePartArrayIndexed<StatePartKindSmallSlots>>),
|
||||
BigSlotArrayIndexed(Transform::Type<StatePartArrayIndexed<StatePartKindBigSlots>>),
|
||||
SmallUInt(Transform::Type<SmallUInt>),
|
||||
SmallSInt(Transform::Type<SmallSInt>),
|
||||
InternedBigInt(Transform::Type<Interned<BigInt>>),
|
||||
|
@ -787,6 +789,167 @@ macro_rules! make_state_part_kinds {
|
|||
*self.orig_pc = self.pc;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
|
||||
pub(crate) struct TypeArrayIndexes {
|
||||
$(pub(crate) $type_field: Interned<[StatePartArrayIndex<$TypeKind>]>,)*
|
||||
}
|
||||
|
||||
impl TypeArrayIndexes {
|
||||
pub(crate) fn as_ref(&self) -> TypeArrayIndexesRef<'_> {
|
||||
TypeArrayIndexesRef {
|
||||
$($type_field: &self.$type_field,)*
|
||||
}
|
||||
}
|
||||
#[must_use]
|
||||
pub(crate) fn join(self, next: TypeArrayIndex) -> TypeArrayIndexes {
|
||||
TypeArrayIndexes {
|
||||
$($type_field: Interned::from_iter(self.$type_field.iter().copied().chain([next.$type_field])),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct TypeArrayIndex {
|
||||
$(pub(crate) $type_field: StatePartArrayIndex<$TypeKind>,)*
|
||||
}
|
||||
|
||||
impl TypeArrayIndex {
|
||||
pub(crate) fn from_parts(index: StatePartIndex<StatePartKindSmallSlots>, len: usize, stride: TypeLen) -> Self {
|
||||
Self {
|
||||
$($type_field: StatePartArrayIndex {
|
||||
index,
|
||||
len,
|
||||
stride: stride.$type_field,
|
||||
},)*
|
||||
}
|
||||
}
|
||||
pub(crate) fn len(self) -> usize {
|
||||
let len = self.small_slots.len;
|
||||
$(assert_eq!(self.$type_field.len, len, "array length mismatch");)*
|
||||
len
|
||||
}
|
||||
pub(crate) fn index(self) -> StatePartIndex<StatePartKindSmallSlots> {
|
||||
let index = self.small_slots.index;
|
||||
$(assert_eq!(self.$type_field.index, index, "array index mismatch");)*
|
||||
index
|
||||
}
|
||||
pub(crate) fn is_empty(self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub(crate) fn stride(self) -> TypeLen {
|
||||
TypeLen {
|
||||
$($type_field: self.$type_field.stride,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
|
||||
pub(crate) struct TypeArrayIndexesRef<'a> {
|
||||
$(pub(crate) $type_field: &'a [StatePartArrayIndex<$TypeKind>],)*
|
||||
}
|
||||
|
||||
impl<'a> TypeArrayIndexesRef<'a> {
|
||||
pub(crate) fn len(self) -> usize {
|
||||
let len = self.small_slots.len();
|
||||
$(assert_eq!(self.$type_field.len(), len, "indexes count mismatch");)*
|
||||
len
|
||||
}
|
||||
pub(crate) fn is_empty(self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
pub(crate) fn iter(self) -> impl Iterator<Item = TypeArrayIndex> + 'a {
|
||||
(0..self.len()).map(move |i| TypeArrayIndex {
|
||||
$($type_field: self.$type_field[i],)*
|
||||
})
|
||||
}
|
||||
pub(crate) fn for_each_offset(
|
||||
self,
|
||||
mut f: impl FnMut(TypeIndex),
|
||||
) {
|
||||
self.for_each_offset2(TypeIndex {
|
||||
$($type_field: StatePartIndex {
|
||||
value: 0,
|
||||
_phantom: PhantomData,
|
||||
},)*
|
||||
}, &mut f);
|
||||
}
|
||||
pub(crate) fn split_first(self) -> Option<(TypeArrayIndex, Self)> {
|
||||
$(let $type_field = self.$type_field.split_first()?;)*
|
||||
let next = TypeArrayIndex {
|
||||
$($type_field: *$type_field.0,)*
|
||||
};
|
||||
let rest = TypeArrayIndexesRef {
|
||||
$($type_field: $type_field.1,)*
|
||||
};
|
||||
Some((next, rest))
|
||||
}
|
||||
pub(crate) fn for_each_offset2(
|
||||
self,
|
||||
base_offset: TypeIndex,
|
||||
f: &mut (impl FnMut(TypeIndex) + ?Sized),
|
||||
) {
|
||||
if let Some((next, rest)) = self.split_first() {
|
||||
let stride = next.stride();
|
||||
for index in 0..next.len().try_into().expect("array too big") {
|
||||
let mut offset = TypeIndex {
|
||||
$($type_field: StatePartIndex {
|
||||
value: stride
|
||||
.$type_field
|
||||
.value
|
||||
.checked_mul(index)
|
||||
.expect("array too big"),
|
||||
_phantom: PhantomData,
|
||||
},)*
|
||||
};
|
||||
$(offset.$type_field.value =
|
||||
base_offset
|
||||
.$type_field
|
||||
.value
|
||||
.checked_add(offset.$type_field.value)
|
||||
.expect("array too big");)*
|
||||
rest.for_each_offset2(offset, f);
|
||||
}
|
||||
} else {
|
||||
$(assert!(self.$type_field.is_empty(), "indexes count mismatch");)*
|
||||
f(base_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct TypeArrayIndexed {
|
||||
$(pub(crate) $type_field: StatePartArrayIndexed<$TypeKind>,)*
|
||||
}
|
||||
|
||||
impl TypeArrayIndexed {
|
||||
pub(crate) fn from_parts(base: TypeIndex, indexes: TypeArrayIndexes) -> Self {
|
||||
Self {
|
||||
$($type_field: StatePartArrayIndexed {
|
||||
base: base.$type_field,
|
||||
indexes: indexes.$type_field,
|
||||
},)*
|
||||
}
|
||||
}
|
||||
pub(crate) fn base(self) -> TypeIndex {
|
||||
TypeIndex {
|
||||
$($type_field: self.$type_field.base,)*
|
||||
}
|
||||
}
|
||||
pub(crate) fn indexes(self) -> TypeArrayIndexes {
|
||||
TypeArrayIndexes {
|
||||
$($type_field: self.$type_field.indexes,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeIndex> for TypeArrayIndexed {
|
||||
fn from(value: TypeIndex) -> Self {
|
||||
TypeArrayIndexed {
|
||||
$($type_field: value.$type_field.into(),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -933,6 +1096,12 @@ impl SlotDebugData {
|
|||
ty: self.ty,
|
||||
}
|
||||
}
|
||||
pub(crate) fn with_anonymized_debug_info(&self) -> Self {
|
||||
Self {
|
||||
name: Interned::default(),
|
||||
ty: self.ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: StatePartKind<DebugData = SlotDebugData>, BK: InsnsBuildingKind> StatePartLayout<K, BK> {
|
||||
|
@ -946,6 +1115,16 @@ impl<K: StatePartKind<DebugData = SlotDebugData>, BK: InsnsBuildingKind> StatePa
|
|||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
pub(crate) fn with_anonymized_debug_info(&self) -> Self {
|
||||
Self {
|
||||
debug_data: self
|
||||
.debug_data
|
||||
.iter()
|
||||
.map(|v| v.with_anonymized_debug_info())
|
||||
.collect(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<BK: InsnsBuildingKind> TypeLayout<BK> {
|
||||
|
@ -955,6 +1134,63 @@ impl<BK: InsnsBuildingKind> TypeLayout<BK> {
|
|||
big_slots: self.big_slots.with_prefixed_debug_names(prefix),
|
||||
}
|
||||
}
|
||||
pub(crate) fn with_anonymized_debug_info(&self) -> Self {
|
||||
Self {
|
||||
small_slots: self.small_slots.with_anonymized_debug_info(),
|
||||
big_slots: self.big_slots.with_anonymized_debug_info(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct StatePartArrayIndex<K: StatePartKind> {
|
||||
pub(crate) index: StatePartIndex<StatePartKindSmallSlots>,
|
||||
pub(crate) len: usize,
|
||||
pub(crate) stride: StatePartLen<K>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub(crate) struct StatePartArrayIndexed<K: StatePartKind> {
|
||||
pub(crate) base: StatePartIndex<K>,
|
||||
pub(crate) indexes: Interned<[StatePartArrayIndex<K>]>,
|
||||
}
|
||||
|
||||
impl<K: StatePartKind> From<StatePartIndex<K>> for StatePartArrayIndexed<K> {
|
||||
fn from(base: StatePartIndex<K>) -> Self {
|
||||
Self {
|
||||
base,
|
||||
indexes: Interned::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: StatePartKind> StatePartArrayIndexed<K> {
|
||||
pub(crate) fn for_each_target2(
|
||||
base: StatePartIndex<K>,
|
||||
indexes: &[StatePartArrayIndex<K>],
|
||||
f: &mut (impl FnMut(StatePartIndex<K>) + ?Sized),
|
||||
) {
|
||||
if let [next, rest @ ..] = indexes {
|
||||
for i in 0..next.len.try_into().expect("array too big") {
|
||||
Self::for_each_target2(
|
||||
StatePartIndex {
|
||||
value: base
|
||||
.value
|
||||
.checked_add(next.stride.value.checked_mul(i).expect("array too big"))
|
||||
.expect("array too big"),
|
||||
_phantom: PhantomData,
|
||||
},
|
||||
rest,
|
||||
f,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
f(base);
|
||||
}
|
||||
}
|
||||
pub(crate) fn for_each_target(self, mut f: impl FnMut(StatePartIndex<K>)) {
|
||||
Self::for_each_target2(self.base, &self.indexes, &mut f);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -1435,6 +1671,26 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
impl BorrowedState<'_> {
|
||||
fn eval_array_indexed<K: StatePartKind>(
|
||||
&self,
|
||||
array_indexed: StatePartArrayIndexed<K>,
|
||||
) -> Option<StatePartIndex<K>> {
|
||||
let StatePartArrayIndexed {
|
||||
base: mut retval,
|
||||
indexes,
|
||||
} = array_indexed;
|
||||
for StatePartArrayIndex { index, len, stride } in indexes {
|
||||
let index = self.small_slots[index];
|
||||
if index >= len as SmallUInt {
|
||||
return None;
|
||||
}
|
||||
retval.value += stride.value * index as u32;
|
||||
}
|
||||
Some(retval)
|
||||
}
|
||||
}
|
||||
|
||||
fn bigint_pow2(width: usize) -> Interned<BigInt> {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct MyMemoize;
|
||||
|
@ -1515,6 +1771,69 @@ impl_insns! {
|
|||
}
|
||||
next!();
|
||||
}
|
||||
CopySmall {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindSmallSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartIndex<StatePartKindSmallSlots>,
|
||||
} => {
|
||||
state.small_slots[dest] = state.small_slots[src];
|
||||
next!();
|
||||
}
|
||||
ReadIndexed {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindBigSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartArrayIndexed<StatePartKindBigSlots>,
|
||||
} => {
|
||||
if let Some(src) = state.eval_array_indexed(src) {
|
||||
if dest != src {
|
||||
let [dest, src] = state.big_slots.get_many_mut([dest, src]);
|
||||
dest.clone_from(src);
|
||||
}
|
||||
} else {
|
||||
state.big_slots[dest] = BigInt::ZERO;
|
||||
}
|
||||
next!();
|
||||
}
|
||||
ReadSmallIndexed {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindSmallSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartArrayIndexed<StatePartKindSmallSlots>,
|
||||
} => {
|
||||
if let Some(src) = state.eval_array_indexed(src) {
|
||||
state.small_slots[dest] = state.small_slots[src];
|
||||
} else {
|
||||
state.small_slots[dest] = 0;
|
||||
}
|
||||
next!();
|
||||
}
|
||||
WriteIndexed {
|
||||
#[kind = Output]
|
||||
dest: StatePartArrayIndexed<StatePartKindBigSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartIndex<StatePartKindBigSlots>,
|
||||
} => {
|
||||
if let Some(dest) = state.eval_array_indexed(dest) {
|
||||
if dest != src {
|
||||
let [dest, src] = state.big_slots.get_many_mut([dest, src]);
|
||||
dest.clone_from(src);
|
||||
}
|
||||
}
|
||||
next!();
|
||||
}
|
||||
WriteSmallIndexed {
|
||||
#[kind = Output]
|
||||
dest: StatePartArrayIndexed<StatePartKindSmallSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartIndex<StatePartKindSmallSlots>,
|
||||
} => {
|
||||
if let Some(dest) = state.eval_array_indexed(dest) {
|
||||
state.small_slots[dest] = state.small_slots[src];
|
||||
}
|
||||
next!();
|
||||
}
|
||||
CastToSInt {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindBigSlots>,
|
||||
|
@ -1792,6 +2111,22 @@ impl_insns! {
|
|||
state.big_slots[dest] = value;
|
||||
next!();
|
||||
}
|
||||
ReduceBitXor {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindBigSlots>,
|
||||
#[kind = Input]
|
||||
src: StatePartIndex<StatePartKindBigSlots>,
|
||||
#[kind = Immediate]
|
||||
input_width: usize,
|
||||
} => {
|
||||
let src = &state.big_slots[src];
|
||||
let src = src & &*bigint_mask(input_width);
|
||||
let value = BigInt::from(
|
||||
src.to_biguint().expect("known to be non-negative").count_ones() % 2,
|
||||
);
|
||||
state.big_slots[dest] = value;
|
||||
next!();
|
||||
}
|
||||
Const {
|
||||
#[kind = Output]
|
||||
dest: StatePartIndex<StatePartKindBigSlots>,
|
||||
|
|
Loading…
Reference in a new issue