From 4937369db322b65db0d7b46aac358ddbe9123d60 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 17 Nov 2024 12:22:52 +0100 Subject: [PATCH] Add numeric instructions for Wasm not available in `core` --- crates/core_arch/src/wasm32/mod.rs | 142 +++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/crates/core_arch/src/wasm32/mod.rs b/crates/core_arch/src/wasm32/mod.rs index 0ee1ff4a54..bb023623b5 100644 --- a/crates/core_arch/src/wasm32/mod.rs +++ b/crates/core_arch/src/wasm32/mod.rs @@ -32,6 +32,148 @@ pub fn unreachable() -> ! { crate::intrinsics::abort() } +/// Generates the [`f32.ceil`] instruction, returning the smallest integer greater than or equal to `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::ceil()`]. +/// +/// [`std::f32::ceil()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.ceil +/// [`f32.ceil`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f32.ceil))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f32_ceil(a: f32) -> f32 { + unsafe { crate::intrinsics::ceilf32(a) } +} + +/// Generates the [`f32.floor`] instruction, returning the largest integer less than or equal to `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::floor()`]. +/// +/// [`std::f32::floor()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.floor +/// [`f32.floor`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f32.floor))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f32_floor(a: f32) -> f32 { + unsafe { crate::intrinsics::floorf32(a) } +} + +/// Generates the [`f32.trunc`] instruction, roundinging to the nearest integer towards zero. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::trunc()`]. +/// +/// [`std::f32::trunc()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.trunc +/// [`f32.trunc`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f32.trunc))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f32_trunc(a: f32) -> f32 { + unsafe { crate::intrinsics::truncf32(a) } +} + +/// Generates the [`f32.nearest`] instruction, roundinging to the nearest integer. Rounds half-way +/// cases to the number with an even least significant digit. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::round_ties_even()`]. +/// +/// [`std::f32::round_ties_even()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.round_ties_even +/// [`f32.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f32.nearest))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f32_nearest(a: f32) -> f32 { + unsafe { crate::intrinsics::rintf32(a) } +} + +/// Generates the [`f32.sqrt`] instruction, returning the square root of the number `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::sqrt()`]. +/// +/// [`std::f32::sqrt()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.sqrt +/// [`f32.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f32.sqrt))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f32_sqrt(a: f32) -> f32 { + unsafe { crate::intrinsics::sqrtf32(a) } +} + +/// Generates the [`f64.ceil`] instruction, returning the smallest integer greater than or equal to `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::ceil()`]. +/// +/// [`std::f64::ceil()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.ceil +/// [`f64.ceil`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f64.ceil))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f64_ceil(a: f64) -> f64 { + unsafe { crate::intrinsics::ceilf64(a) } +} + +/// Generates the [`f64.floor`] instruction, returning the largest integer less than or equal to `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::floor()`]. +/// +/// [`std::f64::floor()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.floor +/// [`f64.floor`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f64.floor))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f64_floor(a: f64) -> f64 { + unsafe { crate::intrinsics::floorf64(a) } +} + +/// Generates the [`f64.trunc`] instruction, roundinging to the nearest integer towards zero. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::trunc()`]. +/// +/// [`std::f64::trunc()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.trunc +/// [`f64.trunc`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f64.trunc))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f64_trunc(a: f64) -> f64 { + unsafe { crate::intrinsics::truncf64(a) } +} + +/// Generates the [`f64.nearest`] instruction, roundinging to the nearest integer. Rounds half-way +/// cases to the number with an even least significant digit. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::round_ties_even()`]. +/// +/// [`std::f64::round_ties_even()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.round_ties_even +/// [`f64.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f64.nearest))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f64_nearest(a: f64) -> f64 { + unsafe { crate::intrinsics::rintf64(a) } +} + +/// Generates the [`f64.sqrt`] instruction, returning the square root of the number `a`. +/// +/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::sqrt()`]. +/// +/// [`std::f64::sqrt()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.sqrt +/// [`f64.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric +#[cfg_attr(test, assert_instr(f64.sqrt))] +#[inline] +#[must_use = "method returns a new number and does not mutate the original value"] +#[unstable(feature = "wasm_numeric_instr", issue = "133908")] +pub fn f64_sqrt(a: f64) -> f64 { + unsafe { crate::intrinsics::sqrtf64(a) } +} + extern "C-unwind" { #[link_name = "llvm.wasm.throw"] fn wasm_throw(tag: i32, ptr: *mut u8) -> !;