core/intrinsics/
simd.rs

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