Skip to main content

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