From d29ea7fedf86d85ca0ca8fbf3ba9931b92753410 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Tue, 29 Nov 2022 08:59:37 +0000 Subject: [PATCH] wasm_interp: last few instructions! --- crates/wasm_interp/src/instance.rs | 50 ++++++++++++++++++++++++---- crates/wasm_interp/tests/test_f32.rs | 23 +++++++++++++ crates/wasm_interp/tests/test_f64.rs | 25 +++++++++++++- 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/crates/wasm_interp/src/instance.rs b/crates/wasm_interp/src/instance.rs index 41df701081..a5579a9d4c 100644 --- a/crates/wasm_interp/src/instance.rs +++ b/crates/wasm_interp/src/instance.rs @@ -1107,9 +1107,28 @@ impl<'a> Instance<'a> { let arg1 = self.value_stack.pop_f32(); self.value_stack.push(Value::F32(arg1 / arg2)); } - F32MIN => todo!("{:?} @ {:#x}", op_code, file_offset), - F32MAX => todo!("{:?} @ {:#x}", op_code, file_offset), - F32COPYSIGN => todo!("{:?} @ {:#x}", op_code, file_offset), + F32MIN => { + let arg2 = self.value_stack.pop_f32(); + let arg1 = self.value_stack.pop_f32(); + let result = if arg1 < arg2 { arg1 } else { arg2 }; + self.value_stack.push(Value::F32(result)); + } + F32MAX => { + let arg2 = self.value_stack.pop_f32(); + let arg1 = self.value_stack.pop_f32(); + let result = if arg1 > arg2 { arg1 } else { arg2 }; + self.value_stack.push(Value::F32(result)); + } + F32COPYSIGN => { + let arg2 = self.value_stack.pop_f32(); + let arg1 = self.value_stack.pop_f32(); + let result = if arg1.is_sign_negative() == arg2.is_sign_negative() { + arg1 + } else { + arg2 + }; + self.value_stack.push(Value::F32(result)); + } F64ABS => { let arg = self.value_stack.pop_f64(); @@ -1175,9 +1194,28 @@ impl<'a> Instance<'a> { let arg1 = self.value_stack.pop_f64(); self.value_stack.push(Value::F64(arg1 / arg2)); } - F64MIN => todo!("{:?} @ {:#x}", op_code, file_offset), - F64MAX => todo!("{:?} @ {:#x}", op_code, file_offset), - F64COPYSIGN => todo!("{:?} @ {:#x}", op_code, file_offset), + F64MIN => { + let arg2 = self.value_stack.pop_f64(); + let arg1 = self.value_stack.pop_f64(); + let result = if arg1 < arg2 { arg1 } else { arg2 }; + self.value_stack.push(Value::F64(result)); + } + F64MAX => { + let arg2 = self.value_stack.pop_f64(); + let arg1 = self.value_stack.pop_f64(); + let result = if arg1 > arg2 { arg1 } else { arg2 }; + self.value_stack.push(Value::F64(result)); + } + F64COPYSIGN => { + let arg2 = self.value_stack.pop_f64(); + let arg1 = self.value_stack.pop_f64(); + let result = if arg1.is_sign_negative() == arg2.is_sign_negative() { + arg1 + } else { + arg2 + }; + self.value_stack.push(Value::F64(result)); + } I32WRAPI64 => { let arg = self.value_stack.pop_u64(); diff --git a/crates/wasm_interp/tests/test_f32.rs b/crates/wasm_interp/tests/test_f32.rs index a56251812f..22c1babe55 100644 --- a/crates/wasm_interp/tests/test_f32.rs +++ b/crates/wasm_interp/tests/test_f32.rs @@ -160,3 +160,26 @@ fn test_f32div() { test_f32_binop(op, -1.0, 0.0, f32::NEG_INFINITY); // test_f32_binop(op, 0.0, 0.0, f32::NAN); // can't check NaN for equality! LOL } + +#[test] +fn test_f32min() { + let op = F32MIN; + test_f32_binop(op, 1.1, 2.2, 1.1); + test_f32_binop(op, -1.1, -2.2, -2.2); +} + +#[test] +fn test_f32max() { + let op = F32MAX; + test_f32_binop(op, 1.1, 2.2, 2.2); + test_f32_binop(op, -1.1, -2.2, -1.1); +} + +#[test] +fn test_f32copysign() { + let op = F32COPYSIGN; + test_f32_binop(op, 1.1, 2.2, 1.1); + test_f32_binop(op, -1.1, -2.2, -1.1); + test_f32_binop(op, -1.1, 1.1, 1.1); + test_f32_binop(op, 1.1, -1.1, -1.1); +} diff --git a/crates/wasm_interp/tests/test_f64.rs b/crates/wasm_interp/tests/test_f64.rs index f36eeb6440..35c410f8df 100644 --- a/crates/wasm_interp/tests/test_f64.rs +++ b/crates/wasm_interp/tests/test_f64.rs @@ -158,5 +158,28 @@ fn test_f64div() { test_f64_binop(op, 1.0, 0.0, f64::INFINITY); test_f64_binop(op, -1.0, 0.0, f64::NEG_INFINITY); - // test_f64_binop(op, 0.0, 0.0, f64::NAN); // can't check NaN for equality! LOL + // to-probably-never-do: check NaN. It needs its own special test setup. +} + +#[test] +fn test_f64min() { + let op = F64MIN; + test_f64_binop(op, 1.1, 2.2, 1.1); + test_f64_binop(op, -1.1, -2.2, -2.2); +} + +#[test] +fn test_f64max() { + let op = F64MAX; + test_f64_binop(op, 1.1, 2.2, 2.2); + test_f64_binop(op, -1.1, -2.2, -1.1); +} + +#[test] +fn test_f64copysign() { + let op = F64COPYSIGN; + test_f64_binop(op, 1.1, 2.2, 1.1); + test_f64_binop(op, -1.1, -2.2, -1.1); + test_f64_binop(op, -1.1, 1.1, 1.1); + test_f64_binop(op, 1.1, -1.1, -1.1); }