working on simulator...
All checks were successful
/ deps (push) Successful in 20s
/ test (push) Successful in 4m58s

This commit is contained in:
Jacob Lifshay 2024-11-12 22:11:12 -08:00
parent 5b2abd3fca
commit f780e31622
Signed by: programmerjake
SSH key fingerprint: SHA256:B1iRVvUJkvd7upMIiMqn6OyxvD2SgJkAH3ZnUOj6z+c
2 changed files with 1044 additions and 336 deletions

File diff suppressed because it is too large Load diff

View file

@ -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>,