Skip to content

Commit

Permalink
feat: pass all float tests
Browse files Browse the repository at this point in the history
Signed-off-by: Henry <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Dec 25, 2023
1 parent 9ea2796 commit 03ff413
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 41 deletions.
43 changes: 32 additions & 11 deletions crates/tinywasm/src/runtime/executor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::ops::{BitAnd, BitOr, BitXor};
use core::ops::{BitAnd, BitOr, BitXor, Neg};

use super::{DefaultRuntime, Stack};
use crate::{
Expand Down Expand Up @@ -332,16 +332,16 @@ fn exec_one(
I64Or => arithmetic_method!(bitor, i64, stack),
I32Xor => arithmetic_method!(bitxor, i32, stack),
I64Xor => arithmetic_method!(bitxor, i64, stack),
I32Shl => arithmetic_method!(wrapping_shl_self, i32, stack),
I64Shl => arithmetic_method!(wrapping_shl_self, i64, stack),
I32ShrS => arithmetic_method!(wrapping_shr_self, i32, stack),
I64ShrS => arithmetic_method!(wrapping_shr_self, i64, stack),
I32ShrU => arithmetic_method_cast!(wrapping_shr_self, i32, u32, stack),
I64ShrU => arithmetic_method_cast!(wrapping_shr_self, i64, u64, stack),
I32Rotl => arithmetic_method!(wrapping_rotl_self, i32, stack),
I64Rotl => arithmetic_method!(wrapping_rotl_self, i64, stack),
I32Rotr => arithmetic_method!(wrapping_rotr_self, i32, stack),
I64Rotr => arithmetic_method!(wrapping_rotr_self, i64, stack),
I32Shl => arithmetic_method!(wasm_shl, i32, stack),
I64Shl => arithmetic_method!(wasm_shl, i64, stack),
I32ShrS => arithmetic_method!(wasm_shr, i32, stack),
I64ShrS => arithmetic_method!(wasm_shr, i64, stack),
I32ShrU => arithmetic_method_cast!(wasm_shr, i32, u32, stack),
I64ShrU => arithmetic_method_cast!(wasm_shr, i64, u64, stack),
I32Rotl => arithmetic_method!(wasm_rotl, i32, stack),
I64Rotl => arithmetic_method!(wasm_rotl, i64, stack),
I32Rotr => arithmetic_method!(wasm_rotr, i32, stack),
I64Rotr => arithmetic_method!(wasm_rotr, i64, stack),

I32Clz => arithmetic_method_self!(leading_zeros, i32, stack),
I64Clz => arithmetic_method_self!(leading_zeros, i64, stack),
Expand All @@ -367,6 +367,27 @@ fn exec_one(
I64ExtendI32S => conv_1!(i32, i64, stack),
I32WrapI64 => conv_1!(i64, i32, stack),

F32Abs => arithmetic_method_self!(abs, f32, stack),
F64Abs => arithmetic_method_self!(abs, f64, stack),
F32Neg => arithmetic_method_self!(neg, f32, stack),
F64Neg => arithmetic_method_self!(neg, f64, stack),
F32Ceil => arithmetic_method_self!(ceil, f32, stack),
F64Ceil => arithmetic_method_self!(ceil, f64, stack),
F32Floor => arithmetic_method_self!(floor, f32, stack),
F64Floor => arithmetic_method_self!(floor, f64, stack),
F32Trunc => arithmetic_method_self!(trunc, f32, stack),
F64Trunc => arithmetic_method_self!(trunc, f64, stack),
F32Nearest => arithmetic_method_self!(wasm_nearest, f32, stack),
F64Nearest => arithmetic_method_self!(wasm_nearest, f64, stack),
F32Sqrt => arithmetic_method_self!(sqrt, f32, stack),
F64Sqrt => arithmetic_method_self!(sqrt, f64, stack),
F32Min => arithmetic_method!(wasm_min, f32, stack),
F64Min => arithmetic_method!(wasm_min, f64, stack),
F32Max => arithmetic_method!(wasm_max, f32, stack),
F64Max => arithmetic_method!(wasm_max, f64, stack),
F32Copysign => arithmetic_method!(copysign, f32, stack),
F64Copysign => arithmetic_method!(copysign, f64, stack),

// no-op instructions since types are erased at runtime
I32ReinterpretF32 => {}
I64ReinterpretF64 => {}
Expand Down
78 changes: 68 additions & 10 deletions crates/tinywasm/src/runtime/executor/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,91 @@ where
fn checked_wrapping_rem(self, rhs: Self) -> Option<Self>;
}

pub(crate) trait WrappingSelfOps {
fn wrapping_shl_self(self, rhs: Self) -> Self;
fn wrapping_shr_self(self, rhs: Self) -> Self;
fn wrapping_rotl_self(self, rhs: Self) -> Self;
fn wrapping_rotr_self(self, rhs: Self) -> Self;
pub(crate) trait WasmFloatOps {
fn wasm_min(self, other: Self) -> Self;
fn wasm_max(self, other: Self) -> Self;
fn wasm_nearest(self) -> Self;
}

macro_rules! impl_wasm_float_ops {
($($t:ty)*) => ($(
impl WasmFloatOps for $t {
// https://webassembly.github.io/spec/core/exec/numerics.html#op-fnearest
fn wasm_nearest(self) -> Self {
log::info!("wasm_nearest: {}", self);
match self {
x if x.is_nan() => x,
x if x.is_infinite() || x == 0.0 => x,
x if x > 0.0 && x <= 0.5 => 0.0,
x if x < 0.0 && x >= -0.5 => -0.0,
x => x.round(),
}
}

// https://webassembly.github.io/spec/core/exec/numerics.html#op-fmin
// Based on f32::minimum (which is not yet stable)
#[inline]
fn wasm_min(self, other: Self) -> Self {
if self < other {
self
} else if other < self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}

// https://webassembly.github.io/spec/core/exec/numerics.html#op-fmax
// Based on f32::maximum (which is not yet stable)
#[inline]
fn wasm_max(self, other: Self) -> Self {
if self > other {
self
} else if other > self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { other } else { self }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}
}
)*)
}

impl_wasm_float_ops! { f32 f64 }

pub(crate) trait WasmIntOps {
fn wasm_shl(self, rhs: Self) -> Self;
fn wasm_shr(self, rhs: Self) -> Self;
fn wasm_rotl(self, rhs: Self) -> Self;
fn wasm_rotr(self, rhs: Self) -> Self;
}

macro_rules! impl_wrapping_self_sh {
($($t:ty)*) => ($(
impl WrappingSelfOps for $t {
impl WasmIntOps for $t {
#[inline]
fn wrapping_shl_self(self, rhs: Self) -> Self {
fn wasm_shl(self, rhs: Self) -> Self {
self.wrapping_shl(rhs as u32)
}

#[inline]
fn wrapping_shr_self(self, rhs: Self) -> Self {
fn wasm_shr(self, rhs: Self) -> Self {
self.wrapping_shr(rhs as u32)
}

#[inline]
fn wrapping_rotl_self(self, rhs: Self) -> Self {
fn wasm_rotl(self, rhs: Self) -> Self {
self.rotate_left(rhs as u32)
}

#[inline]
fn wrapping_rotr_self(self, rhs: Self) -> Self {
fn wasm_rotr(self, rhs: Self) -> Self {
self.rotate_right(rhs as u32)
}
}
Expand Down
Loading

0 comments on commit 03ff413

Please sign in to comment.