#
core/stdarch/crates/core_arch/src/wasm32/
mod.rs

    1//! WASM32 intrinsics
    2
    3#[cfg(test)]
    4use stdarch_test::assert_instr;
    5
    6mod atomic;
    7#[unstable(feature = "stdarch_wasm_atomic_wait", issue = "77839")]
    8pub use self::atomic::*;
    9
    10mod simd128;
    11#[stable(feature = "wasm_simd", since = "1.54.0")]
    12pub use self::simd128::*;
    13
    14mod relaxed_simd;
    15#[stable(feature = "stdarch_wasm_relaxed_simd", since = "1.82.0")]
    16pub use self::relaxed_simd::*;
    17
    18mod memory;
    19#[stable(feature = "simd_wasm32", since = "1.33.0")]
    20pub use self::memory::*;
    21
    22/// Generates the [`unreachable`] instruction, which causes an unconditional [trap].
    23///
    24/// This function is safe to call and immediately aborts the execution.
    25///
    26/// [`unreachable`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-control
    27/// [trap]: https://webassembly.github.io/spec/core/intro/overview.html#trap
    28#[cfg_attr(test, assert_instr(unreachable))]
    29#[inline]
    30#[stable(feature = "unreachable_wasm32", since = "1.37.0")]
    31pub fn unreachable() -> ! {
    32    crate::intrinsics::abort()
    33}
    34
    35/// Generates the [`f32.ceil`] instruction, returning the smallest integer greater than or equal to `a`.
    36///
    37/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::ceil()`].
    38///
    39/// [`std::f32::ceil()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.ceil
    40/// [`f32.ceil`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    41#[cfg_attr(test, assert_instr(f32.ceil))]
    42#[inline]
    43#[must_use = "method returns a new number and does not mutate the original value"]
    44#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    45pub fn f32_ceil(a: f32) -> f32 {
    46    unsafe { crate::intrinsics::ceilf32(a) }
    47}
    48
    49/// Generates the [`f32.floor`] instruction, returning the largest integer less than or equal to `a`.
    50///
    51/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::floor()`].
    52///
    53/// [`std::f32::floor()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.floor
    54/// [`f32.floor`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    55#[cfg_attr(test, assert_instr(f32.floor))]
    56#[inline]
    57#[must_use = "method returns a new number and does not mutate the original value"]
    58#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    59pub fn f32_floor(a: f32) -> f32 {
    60    unsafe { crate::intrinsics::floorf32(a) }
    61}
    62
    63/// Generates the [`f32.trunc`] instruction, roundinging to the nearest integer towards zero.
    64///
    65/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::trunc()`].
    66///
    67/// [`std::f32::trunc()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.trunc
    68/// [`f32.trunc`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    69#[cfg_attr(test, assert_instr(f32.trunc))]
    70#[inline]
    71#[must_use = "method returns a new number and does not mutate the original value"]
    72#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    73pub fn f32_trunc(a: f32) -> f32 {
    74    unsafe { crate::intrinsics::truncf32(a) }
    75}
    76
    77/// Generates the [`f32.nearest`] instruction, roundinging to the nearest integer. Rounds half-way
    78/// cases to the number with an even least significant digit.
    79///
    80/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::round_ties_even()`].
    81///
    82/// [`std::f32::round_ties_even()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.round_ties_even
    83/// [`f32.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    84#[cfg_attr(test, assert_instr(f32.nearest))]
    85#[inline]
    86#[must_use = "method returns a new number and does not mutate the original value"]
    87#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    88pub fn f32_nearest(a: f32) -> f32 {
    89    crate::intrinsics::round_ties_even_f32(a)
    90}
    91
    92/// Generates the [`f32.sqrt`] instruction, returning the square root of the number `a`.
    93///
    94/// This method is useful when targeting `no_std` and is equivalent to [`std::f32::sqrt()`].
    95///
    96/// [`std::f32::sqrt()`]: https://doc.rust-lang.org/std/primitive.f32.html#method.sqrt
    97/// [`f32.sqrt`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    98#[cfg_attr(test, assert_instr(f32.sqrt))]
    99#[inline]
    100#[must_use = "method returns a new number and does not mutate the original value"]
    101#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    102pub fn f32_sqrt(a: f32) -> f32 {
    103    unsafe { crate::intrinsics::sqrtf32(a) }
    104}
    105
    106/// Generates the [`f64.ceil`] instruction, returning the smallest integer greater than or equal to `a`.
    107///
    108/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::ceil()`].
    109///
    110/// [`std::f64::ceil()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.ceil
    111/// [`f64.ceil`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    112#[cfg_attr(test, assert_instr(f64.ceil))]
    113#[inline]
    114#[must_use = "method returns a new number and does not mutate the original value"]
    115#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    116pub fn f64_ceil(a: f64) -> f64 {
    117    unsafe { crate::intrinsics::ceilf64(a) }
    118}
    119
    120/// Generates the [`f64.floor`] instruction, returning the largest integer less than or equal to `a`.
    121///
    122/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::floor()`].
    123///
    124/// [`std::f64::floor()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.floor
    125/// [`f64.floor`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    126#[cfg_attr(test, assert_instr(f64.floor))]
    127#[inline]
    128#[must_use = "method returns a new number and does not mutate the original value"]
    129#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    130pub fn f64_floor(a: f64) -> f64 {
    131    unsafe { crate::intrinsics::floorf64(a) }
    132}
    133
    134/// Generates the [`f64.trunc`] instruction, roundinging to the nearest integer towards zero.
    135///
    136/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::trunc()`].
    137///
    138/// [`std::f64::trunc()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.trunc
    139/// [`f64.trunc`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    140#[cfg_attr(test, assert_instr(f64.trunc))]
    141#[inline]
    142#[must_use = "method returns a new number and does not mutate the original value"]
    143#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    144pub fn f64_trunc(a: f64) -> f64 {
    145    unsafe { crate::intrinsics::truncf64(a) }
    146}
    147
    148/// Generates the [`f64.nearest`] instruction, roundinging to the nearest integer. Rounds half-way
    149/// cases to the number with an even least significant digit.
    150///
    151/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::round_ties_even()`].
    152///
    153/// [`std::f64::round_ties_even()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.round_ties_even
    154/// [`f64.nearest`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    155#[cfg_attr(test, assert_instr(f64.nearest))]
    156#[inline]
    157#[must_use = "method returns a new number and does not mutate the original value"]
    158#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    159pub fn f64_nearest(a: f64) -> f64 {
    160    crate::intrinsics::round_ties_even_f64(a)
    161}
    162
    163/// Generates the [`f64.sqrt`] instruction, returning the square root of the number `a`.
    164///
    165/// This method is useful when targeting `no_std` and is equivalent to [`std::f64::sqrt()`].
    166///
    167/// [`std::f64::sqrt()`]: https://doc.rust-lang.org/std/primitive.f64.html#method.sqrt
    168/// [`f64.sqrt`]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-instr-numeric
    169#[cfg_attr(test, assert_instr(f64.sqrt))]
    170#[inline]
    171#[must_use = "method returns a new number and does not mutate the original value"]
    172#[unstable(feature = "wasm_numeric_instr", issue = "133908")]
    173pub fn f64_sqrt(a: f64) -> f64 {
    174    unsafe { crate::intrinsics::sqrtf64(a) }
    175}
    176
    177unsafe extern "C-unwind" {
    178    #[link_name = "llvm.wasm.throw"]
    179    fn wasm_throw(tag: i32, ptr: *mut u8) -> !;
    180}
    181
    182/// Generates the [`throw`] instruction from the [exception-handling proposal] for WASM.
    183///
    184/// This function is unlikely to be stabilized until codegen backends have better support.
    185///
    186/// [`throw`]: https://webassembly.github.io/exception-handling/core/syntax/instructions.html#syntax-instr-control
    187/// [exception-handling proposal]: https://github.com/WebAssembly/exception-handling
    188// FIXME: wasmtime does not currently support exception-handling, so cannot execute
    189//        a wasm module with the throw instruction in it. once it does, we can
    190//        reenable this attribute.
    191// #[cfg_attr(test, assert_instr(throw, TAG = 0, ptr = core::ptr::null_mut()))]
    192#[inline]
    193#[unstable(feature = "wasm_exception_handling_intrinsics", issue = "122465")]
    194// FIXME: Since this instruction unwinds, `core` built with `-C panic=unwind`
    195//        cannot be linked with `-C panic=abort` programs. But that's not
    196//        entirely supported anyway, because runtimes without EH support won't
    197//        be able to handle `try` blocks in `-C panic=unwind` crates either.
    198//        We ship `-C panic=abort` `core`, so this doesn't affect users
    199//        directly. Resolving this will likely require patching out both `try`
    200//        and `throw` instructions, at which point we can look into whitelisting
    201//        this function in the compiler to allow linking.
    202//        See https://github.com/rust-lang/rust/issues/118168.
    203#[allow(ffi_unwind_calls)]
    204pub unsafe fn throw<const TAG: i32>(ptr: *mut u8) -> ! {
    205    static_assert!(TAG == 0); // LLVM only supports tag 0 == C++ right now.
    206    wasm_throw(TAG, ptr)
    207}