diff --git a/runtime/src/main/java/run/endive/runtime/InterpreterMachine.java b/runtime/src/main/java/run/endive/runtime/InterpreterMachine.java index e686c7fef..ebefdb4d1 100644 --- a/runtime/src/main/java/run/endive/runtime/InterpreterMachine.java +++ b/runtime/src/main/java/run/endive/runtime/InterpreterMachine.java @@ -2457,8 +2457,8 @@ private static void LOCAL_SET(MStack stack, Operands operands, StackFrame curren if (localType.isObjectRef()) { currentStackFrame.setLocalRef(i, stack.popRef()); } else if (localType.equals(ValType.V128)) { - currentStackFrame.setLocal(i, stack.pop()); currentStackFrame.setLocal(i + 1, stack.pop()); + currentStackFrame.setLocal(i, stack.pop()); } else { currentStackFrame.setLocal(i, stack.pop()); } @@ -2472,10 +2472,10 @@ private static void LOCAL_TEE(MStack stack, Operands operands, StackFrame curren if (localType.isObjectRef()) { currentStackFrame.setLocalRef(i, stack.peekRef()); } else if (localType.equals(ValType.V128)) { - var tmp = stack.pop(); - currentStackFrame.setLocal(i, tmp); - currentStackFrame.setLocal(i + 1, stack.peek()); - stack.push(tmp); + var high = stack.pop(); + currentStackFrame.setLocal(i + 1, high); + currentStackFrame.setLocal(i, stack.peek()); + stack.push(high); } else { currentStackFrame.setLocal(i, stack.peek()); } diff --git a/simd/src/test/java/run/endive/simd/BasicSimdTest.java b/simd/src/test/java/run/endive/simd/BasicSimdTest.java index f4168bddb..8a069943f 100644 --- a/simd/src/test/java/run/endive/simd/BasicSimdTest.java +++ b/simd/src/test/java/run/endive/simd/BasicSimdTest.java @@ -23,4 +23,19 @@ public void shouldRunBasicExample() { var result = main.apply()[0]; assertEquals(6L, result); } + + @Test + public void shouldRoundTripV128Locals() { + var instance = + Instance.builder( + Parser.parse( + CorpusResources.getResource( + "compiled/simd-locals.wat.wasm"))) + .withMachineFactory(SimdInterpreterMachine::new) + .build(); + assertEquals(10L, instance.export("local_roundtrip").apply()[0]); + assertEquals(7L, instance.export("local_roundtrip_lane0").apply()[0]); + assertEquals(10L, instance.export("local_tee").apply()[0]); + assertEquals(7L, instance.export("local_tee_get").apply()[0]); + } } diff --git a/wasm-corpus/src/main/resources/compiled/simd-locals.wat.wasm b/wasm-corpus/src/main/resources/compiled/simd-locals.wat.wasm new file mode 100644 index 000000000..db52c6327 Binary files /dev/null and b/wasm-corpus/src/main/resources/compiled/simd-locals.wat.wasm differ diff --git a/wasm-corpus/src/main/resources/wat/simd-locals.wat b/wasm-corpus/src/main/resources/wat/simd-locals.wat new file mode 100644 index 000000000..e98574a66 --- /dev/null +++ b/wasm-corpus/src/main/resources/wat/simd-locals.wat @@ -0,0 +1,16 @@ +(module + (func (export "local_roundtrip") (result i32) (local v128) + (local.set 0 (v128.const i32x4 7 8 9 10)) + (i32x4.extract_lane 3 (local.get 0))) + + (func (export "local_roundtrip_lane0") (result i32) (local v128) + (local.set 0 (v128.const i32x4 7 8 9 10)) + (i32x4.extract_lane 0 (local.get 0))) + + (func (export "local_tee") (result i32) (local v128) + (i32x4.extract_lane 3 (local.tee 0 (v128.const i32x4 7 8 9 10)))) + + (func (export "local_tee_get") (result i32) (local v128) + (drop (local.tee 0 (v128.const i32x4 7 8 9 10))) + (i32x4.extract_lane 0 (local.get 0))) +)