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