diff --git a/src/engine/v3/V3Interpreter.v3 b/src/engine/v3/V3Interpreter.v3 index ea50773a4..37134ff8b 100644 --- a/src/engine/v3/V3Interpreter.v3 +++ b/src/engine/v3/V3Interpreter.v3 @@ -925,6 +925,10 @@ component V3Interpreter { V128_LOAD_32_ZERO => doLoadZero(4, DataReaders.read_range_u32); V128_LOAD_64_ZERO => doLoadZero(8, DataReaders.read_range_u64); V128_STORE => doStore(16, DataWriters.write_range_u128, Values.v_v128); + V128_STORE_8_LANE => doStoreLane(1, 0, u8.view, DataWriters.write_range_u8); + V128_STORE_16_LANE => doStoreLane(2, 1, u16.view, DataWriters.write_range_u16); + V128_STORE_32_LANE => doStoreLane(4, 2, u32.view, DataWriters.write_range_u32); + V128_STORE_64_LANE => doStoreLane(8, 3, u64.view, DataWriters.write_range_u64); V128_CONST => { var low = codeptr.read_u64(); var high = codeptr.read_u64(); @@ -1236,6 +1240,30 @@ component V3Interpreter { if (t.reason != TrapReason.NONE) trap(t.reason); else write(t.result, unbox(val)); } + def doStoreLane(size: byte, log2_size: u3, view: u64 -> T, write: (Range, T) -> void) { + var v = Values.v_v128(pop()); + // Decode memarg + var memarg = codeptr.read_MemArg(); + var memory = frame.func.instance.memories[memarg.memory_index]; + var index = popm(memory); + // Decode immediate + var idx = codeptr.read1(); + // Extract lane + var low = v.0, high = v.1; + var val: T; + def half_lanes = 8 >> log2_size; + if (idx < half_lanes) { // Extract a lane from low + var shift = u6.view(idx << u3.+(log2_size, 3)); + val = view(low >> shift); + } else { // Extract a lane from high + var shift = u6.view((idx - half_lanes) << u3.+(log2_size, 3)); + val = view(high >> shift); + } + // Write to memory + var t = memory.range_oil_64(memarg.offset, index, size); + if (t.reason != TrapReason.NONE) trap(t.reason); + else write(t.result, val); + } def doFallthru() { frame.stp += 4; }