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