From bda1720eaf09ab859325bdbdeccc7bdac6683e0b Mon Sep 17 00:00:00 2001 From: Haoyu Zhang Date: Wed, 1 Nov 2023 02:59:01 -0400 Subject: [PATCH] [v3i/simd]: Implement load_lane instructions --- src/engine/Value.v3 | 1 + src/engine/v3/V3Interpreter.v3 | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/engine/Value.v3 b/src/engine/Value.v3 index 00a3c136b..0b6ce4582 100644 --- a/src/engine/Value.v3 +++ b/src/engine/Value.v3 @@ -141,6 +141,7 @@ component Values { def v_w_8(v: Value) -> u8 { return u8.view(Value.I64.!(v).val); } def v_w_16(v: Value) -> u16 { return u16.view(Value.I64.!(v).val); } def v_w_32(v: Value) -> u32 { return u32.view(Value.I64.!(v).val); } + def v_w_64(v: Value) -> u64 { return u64.view(Value.I64.!(v).val); } def v_v128(v: Value) -> (u64, u64) { var b = Value.V128.!(v); return (b.low, b.high); diff --git a/src/engine/v3/V3Interpreter.v3 b/src/engine/v3/V3Interpreter.v3 index 7b3cfd16a..5e89c1e22 100644 --- a/src/engine/v3/V3Interpreter.v3 +++ b/src/engine/v3/V3Interpreter.v3 @@ -914,6 +914,10 @@ component V3Interpreter { if (t != TrapReason.NONE) trap(t); } V128_LOAD => doLoad(16, DataReaders.read_range_u128, Value.V128); + V128_LOAD_64_LANE => doLoadLane(8, DataReaders.read_range_u64, Value.I64, Values.v_w_64); + V128_LOAD_32_LANE => doLoadLane(4, DataReaders.read_range_u32, Value.I32, Values.v_u); + V128_LOAD_16_LANE => doLoadLane(2, DataReaders.read_range_u32_u16, Value.I32, Values.v_u_16); + V128_LOAD_8_LANE => doLoadLane(1, DataReaders.read_range_u32_u8, Value.I32, Values.v_u_8); V128_STORE => doStore(16, DataWriters.write_range_u128, Values.v_v128); V128_CONST => { var low = codeptr.read_u64(); @@ -1048,6 +1052,25 @@ component V3Interpreter { if (t.reason != TrapReason.NONE) trap(t.reason); else push(box(read(t.result))); } + def doLoadLane(size: byte, read: Range -> T, box: T -> Value, unbox: Value -> R) { + var v = Values.v_v128(pop()); + doLoad(size, read, box); + var val = u64.!(unbox(pop())); + var idx = codeptr.read1(); + var low = v.0, high = v.1; + // Calculate number of lanes in low/high : (bytes(v128) / size) / 2 + def half_lanes = (16 / size) >> 1; + if (idx < half_lanes) { // Update a lane in low + var shift = byte.view(idx * size * 8); + val <<= shift; + low |= val; + } else { // Update a lane in high + var shift = byte.view((idx - half_lanes) * size * 8); + val <<= shift; + high |= val; + } + push(Value.V128(low, high)); + } def doStore(size: byte, write: (Range, T) -> void, unbox: Value -> T) { var memarg = codeptr.read_MemArg(); var memory = frame.func.instance.memories[memarg.memory_index];