tinywasm 0.9.0-alpha.1

A tiny WebAssembly interpreter
Documentation
use super::Value128;

fn ref_swizzle(a: [u8; 16], idx: [u8; 16]) -> [u8; 16] {
    let mut out = [0u8; 16];
    for i in 0..16 {
        let j = idx[i];
        out[i] = if j < 16 { a[(j & 0x0f) as usize] } else { 0 };
    }
    out
}

fn ref_shuffle(a: [u8; 16], b: [u8; 16], idx: [u8; 16]) -> [u8; 16] {
    let mut out = [0u8; 16];
    for i in 0..16 {
        let j = idx[i] & 31;
        out[i] = if j < 16 { a[j as usize] } else { b[(j & 0x0f) as usize] };
    }
    out
}

#[test]
fn swizzle_matches_reference() {
    let a = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff];

    for seed in 0u32..512 {
        let mut s = [0u8; 16];
        let mut x = seed.wrapping_mul(0x9e37_79b9).wrapping_add(0x7f4a_7c15);
        for byte in &mut s {
            x ^= x << 13;
            x ^= x >> 17;
            x ^= x << 5;
            *byte = (x & 0xff) as u8;
        }

        let got = Value128(a).i8x16_swizzle(Value128(s));
        let expected = ref_swizzle(a, s).into();
        assert_eq!(got, expected, "seed={seed}");
    }
}

#[test]
fn shuffle_matches_reference() {
    let a = [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f];
    let b = [0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf];

    for seed in 0u32..512 {
        let mut idx = [0u8; 16];
        let mut x = seed.wrapping_mul(0x85eb_ca6b).wrapping_add(0xc2b2_ae35);
        for byte in &mut idx {
            x ^= x << 13;
            x ^= x >> 17;
            x ^= x << 5;
            *byte = (x & 0xff) as u8;
        }

        let got = Value128::i8x16_shuffle(Value128(a), Value128(b), Value128(idx));
        let expected = ref_shuffle(a, b, idx).into();
        assert_eq!(got, expected, "seed={seed}");
    }
}