using the compiler

SIMD

Single instruction, multiple data via WebAssembly’s native 128-bit vector type.

--enable-simd adds v128 with an f32x4/i32x4 subset (splat, lanes, arithmetic, compares, min/max, bit ops, load/store). Two rules make one source serve two artifacts:

integrate.as — one source, two artifacts
// Scalar without --enable-simd, four lanes wide with it (this repl
// compiles with the flag); the dead branch never compiles, so the
// scalar artifact stays v128-free and loads on non-simd runtimes.
// Raw loads put this behind the unsafe gate.
export unsafe function integrate(xs: usize, vs: usize,
                                 dt: f32, count: i32): void {
    if (ASC_FEATURE_SIMD) {
        for (let i = 0; i < count; i += 4) {
            let x = v128.load(xs + (<usize>i << 2));
            let v = v128.load(vs + (<usize>i << 2));
            v128.store(xs + (<usize>i << 2),
                       f32x4.add(x, f32x4.mul(v, f32x4.splat(dt))));
        }
        return;
    }
    for (let i = 0; i < count; i++) {
        let p = xs + (<usize>i << 2);
        store<f32>(p, load<f32>(p) + load<f32>(vs + (<usize>i << 2)) * dt);
    }
}

export unsafe function demo(): f32 {
    let xs = __alloc(16 << 2);
    let vs = __alloc(16 << 2);
    for (let i = 0; i < 16; i++) {
        store<f32>(xs + (<usize>i << 2), f32(i));
        store<f32>(vs + (<usize>i << 2), 0.5);
    }
    integrate(xs, vs, 2.0, 16);
    let sum: f32 = 0;
    for (let i = 0; i < 16; i++) {
        sum += load<f32>(xs + (<usize>i << 2));
    }
    return sum;   // 120 + 16 × 0.5 × 2.0 = 136, both artifacts
}
lanes.as — wide-only helpers (compiles under the flag)
// f32x4.min/max diverge from the scalar ternary on NaN and ±0;
// compare + bitselect matches scalar bit-for-bit, which is what keeps
// differential harnesses exact (the Box2D W lane uses this shape).
// v128 in a signature is legal only under the flag.
function min4(a: v128, b: v128): v128 {
    return v128.bitselect(a, b, f32x4.le(a, b));
}

export function step(px: f32, py: f32): f32 {
    let c = f32x4.splat(px);
    c = f32x4.replace_lane(c, 1, py);
    let best = min4(c, f32x4.splat(100.0));
    if (ASC_FEATURE_RELAXED_SIMD) {
        // Fused, single-rounding: deterministic against an fmaf
        // reference, but a different golden than mul+add.
        best = f32x4.relaxed_madd(best, f32x4.splat(0.5), f32x4.splat(1.0));
    } else {
        best = f32x4.add(f32x4.mul(best, f32x4.splat(0.5)), f32x4.splat(1.0));
    }
    return f32x4.extract_lane(best, 0);
}

--enable-relaxed-simd adds f32x4.relaxed_madd / relaxed_nmadd and ASC_FEATURE_RELAXED_SIMD. Fused fma is single-rounding deterministic, so the relaxed artifact carries its own bit-exact contract — deterministic output stays byte-identical, just to a different golden.