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")]
194pub unsafe fn throw<const TAG: i32>(ptr: *mut u8) -> ! {
195 static_assert!(TAG == 0); // LLVM only supports tag 0 == C++ right now.
196 wasm_throw(TAG, ptr)
197}