core/intrinsics/simd.rs
1//! SIMD compiler intrinsics.
2//!
3//! In this module, a "vector" is any `repr(simd)` type.
4
5/// Inserts an element into a vector, returning the updated vector.
6///
7/// `T` must be a vector with element type `U`, and `idx` must be `const`.
8///
9/// # Safety
10///
11/// `idx` must be in-bounds of the vector.
12#[rustc_intrinsic]
13#[rustc_nounwind]
14pub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
15
16/// Extracts an element from a vector.
17///
18/// `T` must be a vector with element type `U`, and `idx` must be `const`.
19///
20/// # Safety
21///
22/// `idx` must be const and in-bounds of the vector.
23#[rustc_intrinsic]
24#[rustc_nounwind]
25pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
26
27/// Inserts an element into a vector, returning the updated vector.
28///
29/// `T` must be a vector with element type `U`.
30///
31/// If the index is `const`, [`simd_insert`] may emit better assembly.
32///
33/// # Safety
34///
35/// `idx` must be in-bounds of the vector.
36#[rustc_nounwind]
37#[cfg_attr(not(bootstrap), rustc_intrinsic)]
38pub unsafe fn simd_insert_dyn<T, U>(mut x: T, idx: u32, val: U) -> T {
39 // SAFETY: `idx` must be in-bounds
40 unsafe { (&raw mut x).cast::<U>().add(idx as usize).write(val) }
41 x
42}
43
44/// Extracts an element from a vector.
45///
46/// `T` must be a vector with element type `U`.
47///
48/// If the index is `const`, [`simd_extract`] may emit better assembly.
49///
50/// # Safety
51///
52/// `idx` must be in-bounds of the vector.
53#[rustc_nounwind]
54#[cfg_attr(not(bootstrap), rustc_intrinsic)]
55pub unsafe fn simd_extract_dyn<T, U>(x: T, idx: u32) -> U {
56 // SAFETY: `idx` must be in-bounds
57 unsafe { (&raw const x).cast::<U>().add(idx as usize).read() }
58}
59
60/// Adds two simd vectors elementwise.
61///
62/// `T` must be a vector of integers or floats.
63#[rustc_intrinsic]
64#[rustc_nounwind]
65pub unsafe fn simd_add<T>(x: T, y: T) -> T;
66
67/// Subtracts `rhs` from `lhs` elementwise.
68///
69/// `T` must be a vector of integers or floats.
70#[rustc_intrinsic]
71#[rustc_nounwind]
72pub unsafe fn simd_sub<T>(lhs: T, rhs: T) -> T;
73
74/// Multiplies two simd vectors elementwise.
75///
76/// `T` must be a vector of integers or floats.
77#[rustc_intrinsic]
78#[rustc_nounwind]
79pub unsafe fn simd_mul<T>(x: T, y: T) -> T;
80
81/// Divides `lhs` by `rhs` elementwise.
82///
83/// `T` must be a vector of integers or floats.
84///
85/// # Safety
86/// For integers, `rhs` must not contain any zero elements.
87/// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
88#[rustc_intrinsic]
89#[rustc_nounwind]
90pub unsafe fn simd_div<T>(lhs: T, rhs: T) -> T;
91
92/// Returns remainder of two vectors elementwise.
93///
94/// `T` must be a vector of integers or floats.
95///
96/// # Safety
97/// For integers, `rhs` must not contain any zero elements.
98/// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
99#[rustc_intrinsic]
100#[rustc_nounwind]
101pub unsafe fn simd_rem<T>(lhs: T, rhs: T) -> T;
102
103/// Shifts vector left elementwise, with UB on overflow.
104///
105/// Shifts `lhs` left by `rhs`, shifting in sign bits for signed types.
106///
107/// `T` must be a vector of integers.
108///
109/// # Safety
110///
111/// Each element of `rhs` must be less than `<int>::BITS`.
112#[rustc_intrinsic]
113#[rustc_nounwind]
114pub unsafe fn simd_shl<T>(lhs: T, rhs: T) -> T;
115
116/// Shifts vector right elementwise, with UB on overflow.
117///
118/// `T` must be a vector of integers.
119///
120/// Shifts `lhs` right by `rhs`, shifting in sign bits for signed types.
121///
122/// # Safety
123///
124/// Each element of `rhs` must be less than `<int>::BITS`.
125#[rustc_intrinsic]
126#[rustc_nounwind]
127pub unsafe fn simd_shr<T>(lhs: T, rhs: T) -> T;
128
129/// "Ands" vectors elementwise.
130///
131/// `T` must be a vector of integers.
132#[rustc_intrinsic]
133#[rustc_nounwind]
134pub unsafe fn simd_and<T>(x: T, y: T) -> T;
135
136/// "Ors" vectors elementwise.
137///
138/// `T` must be a vector of integers.
139#[rustc_intrinsic]
140#[rustc_nounwind]
141pub unsafe fn simd_or<T>(x: T, y: T) -> T;
142
143/// "Exclusive ors" vectors elementwise.
144///
145/// `T` must be a vector of integers.
146#[rustc_intrinsic]
147#[rustc_nounwind]
148pub unsafe fn simd_xor<T>(x: T, y: T) -> T;
149
150/// Numerically casts a vector, elementwise.
151///
152/// `T` and `U` must be vectors of integers or floats, and must have the same length.
153///
154/// When casting floats to integers, the result is truncated. Out-of-bounds result lead to UB.
155/// When casting integers to floats, the result is rounded.
156/// Otherwise, truncates or extends the value, maintaining the sign for signed integers.
157///
158/// # Safety
159/// Casting from integer types is always safe.
160/// Casting between two float types is also always safe.
161///
162/// Casting floats to integers truncates, following the same rules as `to_int_unchecked`.
163/// Specifically, each element must:
164/// * Not be `NaN`
165/// * Not be infinite
166/// * Be representable in the return type, after truncating off its fractional part
167#[rustc_intrinsic]
168#[rustc_nounwind]
169pub unsafe fn simd_cast<T, U>(x: T) -> U;
170
171/// Numerically casts a vector, elementwise.
172///
173/// `T` and `U` be a vectors of integers or floats, and must have the same length.
174///
175/// Like `simd_cast`, but saturates float-to-integer conversions (NaN becomes 0).
176/// This matches regular `as` and is always safe.
177///
178/// When casting floats to integers, the result is truncated.
179/// When casting integers to floats, the result is rounded.
180/// Otherwise, truncates or extends the value, maintaining the sign for signed integers.
181#[rustc_intrinsic]
182#[rustc_nounwind]
183pub unsafe fn simd_as<T, U>(x: T) -> U;
184
185/// Negates a vector elementwise.
186///
187/// `T` must be a vector of integers or floats.
188///
189/// Rust panics for `-<int>::Min` due to overflow, but it is not UB with this intrinsic.
190#[rustc_intrinsic]
191#[rustc_nounwind]
192pub unsafe fn simd_neg<T>(x: T) -> T;
193
194/// Returns absolute value of a vector, elementwise.
195///
196/// `T` must be a vector of floating-point primitive types.
197#[rustc_intrinsic]
198#[rustc_nounwind]
199pub unsafe fn simd_fabs<T>(x: T) -> T;
200
201/// Returns the minimum of two vectors, elementwise.
202///
203/// `T` must be a vector of floating-point primitive types.
204///
205/// Follows IEEE-754 `minNum` semantics.
206#[rustc_intrinsic]
207#[rustc_nounwind]
208pub unsafe fn simd_fmin<T>(x: T, y: T) -> T;
209
210/// Returns the maximum of two vectors, elementwise.
211///
212/// `T` must be a vector of floating-point primitive types.
213///
214/// Follows IEEE-754 `maxNum` semantics.
215#[rustc_intrinsic]
216#[rustc_nounwind]
217pub unsafe fn simd_fmax<T>(x: T, y: T) -> T;
218
219/// Tests elementwise equality of two vectors.
220///
221/// `T` must be a vector of integers or floats.
222///
223/// `U` must be a vector of integers with the same number of elements and element size as `T`.
224///
225/// Returns `0` for false and `!0` for true.
226#[rustc_intrinsic]
227#[rustc_nounwind]
228pub unsafe fn simd_eq<T, U>(x: T, y: T) -> U;
229
230/// Tests elementwise inequality equality of two vectors.
231///
232/// `T` must be a vector of integers or floats.
233///
234/// `U` must be a vector of integers with the same number of elements and element size as `T`.
235///
236/// Returns `0` for false and `!0` for true.
237#[rustc_intrinsic]
238#[rustc_nounwind]
239pub unsafe fn simd_ne<T, U>(x: T, y: T) -> U;
240
241/// Tests if `x` is less than `y`, elementwise.
242///
243/// `T` must be a vector of integers or floats.
244///
245/// `U` must be a vector of integers with the same number of elements and element size as `T`.
246///
247/// Returns `0` for false and `!0` for true.
248#[rustc_intrinsic]
249#[rustc_nounwind]
250pub unsafe fn simd_lt<T, U>(x: T, y: T) -> U;
251
252/// Tests if `x` is less than or equal to `y`, elementwise.
253///
254/// `T` must be a vector of integers or floats.
255///
256/// `U` must be a vector of integers with the same number of elements and element size as `T`.
257///
258/// Returns `0` for false and `!0` for true.
259#[rustc_intrinsic]
260#[rustc_nounwind]
261pub unsafe fn simd_le<T, U>(x: T, y: T) -> U;
262
263/// Tests if `x` is greater than `y`, elementwise.
264///
265/// `T` must be a vector of integers or floats.
266///
267/// `U` must be a vector of integers with the same number of elements and element size as `T`.
268///
269/// Returns `0` for false and `!0` for true.
270#[rustc_intrinsic]
271#[rustc_nounwind]
272pub unsafe fn simd_gt<T, U>(x: T, y: T) -> U;
273
274/// Tests if `x` is greater than or equal to `y`, elementwise.
275///
276/// `T` must be a vector of integers or floats.
277///
278/// `U` must be a vector of integers with the same number of elements and element size as `T`.
279///
280/// Returns `0` for false and `!0` for true.
281#[rustc_intrinsic]
282#[rustc_nounwind]
283pub unsafe fn simd_ge<T, U>(x: T, y: T) -> U;
284
285/// Shuffles two vectors by const indices.
286///
287/// `T` must be a vector.
288///
289/// `U` must be a **const** vector of `u32`s. This means it must either refer to a named
290/// const or be given as an inline const expression (`const { ... }`).
291///
292/// `V` must be a vector with the same element type as `T` and the same length as `U`.
293///
294/// Returns a new vector such that element `i` is selected from `xy[idx[i]]`, where `xy`
295/// is the concatenation of `x` and `y`. It is a compile-time error if `idx[i]` is out-of-bounds
296/// of `xy`.
297#[rustc_intrinsic]
298#[rustc_nounwind]
299pub unsafe fn simd_shuffle<T, U, V>(x: T, y: T, idx: U) -> V;
300
301/// Reads a vector of pointers.
302///
303/// `T` must be a vector.
304///
305/// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`.
306///
307/// `V` must be a vector of integers with the same length as `T` (but any element size).
308///
309/// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, read the pointer.
310/// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from
311/// `val`.
312///
313/// # Safety
314/// Unmasked values in `T` must be readable as if by `<ptr>::read` (e.g. aligned to the element
315/// type).
316///
317/// `mask` must only contain `0` or `!0` values.
318#[rustc_intrinsic]
319#[rustc_nounwind]
320pub unsafe fn simd_gather<T, U, V>(val: T, ptr: U, mask: V) -> T;
321
322/// Writes to a vector of pointers.
323///
324/// `T` must be a vector.
325///
326/// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`.
327///
328/// `V` must be a vector of integers with the same length as `T` (but any element size).
329///
330/// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, write the
331/// corresponding value in `val` to the pointer.
332/// Otherwise if the corresponding value in `mask` is `0`, do nothing.
333///
334/// The stores happen in left-to-right order.
335/// (This is relevant in case two of the stores overlap.)
336///
337/// # Safety
338/// Unmasked values in `T` must be writeable as if by `<ptr>::write` (e.g. aligned to the element
339/// type).
340///
341/// `mask` must only contain `0` or `!0` values.
342#[rustc_intrinsic]
343#[rustc_nounwind]
344pub unsafe fn simd_scatter<T, U, V>(val: T, ptr: U, mask: V);
345
346/// Reads a vector of pointers.
347///
348/// `T` must be a vector.
349///
350/// `U` must be a pointer to the element type of `T`
351///
352/// `V` must be a vector of integers with the same length as `T` (but any element size).
353///
354/// For each element, if the corresponding value in `mask` is `!0`, read the corresponding
355/// pointer offset from `ptr`.
356/// The first element is loaded from `ptr`, the second from `ptr.wrapping_offset(1)` and so on.
357/// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from
358/// `val`.
359///
360/// # Safety
361/// Unmasked values in `T` must be readable as if by `<ptr>::read` (e.g. aligned to the element
362/// type).
363///
364/// `mask` must only contain `0` or `!0` values.
365#[rustc_intrinsic]
366#[rustc_nounwind]
367pub unsafe fn simd_masked_load<V, U, T>(mask: V, ptr: U, val: T) -> T;
368
369/// Writes to a vector of pointers.
370///
371/// `T` must be a vector.
372///
373/// `U` must be a pointer to the element type of `T`
374///
375/// `V` must be a vector of integers with the same length as `T` (but any element size).
376///
377/// For each element, if the corresponding value in `mask` is `!0`, write the corresponding
378/// value in `val` to the pointer offset from `ptr`.
379/// The first element is written to `ptr`, the second to `ptr.wrapping_offset(1)` and so on.
380/// Otherwise if the corresponding value in `mask` is `0`, do nothing.
381///
382/// # Safety
383/// Unmasked values in `T` must be writeable as if by `<ptr>::write` (e.g. aligned to the element
384/// type).
385///
386/// `mask` must only contain `0` or `!0` values.
387#[rustc_intrinsic]
388#[rustc_nounwind]
389pub unsafe fn simd_masked_store<V, U, T>(mask: V, ptr: U, val: T);
390
391/// Adds two simd vectors elementwise, with saturation.
392///
393/// `T` must be a vector of integer primitive types.
394#[rustc_intrinsic]
395#[rustc_nounwind]
396pub unsafe fn simd_saturating_add<T>(x: T, y: T) -> T;
397
398/// Subtracts two simd vectors elementwise, with saturation.
399///
400/// `T` must be a vector of integer primitive types.
401///
402/// Subtract `rhs` from `lhs`.
403#[rustc_intrinsic]
404#[rustc_nounwind]
405pub unsafe fn simd_saturating_sub<T>(lhs: T, rhs: T) -> T;
406
407/// Adds elements within a vector from left to right.
408///
409/// `T` must be a vector of integers or floats.
410///
411/// `U` must be the element type of `T`.
412///
413/// Starting with the value `y`, add the elements of `x` and accumulate.
414#[rustc_intrinsic]
415#[rustc_nounwind]
416pub unsafe fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
417
418/// Adds elements within a vector in arbitrary order. May also be re-associated with
419/// unordered additions on the inputs/outputs.
420///
421/// `T` must be a vector of integers or floats.
422///
423/// `U` must be the element type of `T`.
424#[rustc_intrinsic]
425#[rustc_nounwind]
426pub unsafe fn simd_reduce_add_unordered<T, U>(x: T) -> U;
427
428/// Multiplies elements within a vector from left to right.
429///
430/// `T` must be a vector of integers or floats.
431///
432/// `U` must be the element type of `T`.
433///
434/// Starting with the value `y`, multiply the elements of `x` and accumulate.
435#[rustc_intrinsic]
436#[rustc_nounwind]
437pub unsafe fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
438
439/// Multiplies elements within a vector in arbitrary order. May also be re-associated with
440/// unordered additions on the inputs/outputs.
441///
442/// `T` must be a vector of integers or floats.
443///
444/// `U` must be the element type of `T`.
445#[rustc_intrinsic]
446#[rustc_nounwind]
447pub unsafe fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
448
449/// Checks if all mask values are true.
450///
451/// `T` must be a vector of integer primitive types.
452///
453/// # Safety
454/// `x` must contain only `0` or `!0`.
455#[rustc_intrinsic]
456#[rustc_nounwind]
457pub unsafe fn simd_reduce_all<T>(x: T) -> bool;
458
459/// Checks if any mask value is true.
460///
461/// `T` must be a vector of integer primitive types.
462///
463/// # Safety
464/// `x` must contain only `0` or `!0`.
465#[rustc_intrinsic]
466#[rustc_nounwind]
467pub unsafe fn simd_reduce_any<T>(x: T) -> bool;
468
469/// Returns the maximum element of a vector.
470///
471/// `T` must be a vector of integers or floats.
472///
473/// `U` must be the element type of `T`.
474///
475/// For floating-point values, uses IEEE-754 `maxNum`.
476#[rustc_intrinsic]
477#[rustc_nounwind]
478pub unsafe fn simd_reduce_max<T, U>(x: T) -> U;
479
480/// Returns the minimum element of a vector.
481///
482/// `T` must be a vector of integers or floats.
483///
484/// `U` must be the element type of `T`.
485///
486/// For floating-point values, uses IEEE-754 `minNum`.
487#[rustc_intrinsic]
488#[rustc_nounwind]
489pub unsafe fn simd_reduce_min<T, U>(x: T) -> U;
490
491/// Logical "ands" all elements together.
492///
493/// `T` must be a vector of integers or floats.
494///
495/// `U` must be the element type of `T`.
496#[rustc_intrinsic]
497#[rustc_nounwind]
498pub unsafe fn simd_reduce_and<T, U>(x: T) -> U;
499
500/// Logical "ors" all elements together.
501///
502/// `T` must be a vector of integers or floats.
503///
504/// `U` must be the element type of `T`.
505#[rustc_intrinsic]
506#[rustc_nounwind]
507pub unsafe fn simd_reduce_or<T, U>(x: T) -> U;
508
509/// Logical "exclusive ors" all elements together.
510///
511/// `T` must be a vector of integers or floats.
512///
513/// `U` must be the element type of `T`.
514#[rustc_intrinsic]
515#[rustc_nounwind]
516pub unsafe fn simd_reduce_xor<T, U>(x: T) -> U;
517
518/// Truncates an integer vector to a bitmask.
519///
520/// `T` must be an integer vector.
521///
522/// `U` must be either the smallest unsigned integer with at least as many bits as the length
523/// of `T`, or the smallest array of `u8` with at least as many bits as the length of `T`.
524///
525/// Each element is truncated to a single bit and packed into the result.
526///
527/// No matter whether the output is an array or an unsigned integer, it is treated as a single
528/// contiguous list of bits. The bitmask is always packed on the least-significant side of the
529/// output, and padded with 0s in the most-significant bits. The order of the bits depends on
530/// endianness:
531///
532/// * On little endian, the least significant bit corresponds to the first vector element.
533/// * On big endian, the least significant bit corresponds to the last vector element.
534///
535/// For example, `[!0, 0, !0, !0]` packs to
536/// - `0b1101u8` or `[0b1101]` on little endian, and
537/// - `0b1011u8` or `[0b1011]` on big endian.
538///
539/// To consider a larger example,
540/// `[!0, 0, 0, 0, 0, 0, 0, 0, !0, !0, 0, 0, 0, 0, !0, 0]` packs to
541/// - `0b0100001100000001u16` or `[0b00000001, 0b01000011]` on little endian, and
542/// - `0b1000000011000010u16` or `[0b10000000, 0b11000010]` on big endian.
543///
544/// And finally, a non-power-of-2 example with multiple bytes:
545/// `[!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]` packs to
546/// - `0b0101001011u16` or `[0b01001011, 0b01]` on little endian, and
547/// - `0b1101001010u16` or `[0b11, 0b01001010]` on big endian.
548///
549/// # Safety
550/// `x` must contain only `0` and `!0`.
551#[rustc_intrinsic]
552#[rustc_nounwind]
553pub unsafe fn simd_bitmask<T, U>(x: T) -> U;
554
555/// Selects elements from a mask.
556///
557/// `T` must be a vector.
558///
559/// `M` must be an integer vector with the same length as `T` (but any element size).
560///
561/// For each element, if the corresponding value in `mask` is `!0`, select the element from
562/// `if_true`. If the corresponding value in `mask` is `0`, select the element from
563/// `if_false`.
564///
565/// # Safety
566/// `mask` must only contain `0` and `!0`.
567#[rustc_intrinsic]
568#[rustc_nounwind]
569pub unsafe fn simd_select<M, T>(mask: M, if_true: T, if_false: T) -> T;
570
571/// Selects elements from a bitmask.
572///
573/// `M` must be an unsigned integer or array of `u8`, matching `simd_bitmask`.
574///
575/// `T` must be a vector.
576///
577/// For each element, if the bit in `mask` is `1`, select the element from
578/// `if_true`. If the corresponding bit in `mask` is `0`, select the element from
579/// `if_false`.
580/// The remaining bits of the mask are ignored.
581///
582/// The bitmask bit order matches `simd_bitmask`.
583#[rustc_intrinsic]
584#[rustc_nounwind]
585pub unsafe fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
586
587/// Calculates the offset from a pointer vector elementwise, potentially
588/// wrapping.
589///
590/// `T` must be a vector of pointers.
591///
592/// `U` must be a vector of `isize` or `usize` with the same number of elements as `T`.
593///
594/// Operates as if by `<ptr>::wrapping_offset`.
595#[rustc_intrinsic]
596#[rustc_nounwind]
597pub unsafe fn simd_arith_offset<T, U>(ptr: T, offset: U) -> T;
598
599/// Casts a vector of pointers.
600///
601/// `T` and `U` must be vectors of pointers with the same number of elements.
602#[rustc_intrinsic]
603#[rustc_nounwind]
604pub unsafe fn simd_cast_ptr<T, U>(ptr: T) -> U;
605
606/// Exposes a vector of pointers as a vector of addresses.
607///
608/// `T` must be a vector of pointers.
609///
610/// `U` must be a vector of `usize` with the same length as `T`.
611#[rustc_intrinsic]
612#[rustc_nounwind]
613pub unsafe fn simd_expose_provenance<T, U>(ptr: T) -> U;
614
615/// Creates a vector of pointers from a vector of addresses.
616///
617/// `T` must be a vector of `usize`.
618///
619/// `U` must be a vector of pointers, with the same length as `T`.
620#[rustc_intrinsic]
621#[rustc_nounwind]
622pub unsafe fn simd_with_exposed_provenance<T, U>(addr: T) -> U;
623
624/// Swaps bytes of each element.
625///
626/// `T` must be a vector of integers.
627#[rustc_intrinsic]
628#[rustc_nounwind]
629pub unsafe fn simd_bswap<T>(x: T) -> T;
630
631/// Reverses bits of each element.
632///
633/// `T` must be a vector of integers.
634#[rustc_intrinsic]
635#[rustc_nounwind]
636pub unsafe fn simd_bitreverse<T>(x: T) -> T;
637
638/// Counts the leading zeros of each element.
639///
640/// `T` must be a vector of integers.
641#[rustc_intrinsic]
642#[rustc_nounwind]
643pub unsafe fn simd_ctlz<T>(x: T) -> T;
644
645/// Counts the number of ones in each element.
646///
647/// `T` must be a vector of integers.
648#[rustc_intrinsic]
649#[rustc_nounwind]
650pub unsafe fn simd_ctpop<T>(x: T) -> T;
651
652/// Counts the trailing zeros of each element.
653///
654/// `T` must be a vector of integers.
655#[rustc_intrinsic]
656#[rustc_nounwind]
657pub unsafe fn simd_cttz<T>(x: T) -> T;
658
659/// Rounds up each element to the next highest integer-valued float.
660///
661/// `T` must be a vector of floats.
662#[rustc_intrinsic]
663#[rustc_nounwind]
664pub unsafe fn simd_ceil<T>(x: T) -> T;
665
666/// Rounds down each element to the next lowest integer-valued float.
667///
668/// `T` must be a vector of floats.
669#[rustc_intrinsic]
670#[rustc_nounwind]
671pub unsafe fn simd_floor<T>(x: T) -> T;
672
673/// Rounds each element to the closest integer-valued float.
674/// Ties are resolved by rounding away from 0.
675///
676/// `T` must be a vector of floats.
677#[rustc_intrinsic]
678#[rustc_nounwind]
679pub unsafe fn simd_round<T>(x: T) -> T;
680
681/// Returns the integer part of each element as an integer-valued float.
682/// In other words, non-integer values are truncated towards zero.
683///
684/// `T` must be a vector of floats.
685#[rustc_intrinsic]
686#[rustc_nounwind]
687pub unsafe fn simd_trunc<T>(x: T) -> T;
688
689/// Takes the square root of each element.
690///
691/// `T` must be a vector of floats.
692#[rustc_intrinsic]
693#[rustc_nounwind]
694pub unsafe fn simd_fsqrt<T>(x: T) -> T;
695
696/// Computes `(x*y) + z` for each element, but without any intermediate rounding.
697///
698/// `T` must be a vector of floats.
699#[rustc_intrinsic]
700#[rustc_nounwind]
701pub unsafe fn simd_fma<T>(x: T, y: T, z: T) -> T;
702
703/// Computes `(x*y) + z` for each element, non-deterministically executing either
704/// a fused multiply-add or two operations with rounding of the intermediate result.
705///
706/// The operation is fused if the code generator determines that target instruction
707/// set has support for a fused operation, and that the fused operation is more efficient
708/// than the equivalent, separate pair of mul and add instructions. It is unspecified
709/// whether or not a fused operation is selected, and that may depend on optimization
710/// level and context, for example. It may even be the case that some SIMD lanes get fused
711/// and others do not.
712///
713/// `T` must be a vector of floats.
714#[rustc_intrinsic]
715#[rustc_nounwind]
716pub unsafe fn simd_relaxed_fma<T>(x: T, y: T, z: T) -> T;
717
718// Computes the sine of each element.
719///
720/// `T` must be a vector of floats.
721#[rustc_intrinsic]
722#[rustc_nounwind]
723pub unsafe fn simd_fsin<T>(a: T) -> T;
724
725// Computes the cosine of each element.
726///
727/// `T` must be a vector of floats.
728#[rustc_intrinsic]
729#[rustc_nounwind]
730pub unsafe fn simd_fcos<T>(a: T) -> T;
731
732// Computes the exponential function of each element.
733///
734/// `T` must be a vector of floats.
735#[rustc_intrinsic]
736#[rustc_nounwind]
737pub unsafe fn simd_fexp<T>(a: T) -> T;
738
739// Computes 2 raised to the power of each element.
740///
741/// `T` must be a vector of floats.
742#[rustc_intrinsic]
743#[rustc_nounwind]
744pub unsafe fn simd_fexp2<T>(a: T) -> T;
745
746// Computes the base 10 logarithm of each element.
747///
748/// `T` must be a vector of floats.
749#[rustc_intrinsic]
750#[rustc_nounwind]
751pub unsafe fn simd_flog10<T>(a: T) -> T;
752
753// Computes the base 2 logarithm of each element.
754///
755/// `T` must be a vector of floats.
756#[rustc_intrinsic]
757#[rustc_nounwind]
758pub unsafe fn simd_flog2<T>(a: T) -> T;
759
760// Computes the natural logarithm of each element.
761///
762/// `T` must be a vector of floats.
763#[rustc_intrinsic]
764#[rustc_nounwind]
765pub unsafe fn simd_flog<T>(a: T) -> T;