summaryrefslogtreecommitdiffstats
path: root/third_party/rust/packed_simd/src/api/minimal/iuf.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/packed_simd/src/api/minimal/iuf.rs')
-rw-r--r--third_party/rust/packed_simd/src/api/minimal/iuf.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/third_party/rust/packed_simd/src/api/minimal/iuf.rs b/third_party/rust/packed_simd/src/api/minimal/iuf.rs
new file mode 100644
index 0000000000..a155ac178a
--- /dev/null
+++ b/third_party/rust/packed_simd/src/api/minimal/iuf.rs
@@ -0,0 +1,169 @@
+//! Minimal API of signed integer, unsigned integer, and floating-point
+//! vectors.
+
+macro_rules! impl_minimal_iuf {
+ ([$elem_ty:ident; $elem_count:expr]: $id:ident | $ielem_ty:ident |
+ $test_tt:tt | $($elem_name:ident),+ | $(#[$doc:meta])*) => {
+
+ $(#[$doc])*
+ pub type $id = Simd<[$elem_ty; $elem_count]>;
+
+ impl sealed::Simd for $id {
+ type Element = $elem_ty;
+ const LANES: usize = $elem_count;
+ type LanesType = [u32; $elem_count];
+ }
+
+ impl $id {
+ /// Creates a new instance with each vector elements initialized
+ /// with the provided values.
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ pub const fn new($($elem_name: $elem_ty),*) -> Self {
+ Simd(codegen::$id($($elem_name as $ielem_ty),*))
+ }
+
+ /// Returns the number of vector lanes.
+ #[inline]
+ pub const fn lanes() -> usize {
+ $elem_count
+ }
+
+ /// Constructs a new instance with each element initialized to
+ /// `value`.
+ #[inline]
+ pub const fn splat(value: $elem_ty) -> Self {
+ Simd(codegen::$id($({
+ #[allow(non_camel_case_types, dead_code)]
+ struct $elem_name;
+ value as $ielem_ty
+ }),*))
+ }
+
+ /// Extracts the value at `index`.
+ ///
+ /// # Panics
+ ///
+ /// If `index >= Self::lanes()`.
+ #[inline]
+ pub fn extract(self, index: usize) -> $elem_ty {
+ assert!(index < $elem_count);
+ unsafe { self.extract_unchecked(index) }
+ }
+
+ /// Extracts the value at `index`.
+ ///
+ /// # Safety
+ ///
+ /// If `index >= Self::lanes()` the behavior is undefined.
+ #[inline]
+ pub unsafe fn extract_unchecked(self, index: usize) -> $elem_ty {
+ use crate::llvm::simd_extract;
+ let e: $ielem_ty = simd_extract(self.0, index as u32);
+ e as $elem_ty
+ }
+
+ /// Returns a new vector where the value at `index` is replaced by `new_value`.
+ ///
+ /// # Panics
+ ///
+ /// If `index >= Self::lanes()`.
+ #[inline]
+ #[must_use = "replace does not modify the original value - \
+ it returns a new vector with the value at `index` \
+ replaced by `new_value`d"
+ ]
+ pub fn replace(self, index: usize, new_value: $elem_ty) -> Self {
+ assert!(index < $elem_count);
+ unsafe { self.replace_unchecked(index, new_value) }
+ }
+
+ /// Returns a new vector where the value at `index` is replaced by `new_value`.
+ ///
+ /// # Safety
+ ///
+ /// If `index >= Self::lanes()` the behavior is undefined.
+ #[inline]
+ #[must_use = "replace_unchecked does not modify the original value - \
+ it returns a new vector with the value at `index` \
+ replaced by `new_value`d"
+ ]
+ pub unsafe fn replace_unchecked(
+ self,
+ index: usize,
+ new_value: $elem_ty,
+ ) -> Self {
+ use crate::llvm::simd_insert;
+ Simd(simd_insert(self.0, index as u32, new_value as $ielem_ty))
+ }
+ }
+
+ test_if!{
+ $test_tt:
+ paste::item! {
+ // Comparisons use integer casts within mantissa^1 range.
+ #[allow(clippy::float_cmp)]
+ pub mod [<$id _minimal>] {
+ use super::*;
+ #[cfg_attr(not(target_arch = "wasm32"), test)]
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ fn minimal() {
+ // lanes:
+ assert_eq!($elem_count, $id::lanes());
+
+ // splat and extract / extract_unchecked:
+ const VAL: $elem_ty = 7 as $elem_ty;
+ const VEC: $id = $id::splat(VAL);
+ for i in 0..$id::lanes() {
+ assert_eq!(VAL, VEC.extract(i));
+ assert_eq!(
+ VAL, unsafe { VEC.extract_unchecked(i) }
+ );
+ }
+
+ // replace / replace_unchecked
+ let new_vec = VEC.replace(0, 42 as $elem_ty);
+ for i in 0..$id::lanes() {
+ if i == 0 {
+ assert_eq!(42 as $elem_ty, new_vec.extract(i));
+ } else {
+ assert_eq!(VAL, new_vec.extract(i));
+ }
+ }
+ let new_vec = unsafe {
+ VEC.replace_unchecked(0, 42 as $elem_ty)
+ };
+ for i in 0..$id::lanes() {
+ if i == 0 {
+ assert_eq!(42 as $elem_ty, new_vec.extract(i));
+ } else {
+ assert_eq!(VAL, new_vec.extract(i));
+ }
+ }
+ }
+
+ // FIXME: wasm-bindgen-test does not support #[should_panic]
+ // #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ #[cfg(not(target_arch = "wasm32"))]
+ #[test]
+ #[should_panic]
+ fn extract_panic_oob() {
+ const VAL: $elem_ty = 7 as $elem_ty;
+ const VEC: $id = $id::splat(VAL);
+ let _ = VEC.extract($id::lanes());
+ }
+ // FIXME: wasm-bindgen-test does not support #[should_panic]
+ // #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ #[cfg(not(target_arch = "wasm32"))]
+ #[test]
+ #[should_panic]
+ fn replace_panic_oob() {
+ const VAL: $elem_ty = 7 as $elem_ty;
+ const VEC: $id = $id::splat(VAL);
+ let _ = VEC.replace($id::lanes(), 42 as $elem_ty);
+ }
+ }
+ }
+ }
+ }
+}