diff --git a/ci/run.sh b/ci/run.sh index a55860e11..a9c6c4963 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -41,6 +41,14 @@ cargo_test() { fi } +cargo_test_impl() { + ORIGINAL_RUSTFLAGS=${RUSTFLAGS} + RUSTFLAGS="${ORIGINAL_RUSTFLAGS} --cfg test_v16 --cfg test_v32" cargo_test ${1} + RUSTFLAGS="${ORIGINAL_RUSTFLAGS} --cfg test_v64 --cfg test_v128" cargo_test ${1} + RUSTFLAGS="${ORIGINAL_RUSTFLAGS} --cfg test_v256 --cfg test_v512" cargo_test ${1} + RUSTFLAGS=${ORIGINAL_RUSTFLAGS} +} + case ${TARGET} in x86_64-apple-ios) # Note: this case must go before the catch-all "x86*" case below @@ -48,43 +56,43 @@ case ${TARGET} in rustc ./ci/deploy_and_run_on_ios_simulator.rs -o $HOME/runtest export CARGO_TARGET_X86_64_APPLE_IOS_RUNNER=$HOME/runtest - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ;; i386-apple-ios) export RUSTFLAGS=-Clink-arg=-mios-simulator-version-min=7.0 rustc ./ci/deploy_and_run_on_ios_simulator.rs -o $HOME/runtest export CARGO_TARGET_I386_APPLE_IOS_RUNNER=$HOME/runtest - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ;; i586*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ORIGINAL_RUSFTFLAGS=${RUSTFLAGS} export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+sse4.2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+avx2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS=${ORIGINAL_RUSFTFLAGS} ;; i686*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ORIGINAL_RUSFTFLAGS=${RUSTFLAGS} export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+sse4.2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" if [[ ${TARGET} != *"apple"* ]]; then # Travis-CI apple build bots do not appear to support AVX2 export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+avx2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" fi export RUSTFLAGS=${ORIGINAL_RUSFTFLAGS} @@ -95,79 +103,79 @@ case ${TARGET} in exit 1 fi - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ORIGINAL_RUSFTFLAGS=${RUSTFLAGS} export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+sse4.2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" if [[ ${TARGET} != *"apple"* ]]; then # Travis-CI apple build bots do not appear to support AVX2 export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+avx2" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" fi export RUSTFLAGS=${ORIGINAL_RUSFTFLAGS} ;; armv7*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+neon" - cargo_test "--release --features=into_bits" - cargo_test "--release --features=into_bits,coresimd" + cargo_test_impl "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits,coresimd" ;; arm*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+v7,+neon" - cargo_test "--release --features=into_bits" - cargo_test "--release --features=into_bits,coresimd" + cargo_test_impl "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits,coresimd" ;; aarch64*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+neon" - cargo_test "--release --features=into_bits" - cargo_test "--release --features=into_bits,coresimd" + cargo_test_impl "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits,coresimd" ;; mips64*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" # FIXME: this doesn't compile succesfully # https://github.com/rust-lang-nursery/packed_simd/issues/18 # # export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+msa -C target-cpu=mips64r6" - # cargo_test "--release --features=into_bits" + # cargo_test_impl "--release --features=into_bits" ;; powerpc-*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+altivec" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" ;; powerpc64-*) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ORIGINAL_RUSFTFLAGS=${RUSTFLAGS} export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+altivec" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS="${ORIGINAL_RUSTFLAGS} -C target-feature=+vsx" - cargo_test "--release --features=into_bits" + cargo_test_impl "--release --features=into_bits" export RUSTFLAGS=${ORIGINAL_RUSFTFLAGS} ;; *) - cargo_test - cargo_test "--release --features=into_bits" + cargo_test_impl + cargo_test_impl "--release --features=into_bits" ;; esac diff --git a/src/api.rs b/src/api.rs index 7e8706176..62b6864aa 100644 --- a/src/api.rs +++ b/src/api.rs @@ -34,141 +34,205 @@ mod swap_bytes; crate mod into_bits; macro_rules! impl_i { - ([$elem_ty:ident; $elem_count:expr]: $tuple_id:ident, $mask_ty:ident - | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* | $(#[$doc:meta])*) => { - impl_minimal_iuf!([$elem_ty; $elem_count]: $tuple_id + ([$elem_ty:ident; $elem_n:expr]: $tuple_id:ident, $mask_ty:ident | + $test_tt:tt | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* + | $(#[$doc:meta])*) => { + impl_minimal_iuf!([$elem_ty; $elem_n]: $tuple_id | $test_tt | $($elem_ids),* | $(#[$doc])*); - impl_ops_vector_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_bitwise!([$elem_ty; $elem_count]: $tuple_id | (!(0 as $elem_ty), 0)); - impl_ops_scalar_bitwise!([$elem_ty; $elem_count]: $tuple_id | (!(0 as $elem_ty), 0)); - impl_ops_vector_shifts!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_shifts!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_rotates!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_neg!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_int_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_integer_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_bitwise!([$elem_ty; $elem_count]: $tuple_id | $elem_ty | (|x|{ x }) | (!(0 as $elem_ty), 0)); - impl_fmt_debug!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_lower_hex!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_upper_hex!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_octal!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_binary!([$elem_ty; $elem_count]: $tuple_id); - impl_from_array!([$elem_ty; $elem_count]: $tuple_id | (1, 1)); - impl_from_vectors!([$elem_ty; $elem_count]: $tuple_id | $($from_vec_ty),*); - impl_default!([$elem_ty; $elem_count]: $tuple_id); - impl_hash!([$elem_ty; $elem_count]: $tuple_id); - impl_slice_from_slice!([$elem_ty; $elem_count]: $tuple_id); - impl_slice_write_to_slice!([$elem_ty; $elem_count]: $tuple_id); - impl_swap_bytes!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_partial_eq!([$elem_ty; $elem_count]: $tuple_id | (0, 1)); - impl_cmp_eq!([$elem_ty; $elem_count]: $tuple_id | (0, 1)); - impl_cmp_vertical!([$elem_ty; $elem_count]: $tuple_id, $mask_ty, false, (1, 0)); - impl_cmp_partial_ord!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_ord!([$elem_ty; $elem_count]: $tuple_id | (0, 1)); + impl_ops_vector_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (!(0 as $elem_ty), 0) + ); + impl_ops_scalar_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (!(0 as $elem_ty), 0) + ); + impl_ops_vector_shifts!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_shifts!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_rotates!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_neg!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_int_min_max!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_reduction_integer_arithmetic!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + ); + impl_reduction_min_max!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_reduction_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $elem_ty + | (|x|{ x }) | (!(0 as $elem_ty), 0) + ); + impl_fmt_debug!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_lower_hex!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_upper_hex!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_octal!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_binary!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_from_array!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (1, 1)); + impl_from_vectors!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $($from_vec_ty),* + ); + impl_default!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_hash!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_slice_from_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_slice_write_to_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_swap_bytes!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_partial_eq!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (0, 1)); + impl_cmp_eq!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (0, 1)); + impl_cmp_vertical!( + [$elem_ty; $elem_n]: $tuple_id, $mask_ty, false, (1, 0) | $test_tt + ); + impl_cmp_partial_ord!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_ord!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (0, 1)); - test_select!($elem_ty, $mask_ty, $tuple_id, (1, 2)); - test_cmp_partial_ord_int!([$elem_ty; $elem_count]: $tuple_id); + test_select!($elem_ty, $mask_ty, $tuple_id, (1, 2) | $test_tt); + test_cmp_partial_ord_int!([$elem_ty; $elem_n]: $tuple_id | $test_tt); } } macro_rules! impl_u { - ([$elem_ty:ident; $elem_count:expr]: $tuple_id:ident, $mask_ty:ident - | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* | $(#[$doc:meta])*) => { - impl_minimal_iuf!([$elem_ty; $elem_count]: $tuple_id + ([$elem_ty:ident; $elem_n:expr]: $tuple_id:ident, $mask_ty:ident + | $test_tt:tt | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* + | $(#[$doc:meta])*) => { + impl_minimal_iuf!([$elem_ty; $elem_n]: $tuple_id | $test_tt | $($elem_ids),* | $(#[$doc])*); - impl_ops_vector_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_bitwise!([$elem_ty; $elem_count]: $tuple_id | (!(0 as $elem_ty), 0)); - impl_ops_scalar_bitwise!([$elem_ty; $elem_count]: $tuple_id | (!(0 as $elem_ty), 0)); - impl_ops_vector_shifts!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_shifts!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_rotates!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_int_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_integer_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_bitwise!([$elem_ty; $elem_count]: $tuple_id | $elem_ty | - (|x|{ x }) | (!(0 as $elem_ty), 0)); - impl_fmt_debug!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_lower_hex!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_upper_hex!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_octal!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_binary!([$elem_ty; $elem_count]: $tuple_id); - impl_from_array!([$elem_ty; $elem_count]: $tuple_id | (1, 1)); - impl_from_vectors!([$elem_ty; $elem_count]: $tuple_id | $($from_vec_ty),*); - impl_default!([$elem_ty; $elem_count]: $tuple_id); - impl_hash!([$elem_ty; $elem_count]: $tuple_id); - impl_slice_from_slice!([$elem_ty; $elem_count]: $tuple_id); - impl_slice_write_to_slice!([$elem_ty; $elem_count]: $tuple_id); - impl_swap_bytes!([$elem_ty; $elem_count]: $tuple_id); - impl_shuffle_bytes!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_partial_eq!([$elem_ty; $elem_count]: $tuple_id | (1, 0)); - impl_cmp_eq!([$elem_ty; $elem_count]: $tuple_id | (0, 1)); - impl_cmp_vertical!([$elem_ty; $elem_count]: $tuple_id, $mask_ty, false, (1, 0)); - impl_cmp_partial_ord!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_ord!([$elem_ty; $elem_count]: $tuple_id | (0, 1)); + impl_ops_vector_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (!(0 as $elem_ty), 0) + ); + impl_ops_scalar_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (!(0 as $elem_ty), 0) + ); + impl_ops_vector_shifts!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_shifts!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_rotates!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_int_min_max!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_reduction_integer_arithmetic!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + ); + impl_reduction_min_max!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_reduction_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $elem_ty | + (|x|{ x }) | (!(0 as $elem_ty), 0) + ); + impl_fmt_debug!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_lower_hex!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_upper_hex!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_octal!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_binary!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_from_array!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (1, 1)); + impl_from_vectors!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $($from_vec_ty),* + ); + impl_default!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_hash!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_slice_from_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_slice_write_to_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_swap_bytes!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_shuffle_bytes!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_partial_eq!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (1, 0) + ); + impl_cmp_eq!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (0, 1)); + impl_cmp_vertical!( + [$elem_ty; $elem_n]: $tuple_id, $mask_ty, false, (1, 0) | $test_tt + ); + impl_cmp_partial_ord!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_ord!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (0, 1)); - test_select!($elem_ty, $mask_ty, $tuple_id, (1, 2)); - test_cmp_partial_ord_int!([$elem_ty; $elem_count]: $tuple_id); + test_select!($elem_ty, $mask_ty, $tuple_id, (1, 2) | $test_tt); + test_cmp_partial_ord_int!([$elem_ty; $elem_n]: $tuple_id | $test_tt); } } macro_rules! impl_f { - ([$elem_ty:ident; $elem_count:expr]: $tuple_id:ident, $mask_ty:ident - | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* | $(#[$doc:meta])*) => { - impl_minimal_iuf!([$elem_ty; $elem_count]: $tuple_id + ([$elem_ty:ident; $elem_n:expr]: $tuple_id:ident, $mask_ty:ident + | $test_tt:tt | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* + | $(#[$doc:meta])*) => { + impl_minimal_iuf!([$elem_ty; $elem_n]: $tuple_id | $test_tt | $($elem_ids),* | $(#[$doc])*); - impl_ops_vector_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_scalar_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_neg!([$elem_ty; $elem_count]: $tuple_id); - impl_ops_vector_float_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_float_arithmetic!([$elem_ty; $elem_count]: $tuple_id); - impl_reduction_min_max!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_debug!([$elem_ty; $elem_count]: $tuple_id); - impl_from_array!([$elem_ty; $elem_count]: $tuple_id | (1., 1.)); - impl_from_vectors!([$elem_ty; $elem_count]: $tuple_id | $($from_vec_ty),*); - impl_default!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_partial_eq!([$elem_ty; $elem_count]: $tuple_id | (1., 0.)); - impl_slice_from_slice!([$elem_ty; $elem_count]: $tuple_id); - impl_slice_write_to_slice!([$elem_ty; $elem_count]: $tuple_id); + impl_ops_vector_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_scalar_arithmetic!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_neg!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_ops_vector_float_min_max!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + ); + impl_reduction_float_arithmetic!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_reduction_min_max!([$elem_ty; $elem_n]: $tuple_id | $test_tt + ); + impl_fmt_debug!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_from_array!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (1., 1.)); + impl_from_vectors!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $($from_vec_ty),* + ); + impl_default!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_partial_eq!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (1., 0.) + ); + impl_slice_from_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_slice_write_to_slice!([$elem_ty; $elem_n]: $tuple_id | $test_tt); // floating-point math - impl_math_float_abs!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_cos!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_fma!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_recpre!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_rsqrte!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_sin!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_sqrt!([$elem_ty; $elem_count]: $tuple_id); - impl_math_float_sqrte!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_vertical!([$elem_ty; $elem_count]: $tuple_id, $mask_ty, false, (1., 0.)); + impl_math_float_abs!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_cos!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_fma!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_recpre!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_rsqrte!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_sin!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_sqrt!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_math_float_sqrte!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_vertical!( + [$elem_ty; $elem_n]: $tuple_id, $mask_ty, false, (1., 0.) | $test_tt + ); - test_select!($elem_ty, $mask_ty, $tuple_id, (1., 2.)); - test_reduction_float_min_max!([$elem_ty; $elem_count]:$tuple_id); + test_select!($elem_ty, $mask_ty, $tuple_id, (1., 2.) | $test_tt); + test_reduction_float_min_max!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + ); } } macro_rules! impl_m { - ([$elem_ty:ident; $elem_count:expr]: $tuple_id:ident | $ielem_ty:ident | - $($elem_ids:ident),* | From: $($from_vec_ty:ident),* | $(#[$doc:meta])*) => { - impl_minimal_mask!([$elem_ty; $elem_count]: $tuple_id | $ielem_ty | - $($elem_ids),* | $(#[$doc])*); - impl_ops_vector_mask_bitwise!([$elem_ty; $elem_count]: $tuple_id | (true, false)); - impl_ops_scalar_mask_bitwise!([$elem_ty; $elem_count]: $tuple_id | (true, false)); - impl_reduction_bitwise!([bool; $elem_count]: $tuple_id | $ielem_ty | (|x|{ x != 0 }) | (true, false)); - impl_reduction_mask!([$elem_ty; $elem_count]: $tuple_id); - impl_fmt_debug!([bool; $elem_count]: $tuple_id); - impl_from_array!([$elem_ty; $elem_count]: $tuple_id | ($elem_ty::new(true), true)); - impl_from_vectors!([$elem_ty; $elem_count]: $tuple_id | $($from_vec_ty),*); - impl_default!([bool; $elem_count]: $tuple_id); - impl_cmp_partial_eq!([$elem_ty; $elem_count]: $tuple_id | (true, false)); - impl_cmp_eq!([$elem_ty; $elem_count]: $tuple_id | (true, false)); - impl_cmp_vertical!([$elem_ty; $elem_count]: $tuple_id, $tuple_id, true, (true, false)); - impl_select!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_partial_ord!([$elem_ty; $elem_count]: $tuple_id); - impl_cmp_ord!([$elem_ty; $elem_count]: $tuple_id | (false, true)); + ([$elem_ty:ident; $elem_n:expr]: $tuple_id:ident | $ielem_ty:ident + | $test_tt:tt | $($elem_ids:ident),* | From: $($from_vec_ty:ident),* + | $(#[$doc:meta])*) => { + impl_minimal_mask!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + | $ielem_ty | $($elem_ids),* | $(#[$doc])* + ); + impl_ops_vector_mask_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (true, false) + ); + impl_ops_scalar_mask_bitwise!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (true, false) + ); + impl_reduction_bitwise!( + [bool; $elem_n]: $tuple_id | $test_tt | $ielem_ty + | (|x|{ x != 0 }) | (true, false) + ); + impl_reduction_mask!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_fmt_debug!([bool; $elem_n]: $tuple_id | $test_tt); + impl_from_array!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt + | ($elem_ty::new(true), true) + ); + impl_from_vectors!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | $($from_vec_ty),* + ); + impl_default!([bool; $elem_n]: $tuple_id | $test_tt); + impl_cmp_partial_eq!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (true, false) + ); + impl_cmp_eq!([$elem_ty; $elem_n]: $tuple_id | $test_tt | (true, false)); + impl_cmp_vertical!( + [$elem_ty; $elem_n]: $tuple_id, $tuple_id, true, (true, false) + | $test_tt + ); + impl_select!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_partial_ord!([$elem_ty; $elem_n]: $tuple_id | $test_tt); + impl_cmp_ord!( + [$elem_ty; $elem_n]: $tuple_id | $test_tt | (false, true) + ); - test_cmp_partial_ord_mask!([$elem_ty; $elem_count]: $tuple_id); + test_cmp_partial_ord_mask!([$elem_ty; $elem_n]: $tuple_id | $test_tt); } } diff --git a/src/api/cast/macros.rs b/src/api/cast/macros.rs index b7f2684ff..7929d52fb 100644 --- a/src/api/cast/macros.rs +++ b/src/api/cast/macros.rs @@ -1,7 +1,7 @@ //! Macros implementing `FromCast` macro_rules! impl_from_cast_ { - ($id:ident : $from_ty:ident) => { + ($id:ident[$test_tt:tt]: $from_ty:ident) => { impl crate::api::cast::FromCast<$from_ty> for $id { #[inline] fn from_cast(x: $from_ty) -> Self { @@ -11,13 +11,15 @@ macro_rules! impl_from_cast_ { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _from_cast_ $from_ty] { - use super::*; - #[test] - fn test() { - assert_eq!($id::lanes(), $from_ty::lanes()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from_cast_ $from_ty] { + use super::*; + #[test] + fn test() { + assert_eq!($id::lanes(), $from_ty::lanes()); + } } } } @@ -25,15 +27,15 @@ macro_rules! impl_from_cast_ { } macro_rules! impl_from_cast { - ($id:ident: $($from_ty:ident),*) => { + ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { $( - impl_from_cast_!($id: $from_ty); + impl_from_cast_!($id[$test_tt]: $from_ty); )* } } macro_rules! impl_from_cast_mask_ { - ($id:ident : $from_ty:ident) => { + ($id:ident[$test_tt:tt]: $from_ty:ident) => { impl crate::api::cast::FromCast<$from_ty> for $id { #[inline] fn from_cast(x: $from_ty) -> Self { @@ -43,17 +45,19 @@ macro_rules! impl_from_cast_mask_ { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _from_cast_ $from_ty] { - use super::*; - #[test] - fn test() { - assert_eq!($id::lanes(), $from_ty::lanes()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from_cast_ $from_ty] { + use super::*; + #[test] + fn test() { + assert_eq!($id::lanes(), $from_ty::lanes()); - let x = $from_ty::default(); - let m: $id = x.cast(); - assert!(m.none()); + let x = $from_ty::default(); + let m: $id = x.cast(); + assert!(m.none()); + } } } } @@ -61,18 +65,18 @@ macro_rules! impl_from_cast_mask_ { } macro_rules! impl_from_cast_mask { - ($id:ident: $($from_ty:ident),*) => { + ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { $( - impl_from_cast_mask_!($id: $from_ty); + impl_from_cast_mask_!($id[$test_tt]: $from_ty); )* } } #[allow(unused)] macro_rules! impl_into_cast { - ($id:ident: $($from_ty:ident),*) => { + ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { $( - impl_from_cast_!($from_ty: $id); + impl_from_cast_!($from_ty[$test_tt]: $id); )* } } diff --git a/src/api/cast/v128.rs b/src/api/cast/v128.rs index ea8431830..89ba6eb96 100644 --- a/src/api/cast/v128.rs +++ b/src/api/cast/v128.rs @@ -4,61 +4,61 @@ use crate::*; impl_from_cast!( - i8x16: u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 + i8x16[test_v128]: u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast!( - u8x16: i8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 + u8x16[test_v128]: i8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast_mask!( - m8x16: i8x16, u8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 + m8x16[test_v128]: i8x16, u8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast!( - i16x8: i8x8, u8x8, m8x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + i16x8[test_v128]: i8x8, u8x8, m8x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - u16x8: i8x8, u8x8, m8x8, i16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + u16x8[test_v128]: i8x8, u8x8, m8x8, i16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast_mask!( - m16x8: i8x8, u8x8, m8x8, i16x8, u16x8, i32x8, u32x8, f32x8, m32x8, + m16x8[test_v128]: i8x8, u8x8, m8x8, i16x8, u16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - i32x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, u32x4, f32x4, m32x4, + i32x4[test_v128]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - u32x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, f32x4, m32x4, + u32x4[test_v128]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - f32x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, m32x4, + f32x4[test_v128]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast_mask!( - m32x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, + m32x4[test_v128]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - i64x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + i64x2[test_v128]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - u64x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + u64x2[test_v128]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - f64x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + f64x2[test_v128]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast_mask!( - m64x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + m64x2[test_v128]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, i128x2, u128x2, m128x2 ); -// FIXME: 64-bit single element vectors into_cast impls +// FIXME[test_v128]: 64-bit single element vectors into_cast impls // e.g. impls for _128x1 for e.g. _64x1 diff --git a/src/api/cast/v16.rs b/src/api/cast/v16.rs index ad5d6831f..427c51fe2 100644 --- a/src/api/cast/v16.rs +++ b/src/api/cast/v16.rs @@ -4,14 +4,14 @@ use crate::*; impl_from_cast!( - i8x2: u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + i8x2[test_v16]: u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - u8x2: i8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + u8x2[test_v16]: i8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast_mask!( - m8x2: i8x2, u8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, - i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 + m8x2[test_v16]: i8x2, u8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); diff --git a/src/api/cast/v256.rs b/src/api/cast/v256.rs index a57b6e870..1a1c5a0aa 100644 --- a/src/api/cast/v256.rs +++ b/src/api/cast/v256.rs @@ -3,66 +3,66 @@ use crate::*; -impl_from_cast!(i8x32: u8x32, m8x32, i16x32, u16x32, m16x32); -impl_from_cast!(u8x32: i8x32, m8x32, i16x32, u16x32, m16x32); -impl_from_cast_mask!(m8x32: i8x32, u8x32, i16x32, u16x32, m16x32); +impl_from_cast!(i8x32[test_v256]: u8x32, m8x32, i16x32, u16x32, m16x32); +impl_from_cast!(u8x32[test_v256]: i8x32, m8x32, i16x32, u16x32, m16x32); +impl_from_cast_mask!(m8x32[test_v256]: i8x32, u8x32, i16x32, u16x32, m16x32); impl_from_cast!( - i16x16: i8x16, u8x16, m8x16, u16x16, m16x16, + i16x16[test_v256]: i8x16, u8x16, m8x16, u16x16, m16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast!( - u16x16: i8x16, u8x16, m8x16, i16x16, m16x16, + u16x16[test_v256]: i8x16, u8x16, m8x16, i16x16, m16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast_mask!( - m16x16: i8x16, u8x16, m8x16, i16x16, u16x16, + m16x16[test_v256]: i8x16, u8x16, m8x16, i16x16, u16x16, i32x16, u32x16, f32x16, m32x16 ); impl_from_cast!( - i32x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, u32x8, f32x8, m32x8, + i32x8[test_v256]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - u32x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, f32x8, m32x8, + u32x8[test_v256]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - f32x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, m32x8, + f32x8[test_v256]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast_mask!( - m32x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, + m32x8[test_v256]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - i64x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + i64x4[test_v256]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - u64x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + u64x4[test_v256]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - f64x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + f64x4[test_v256]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast_mask!( - m64x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + m64x4[test_v256]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - i128x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + i128x2[test_v256]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, u128x2, m128x2 ); impl_from_cast!( - u128x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + u128x2[test_v256]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, m128x2 ); impl_from_cast_mask!( - m128x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + m128x2[test_v256]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, m64x2, f64x2, i128x2, u128x2 ); diff --git a/src/api/cast/v32.rs b/src/api/cast/v32.rs index 8278e8d8d..7202479fb 100644 --- a/src/api/cast/v32.rs +++ b/src/api/cast/v32.rs @@ -4,27 +4,27 @@ use crate::*; impl_from_cast!( - i8x4: u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + i8x4[test_v32]: u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - u8x4: i8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + u8x4[test_v32]: i8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast_mask!( - m8x4: i8x4, u8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + m8x4[test_v32]: i8x4, u8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - i16x2: i8x2, u8x2, m8x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + i16x2[test_v32]: i8x2, u8x2, m8x2, u16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - u16x2: i8x2, u8x2, m8x2, i16x2, m16x2, i32x2, u32x2, f32x2, m32x2, + u16x2[test_v32]: i8x2, u8x2, m8x2, i16x2, m16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast_mask!( - m16x2: i8x2, u8x2, m8x2, i16x2, u16x2, i32x2, u32x2, f32x2, m32x2, + m16x2[test_v32]: i8x2, u8x2, m8x2, i16x2, u16x2, i32x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); diff --git a/src/api/cast/v512.rs b/src/api/cast/v512.rs index 0193680f3..03f9f9fc6 100644 --- a/src/api/cast/v512.rs +++ b/src/api/cast/v512.rs @@ -3,53 +3,53 @@ use crate::*; -impl_from_cast!(i8x64: u8x64, m8x64); -impl_from_cast!(u8x64: i8x64, m8x64); -impl_from_cast_mask!(m8x64: i8x64, u8x64); +impl_from_cast!(i8x64[test_v512]: u8x64, m8x64); +impl_from_cast!(u8x64[test_v512]: i8x64, m8x64); +impl_from_cast_mask!(m8x64[test_v512]: i8x64, u8x64); -impl_from_cast!(i16x32: i8x32, u8x32, m8x32, u16x32, m16x32); -impl_from_cast!(u16x32: i8x32, u8x32, m8x32, i16x32, m16x32); -impl_from_cast_mask!(m16x32: i8x32, u8x32, m8x32, i16x32, u16x32); +impl_from_cast!(i16x32[test_v512]: i8x32, u8x32, m8x32, u16x32, m16x32); +impl_from_cast!(u16x32[test_v512]: i8x32, u8x32, m8x32, i16x32, m16x32); +impl_from_cast_mask!(m16x32[test_v512]: i8x32, u8x32, m8x32, i16x32, u16x32); impl_from_cast!( - i32x16: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, u32x16, f32x16, m32x16 + i32x16[test_v512]: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, u32x16, f32x16, m32x16 ); impl_from_cast!( - u32x16: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, f32x16, m32x16 + u32x16[test_v512]: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, f32x16, m32x16 ); impl_from_cast!( - f32x16: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, m32x16 + f32x16[test_v512]: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, m32x16 ); impl_from_cast_mask!( - m32x16: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16 + m32x16[test_v512]: i8x16, u8x16, m8x16, i16x16, u16x16, m16x16, i32x16, u32x16, f32x16 ); impl_from_cast!( - i64x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + i64x8[test_v512]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - u64x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + u64x8[test_v512]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, f64x8, m64x8 ); impl_from_cast!( - f64x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + f64x8[test_v512]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, m64x8 ); impl_from_cast_mask!( - m64x8: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + m64x8[test_v512]: i8x8, u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8 ); impl_from_cast!( - i128x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + i128x4[test_v512]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, u128x4, m128x4 ); impl_from_cast!( - u128x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + u128x4[test_v512]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, m128x4 ); impl_from_cast_mask!( - m128x4: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + m128x4[test_v512]: i8x4, u8x4, m8x4, i16x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, m64x4, f64x4, i128x4, u128x4 ); diff --git a/src/api/cast/v64.rs b/src/api/cast/v64.rs index 36ddac589..a7c54c058 100644 --- a/src/api/cast/v64.rs +++ b/src/api/cast/v64.rs @@ -4,44 +4,44 @@ use crate::*; impl_from_cast!( - i8x8: u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + i8x8[test_v64]: u8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - u8x8: i8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + u8x8[test_v64]: i8x8, m8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast_mask!( - m8x8: i8x8, u8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, + m8x8[test_v64]: i8x8, u8x8, i16x8, u16x8, m16x8, i32x8, u32x8, f32x8, m32x8, i64x8, u64x8, f64x8, m64x8 ); impl_from_cast!( - i16x4: i8x4, u8x4, m8x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + i16x4[test_v64]: i8x4, u8x4, m8x4, u16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - u16x4: i8x4, u8x4, m8x4, i16x4, m16x4, i32x4, u32x4, f32x4, m32x4, + u16x4[test_v64]: i8x4, u8x4, m8x4, i16x4, m16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast_mask!( - m16x4: i8x4, u8x4, m8x4, i16x4, u16x4, i32x4, u32x4, f32x4, m32x4, + m16x4[test_v64]: i8x4, u8x4, m8x4, i16x4, u16x4, i32x4, u32x4, f32x4, m32x4, i64x4, u64x4, f64x4, m64x4, i128x4, u128x4, m128x4 ); impl_from_cast!( - i32x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, u32x2, f32x2, m32x2, + i32x2[test_v64]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, u32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - u32x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, f32x2, m32x2, + u32x2[test_v64]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, f32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast!( - f32x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, m32x2, + f32x2[test_v64]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, m32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); impl_from_cast_mask!( - m32x2: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, + m32x2[test_v64]: i8x2, u8x2, m8x2, i16x2, u16x2, m16x2, i32x2, u32x2, f32x2, i64x2, u64x2, f64x2, m64x2, i128x2, u128x2, m128x2 ); diff --git a/src/api/cmp/eq.rs b/src/api/cmp/eq.rs index 68b77e2c4..2a583e4fa 100644 --- a/src/api/cmp/eq.rs +++ b/src/api/cmp/eq.rs @@ -3,21 +3,23 @@ macro_rules! impl_cmp_eq { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl ::cmp::Eq for $id {} impl ::cmp::Eq for PartiallyOrdered<$id> {} - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_eq] { - use super::*; - #[test] - fn eq() { - fn foo(_: E) {} - let a = $id::splat($false); - foo(a); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_eq] { + use super::*; + #[test] + fn eq() { + fn foo(_: E) {} + let a = $id::splat($false); + foo(a); + } } } } diff --git a/src/api/cmp/ord.rs b/src/api/cmp/ord.rs index b21787ead..807dc635b 100644 --- a/src/api/cmp/ord.rs +++ b/src/api/cmp/ord.rs @@ -3,7 +3,7 @@ macro_rules! impl_cmp_ord { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl $id { @@ -24,16 +24,18 @@ macro_rules! impl_cmp_ord { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_ord] { - use super::*; - #[test] - fn eq() { - fn foo(_: E) {} - let a = $id::splat($false); - foo(a.partial_ord()); - foo(a.ord()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_ord] { + use super::*; + #[test] + fn eq() { + fn foo(_: E) {} + let a = $id::splat($false); + foo(a.partial_ord()); + foo(a.ord()); + } } } } diff --git a/src/api/cmp/partial_eq.rs b/src/api/cmp/partial_eq.rs index 54ccf3aa6..8e6d37a63 100644 --- a/src/api/cmp/partial_eq.rs +++ b/src/api/cmp/partial_eq.rs @@ -3,7 +3,7 @@ macro_rules! impl_cmp_partial_eq { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2892 @@ -34,28 +34,30 @@ macro_rules! impl_cmp_partial_eq { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_PartialEq] { - use super::*; - #[test] - fn partial_eq() { - let a = $id::splat($false); - let b = $id::splat($true); - - assert!(a != b); - assert!(!(a == b)); - assert!(a == a); - assert!(!(a != a)); - - if $id::lanes() > 1 { - let a = $id::splat($false).replace(0, $true); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_PartialEq] { + use super::*; + #[test] + fn partial_eq() { + let a = $id::splat($false); let b = $id::splat($true); assert!(a != b); assert!(!(a == b)); assert!(a == a); assert!(!(a != a)); + + if $id::lanes() > 1 { + let a = $id::splat($false).replace(0, $true); + let b = $id::splat($true); + + assert!(a != b); + assert!(!(a == b)); + assert!(a == a); + assert!(!(a != a)); + } } } } diff --git a/src/api/cmp/partial_ord.rs b/src/api/cmp/partial_ord.rs index cefd595fd..52344a5cd 100644 --- a/src/api/cmp/partial_ord.rs +++ b/src/api/cmp/partial_ord.rs @@ -3,7 +3,7 @@ //! This implements a lexicographical order. macro_rules! impl_cmp_partial_ord { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Returns a wrapper that implements `PartialOrd`. #[inline] @@ -64,116 +64,165 @@ macro_rules! impl_cmp_partial_ord { } macro_rules! test_cmp_partial_ord_int { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_PartialOrd] { - use super::*; - #[test] - fn partial_ord() { - use ::test_utils::{test_cmp}; - // constant values - let a = $id::splat(0); - let b = $id::splat(1); + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_PartialOrd] { + use super::*; + #[test] + fn partial_ord() { + use ::testing::utils::{test_cmp}; + // constant values + let a = $id::splat(0); + let b = $id::splat(1); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); - // variable values: a = [0, 1, 2, 3]; b = [3, 2, 1, 0] - let mut a = $id::splat(0); - let mut b = $id::splat(0); - for i in 0..$id::lanes() { - a = a.replace(i, i as $elem_ty); - b = b.replace(i, ($id::lanes() - i) as $elem_ty); - } - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); - - // variable values: a = [0, 1, 2, 3]; b = [0, 1, 2, 4] - let mut b = a; - b = b.replace($id::lanes()-1, a.extract($id::lanes() - 1) + 1 as $elem_ty); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); - - if $id::lanes() > 2 { - // variable values a = [0, 1, 0, 0]; b = [0, 1, 2, 3] - let b = a; + // variable values: a = [0, 1, 2, 3]; b = [3, 2, 1, 0] let mut a = $id::splat(0); - a = a.replace(1, 1 as $elem_ty); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + let mut b = $id::splat(0); + for i in 0..$id::lanes() { + a = a.replace(i, i as $elem_ty); + b = b.replace(i, ($id::lanes() - i) as $elem_ty); + } + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); - // variable values: a = [0, 1, 2, 3]; b = [0, 1, 3, 2] + // variable values: a = [0, 1, 2, 3]; b = [0, 1, 2, 4] let mut b = a; - b = b.replace(2, a.extract($id::lanes() - 1) + 1 as $elem_ty); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + b = b.replace($id::lanes()-1, + a.extract($id::lanes() - 1) + 1 as $elem_ty); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); + + if $id::lanes() > 2 { + // variable values a = [0, 1, 0, 0]; b = [0, 1, 2, 3] + let b = a; + let mut a = $id::splat(0); + a = a.replace(1, 1 as $elem_ty); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); + + // variable values: a = [0, 1, 2, 3]; b = [0, 1, 3, 2] + let mut b = a; + b = b.replace( + 2, a.extract($id::lanes() - 1) + 1 as $elem_ty + ); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); + } } } } } - } + }; } macro_rules! test_cmp_partial_ord_mask { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_PartialOrd] { - use super::*; - #[test] - fn partial_ord() { - use ::test_utils::{test_cmp}; - // constant values - let a = $id::splat(false); - let b = $id::splat(true); + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_PartialOrd] { + use super::*; + #[test] + fn partial_ord() { + use ::testing::utils::{test_cmp}; + // constant values + let a = $id::splat(false); + let b = $id::splat(true); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); - // variable values: a = [false, false, false, false]; b = [false, false, false, true] - let a = $id::splat(false); - let mut b = $id::splat(false); - b = b.replace($id::lanes() - 1, true); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + // variable values: + // a = [false, false, false, false]; + // b = [false, false, false, true] + let a = $id::splat(false); + let mut b = $id::splat(false); + b = b.replace($id::lanes() - 1, true); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); - // variable values: a = [true, true, true, false]; b = [true, true, true, true] - let mut a = $id::splat(true); - let b = $id::splat(true); - a = a.replace($id::lanes() - 1, false); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + // variable values: + // a = [true, true, true, false]; + // b = [true, true, true, true] + let mut a = $id::splat(true); + let b = $id::splat(true); + a = a.replace($id::lanes() - 1, false); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); - if $id::lanes() > 2 { - // variable values a = [false, true, false, false]; b = [false, true, true, true] - let mut a = $id::splat(false); - let mut b = $id::splat(true); - a = a.replace(1, true); - b = b.replace(0, false); - test_cmp(a.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Less)); - test_cmp(b.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Greater)); - test_cmp(a.partial_ord(), a.partial_ord(), Some(::cmp::Ordering::Equal)); - test_cmp(b.partial_ord(), b.partial_ord(), Some(::cmp::Ordering::Equal)); + if $id::lanes() > 2 { + // variable values + // a = [false, true, false, false]; + // b = [false, true, true, true] + let mut a = $id::splat(false); + let mut b = $id::splat(true); + a = a.replace(1, true); + b = b.replace(0, false); + test_cmp(a.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Less)); + test_cmp(b.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Greater)); + test_cmp(a.partial_ord(), a.partial_ord(), + Some(::cmp::Ordering::Equal)); + test_cmp(b.partial_ord(), b.partial_ord(), + Some(::cmp::Ordering::Equal)); + } } } } } - } + }; } diff --git a/src/api/cmp/vertical.rs b/src/api/cmp/vertical.rs index 9b376c97c..7d5552987 100644 --- a/src/api/cmp/vertical.rs +++ b/src/api/cmp/vertical.rs @@ -5,7 +5,7 @@ macro_rules! impl_cmp_vertical { [$elem_ty:ident; $elem_count:expr]: $id:ident, $mask_ty:ident, - $is_mask:expr,($true:expr, $false:expr) + $is_mask:expr,($true:expr, $false:expr) | $test_tt:tt ) => { impl $id { /// Lane-wise equality comparison. @@ -66,45 +66,47 @@ macro_rules! impl_cmp_vertical { } } } - #[cfg(test)] - interpolate_idents! { - mod [$id _cmp_vertical] { - use super::*; - #[test] - fn cmp() { - let a = $id::splat($false); - let b = $id::splat($true); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _cmp_vertical] { + use super::*; + #[test] + fn cmp() { + let a = $id::splat($false); + let b = $id::splat($true); - let r = a.lt(b); - let e = $mask_ty::splat(true); - assert!(r == e); - let r = a.le(b); - assert!(r == e); + let r = a.lt(b); + let e = $mask_ty::splat(true); + assert!(r == e); + let r = a.le(b); + assert!(r == e); - let e = $mask_ty::splat(false); - let r = a.gt(b); - assert!(r == e); - let r = a.ge(b); - assert!(r == e); - let r = a.eq(b); - assert!(r == e); + let e = $mask_ty::splat(false); + let r = a.gt(b); + assert!(r == e); + let r = a.ge(b); + assert!(r == e); + let r = a.eq(b); + assert!(r == e); - let mut a = a; - let mut b = b; - let mut e = e; - for i in 0..$id::lanes() { - if i % 2 == 0 { - a = a.replace(i, $false); - b = b.replace(i, $true); - e = e.replace(i, true); - } else { - a = a.replace(i, $true); - b = b.replace(i, $false); - e = e.replace(i, false); + let mut a = a; + let mut b = b; + let mut e = e; + for i in 0..$id::lanes() { + if i % 2 == 0 { + a = a.replace(i, $false); + b = b.replace(i, $true); + e = e.replace(i, true); + } else { + a = a.replace(i, $true); + b = b.replace(i, $false); + e = e.replace(i, false); + } } + let r = a.lt(b); + assert!(r == e); } - let r = a.lt(b); - assert!(r == e); } } } diff --git a/src/api/default.rs b/src/api/default.rs index 9b6e5be5c..d13b16ed6 100644 --- a/src/api/default.rs +++ b/src/api/default.rs @@ -1,7 +1,7 @@ //! Implements `Default` for vector types. macro_rules! impl_default { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::default::Default for $id { #[inline] fn default() -> Self { @@ -9,15 +9,17 @@ macro_rules! impl_default { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _default] { - use super::*; - #[test] - fn default() { - let a = $id::default(); - for i in 0..$id::lanes() { - assert_eq!(a.extract(i), $elem_ty::default()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _default] { + use super::*; + #[test] + fn default() { + let a = $id::default(); + for i in 0..$id::lanes() { + assert_eq!(a.extract(i), $elem_ty::default()); + } } } } diff --git a/src/api/fmt/binary.rs b/src/api/fmt/binary.rs index fd9f65e05..e967b2f5b 100644 --- a/src/api/fmt/binary.rs +++ b/src/api/fmt/binary.rs @@ -1,9 +1,10 @@ //! Implement Octal formatting macro_rules! impl_fmt_binary { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::fmt::Binary for $id { - #[cfg_attr(feature = "cargo-clippy", allow(missing_inline_in_public_items))] + #[cfg_attr(feature = "cargo-clippy", + allow(missing_inline_in_public_items))] fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2891 #[cfg_attr(feature = "cargo-clippy", allow(write_literal))] @@ -17,31 +18,36 @@ macro_rules! impl_fmt_binary { write!(f, ")") } } - #[cfg(test)] - interpolate_idents! { - mod [$id _fmt_binary] { - use super::*; - #[test] - fn binary() { - use arrayvec::{ArrayString,ArrayVec}; - type TinyString = ArrayString<[u8; 512]>; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _fmt_binary] { + use super::*; + #[test] + fn binary() { + use arrayvec::{ArrayString,ArrayVec}; + type TinyString = ArrayString<[u8; 512]>; - use fmt::Write; - let v = $id::splat($elem_ty::default()); - let mut s = TinyString::new(); - write!(&mut s, "{:#b}", v).unwrap(); + use fmt::Write; + let v = $id::splat($elem_ty::default()); + let mut s = TinyString::new(); + write!(&mut s, "{:#b}", v).unwrap(); - let mut beg = TinyString::new(); - write!(&mut beg, "{}(", stringify!($id)).unwrap(); - assert!(s.starts_with(beg.as_str())); - assert!(s.ends_with(")")); - let s: ArrayVec<[TinyString; 64]> = s.replace(beg.as_str(), "").replace(")", "").split(",") - .map(|v| TinyString::from(v.trim()).unwrap()).collect(); - assert_eq!(s.len(), $id::lanes()); - for (index, ss) in s.into_iter().enumerate() { - let mut e = TinyString::new(); - write!(&mut e, "{:#b}", v.extract(index)).unwrap(); - assert_eq!(ss, e); + let mut beg = TinyString::new(); + write!(&mut beg, "{}(", stringify!($id)).unwrap(); + assert!(s.starts_with(beg.as_str())); + assert!(s.ends_with(")")); + let s: ArrayVec<[TinyString; 64]> + = s.replace(beg.as_str(), "") + .replace(")", "").split(",") + .map(|v| TinyString::from(v.trim()).unwrap()) + .collect(); + assert_eq!(s.len(), $id::lanes()); + for (index, ss) in s.into_iter().enumerate() { + let mut e = TinyString::new(); + write!(&mut e, "{:#b}", v.extract(index)).unwrap(); + assert_eq!(ss, e); + } } } } diff --git a/src/api/fmt/debug.rs b/src/api/fmt/debug.rs index 4a2a62974..f5a903ec2 100644 --- a/src/api/fmt/debug.rs +++ b/src/api/fmt/debug.rs @@ -1,9 +1,10 @@ //! Implement debug formatting macro_rules! impl_fmt_debug { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::fmt::Debug for $id { - #[cfg_attr(feature = "cargo-clippy", allow(missing_inline_in_public_items))] + #[cfg_attr(feature = "cargo-clippy", + allow(missing_inline_in_public_items))] fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2891 #[cfg_attr(feature = "cargo-clippy", allow(write_literal))] @@ -17,31 +18,36 @@ macro_rules! impl_fmt_debug { write!(f, ")") } } - #[cfg(test)] - interpolate_idents! { - mod [$id _fmt_debug] { - use super::*; - #[test] - fn debug() { - use arrayvec::{ArrayString,ArrayVec}; - type TinyString = ArrayString<[u8; 512]>; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _fmt_debug] { + use super::*; + #[test] + fn debug() { + use arrayvec::{ArrayString,ArrayVec}; + type TinyString = ArrayString<[u8; 512]>; - use fmt::Write; - let v = $id::splat($elem_ty::default()); - let mut s = TinyString::new(); - write!(&mut s, "{:?}", v).unwrap(); + use fmt::Write; + let v = $id::splat($elem_ty::default()); + let mut s = TinyString::new(); + write!(&mut s, "{:?}", v).unwrap(); - let mut beg = TinyString::new(); - write!(&mut beg, "{}(", stringify!($id)).unwrap(); - assert!(s.starts_with(beg.as_str())); - assert!(s.ends_with(")")); - let s: ArrayVec<[TinyString; 64]> = s.replace(beg.as_str(), "").replace(")", "").split(",") - .map(|v| TinyString::from(v.trim()).unwrap()).collect(); - assert_eq!(s.len(), $id::lanes()); - for (index, ss) in s.into_iter().enumerate() { - let mut e = TinyString::new(); - write!(&mut e, "{:?}", v.extract(index)).unwrap(); - assert_eq!(ss, e); + let mut beg = TinyString::new(); + write!(&mut beg, "{}(", stringify!($id)).unwrap(); + assert!(s.starts_with(beg.as_str())); + assert!(s.ends_with(")")); + let s: ArrayVec<[TinyString; 64]> + = s.replace(beg.as_str(), "") + .replace(")", "").split(",") + .map(|v| TinyString::from(v.trim()).unwrap()) + .collect(); + assert_eq!(s.len(), $id::lanes()); + for (index, ss) in s.into_iter().enumerate() { + let mut e = TinyString::new(); + write!(&mut e, "{:?}", v.extract(index)).unwrap(); + assert_eq!(ss, e); + } } } } diff --git a/src/api/fmt/lower_hex.rs b/src/api/fmt/lower_hex.rs index 0b499910e..f6eb878e9 100644 --- a/src/api/fmt/lower_hex.rs +++ b/src/api/fmt/lower_hex.rs @@ -1,9 +1,10 @@ //! Implement `LowerHex` formatting macro_rules! impl_fmt_lower_hex { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::fmt::LowerHex for $id { - #[cfg_attr(feature = "cargo-clippy", allow(missing_inline_in_public_items))] + #[cfg_attr(feature = "cargo-clippy", + allow(missing_inline_in_public_items))] fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2891 #[cfg_attr(feature = "cargo-clippy", allow(write_literal))] @@ -17,31 +18,36 @@ macro_rules! impl_fmt_lower_hex { write!(f, ")") } } - #[cfg(test)] - interpolate_idents! { - mod [$id _fmt_lower_hex] { - use super::*; - #[test] - fn lower_hex() { - use arrayvec::{ArrayString,ArrayVec}; - type TinyString = ArrayString<[u8; 512]>; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _fmt_lower_hex] { + use super::*; + #[test] + fn lower_hex() { + use arrayvec::{ArrayString,ArrayVec}; + type TinyString = ArrayString<[u8; 512]>; - use fmt::Write; - let v = $id::splat($elem_ty::default()); - let mut s = TinyString::new(); - write!(&mut s, "{:#x}", v).unwrap(); + use fmt::Write; + let v = $id::splat($elem_ty::default()); + let mut s = TinyString::new(); + write!(&mut s, "{:#x}", v).unwrap(); - let mut beg = TinyString::new(); - write!(&mut beg, "{}(", stringify!($id)).unwrap(); - assert!(s.starts_with(beg.as_str())); - assert!(s.ends_with(")")); - let s: ArrayVec<[TinyString; 64]> = s.replace(beg.as_str(), "").replace(")", "").split(",") - .map(|v| TinyString::from(v.trim()).unwrap()).collect(); - assert_eq!(s.len(), $id::lanes()); - for (index, ss) in s.into_iter().enumerate() { - let mut e = TinyString::new(); - write!(&mut e, "{:#x}", v.extract(index)).unwrap(); + let mut beg = TinyString::new(); + write!(&mut beg, "{}(", stringify!($id)).unwrap(); + assert!(s.starts_with(beg.as_str())); + assert!(s.ends_with(")")); + let s: ArrayVec<[TinyString; 64]> + = s.replace(beg.as_str(), "").replace(")", "") + .split(",") + .map(|v| TinyString::from(v.trim()).unwrap()) + .collect(); + assert_eq!(s.len(), $id::lanes()); + for (index, ss) in s.into_iter().enumerate() { + let mut e = TinyString::new(); + write!(&mut e, "{:#x}", v.extract(index)).unwrap(); assert_eq!(ss, e); + } } } } diff --git a/src/api/fmt/octal.rs b/src/api/fmt/octal.rs index 27dc13476..fe38feb19 100644 --- a/src/api/fmt/octal.rs +++ b/src/api/fmt/octal.rs @@ -1,9 +1,10 @@ //! Implement Octal formatting macro_rules! impl_fmt_octal { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::fmt::Octal for $id { - #[cfg_attr(feature = "cargo-clippy", allow(missing_inline_in_public_items))] + #[cfg_attr(feature = "cargo-clippy", + allow(missing_inline_in_public_items))] fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2891 #[cfg_attr(feature = "cargo-clippy", allow(write_literal))] @@ -17,31 +18,36 @@ macro_rules! impl_fmt_octal { write!(f, ")") } } - #[cfg(test)] - interpolate_idents! { - mod [$id _fmt_octal] { - use super::*; - #[test] - fn octal_hex() { - use arrayvec::{ArrayString,ArrayVec}; - type TinyString = ArrayString<[u8; 512]>; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _fmt_octal] { + use super::*; + #[test] + fn octal_hex() { + use arrayvec::{ArrayString,ArrayVec}; + type TinyString = ArrayString<[u8; 512]>; - use fmt::Write; - let v = $id::splat($elem_ty::default()); - let mut s = TinyString::new(); - write!(&mut s, "{:#o}", v).unwrap(); + use fmt::Write; + let v = $id::splat($elem_ty::default()); + let mut s = TinyString::new(); + write!(&mut s, "{:#o}", v).unwrap(); - let mut beg = TinyString::new(); - write!(&mut beg, "{}(", stringify!($id)).unwrap(); - assert!(s.starts_with(beg.as_str())); - assert!(s.ends_with(")")); - let s: ArrayVec<[TinyString; 64]> = s.replace(beg.as_str(), "").replace(")", "").split(",") - .map(|v| TinyString::from(v.trim()).unwrap()).collect(); - assert_eq!(s.len(), $id::lanes()); - for (index, ss) in s.into_iter().enumerate() { - let mut e = TinyString::new(); - write!(&mut e, "{:#o}", v.extract(index)).unwrap(); - assert_eq!(ss, e); + let mut beg = TinyString::new(); + write!(&mut beg, "{}(", stringify!($id)).unwrap(); + assert!(s.starts_with(beg.as_str())); + assert!(s.ends_with(")")); + let s: ArrayVec<[TinyString; 64]> + = s.replace(beg.as_str(), "").replace(")", "") + .split(",") + .map(|v| TinyString::from(v.trim()).unwrap()) + .collect(); + assert_eq!(s.len(), $id::lanes()); + for (index, ss) in s.into_iter().enumerate() { + let mut e = TinyString::new(); + write!(&mut e, "{:#o}", v.extract(index)).unwrap(); + assert_eq!(ss, e); + } } } } diff --git a/src/api/fmt/upper_hex.rs b/src/api/fmt/upper_hex.rs index 4964f772e..953b5d874 100644 --- a/src/api/fmt/upper_hex.rs +++ b/src/api/fmt/upper_hex.rs @@ -1,9 +1,10 @@ //! Implement `UpperHex` formatting macro_rules! impl_fmt_upper_hex { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::fmt::UpperHex for $id { - #[cfg_attr(feature = "cargo-clippy", allow(missing_inline_in_public_items))] + #[cfg_attr(feature = "cargo-clippy", + allow(missing_inline_in_public_items))] fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2891 #[cfg_attr(feature = "cargo-clippy", allow(write_literal))] @@ -17,31 +18,36 @@ macro_rules! impl_fmt_upper_hex { write!(f, ")") } } - #[cfg(test)] - interpolate_idents! { - mod [$id _fmt_upper_hex] { - use super::*; - #[test] - fn upper_hex() { - use arrayvec::{ArrayString,ArrayVec}; - type TinyString = ArrayString<[u8; 512]>; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _fmt_upper_hex] { + use super::*; + #[test] + fn upper_hex() { + use arrayvec::{ArrayString,ArrayVec}; + type TinyString = ArrayString<[u8; 512]>; - use fmt::Write; - let v = $id::splat($elem_ty::default()); - let mut s = TinyString::new(); - write!(&mut s, "{:#X}", v).unwrap(); + use fmt::Write; + let v = $id::splat($elem_ty::default()); + let mut s = TinyString::new(); + write!(&mut s, "{:#X}", v).unwrap(); - let mut beg = TinyString::new(); - write!(&mut beg, "{}(", stringify!($id)).unwrap(); - assert!(s.starts_with(beg.as_str())); - assert!(s.ends_with(")")); - let s: ArrayVec<[TinyString; 64]> = s.replace(beg.as_str(), "").replace(")", "").split(",") - .map(|v| TinyString::from(v.trim()).unwrap()).collect(); - assert_eq!(s.len(), $id::lanes()); - for (index, ss) in s.into_iter().enumerate() { - let mut e = TinyString::new(); - write!(&mut e, "{:#X}", v.extract(index)).unwrap(); - assert_eq!(ss, e); + let mut beg = TinyString::new(); + write!(&mut beg, "{}(", stringify!($id)).unwrap(); + assert!(s.starts_with(beg.as_str())); + assert!(s.ends_with(")")); + let s: ArrayVec<[TinyString; 64]> + = s.replace(beg.as_str(), "").replace(")", "") + .split(",") + .map(|v| TinyString::from(v.trim()).unwrap()) + .collect(); + assert_eq!(s.len(), $id::lanes()); + for (index, ss) in s.into_iter().enumerate() { + let mut e = TinyString::new(); + write!(&mut e, "{:#X}", v.extract(index)).unwrap(); + assert_eq!(ss, e); + } } } } diff --git a/src/api/from/from_array.rs b/src/api/from/from_array.rs index 8ac46f6d6..79386bd8a 100644 --- a/src/api/from/from_array.rs +++ b/src/api/from/from_array.rs @@ -1,7 +1,7 @@ //! Implements `From<[T; N]>` and `Into<[T; N]>` for vector types. macro_rules! impl_from_array { - ([$elem_ty:ident; $elem_count:expr]: $id:ident + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | ($non_default_array:expr, $non_default_vec:expr)) => { impl From<[$elem_ty; $elem_count]> for $id { #[inline] @@ -53,50 +53,52 @@ macro_rules! impl_from_array { } */ - #[cfg(test)] - interpolate_idents! { - mod [$id _from] { - use super::*; - #[test] - fn array() { - let vec: $id = Default::default(); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from] { + use super::*; + #[test] + fn array() { + let vec: $id = Default::default(); - // FIXME: Workaround for arrays with more than 32 elements. - // - // Safe because we never take a reference to any uninitialized element. - union W { - array: [$elem_ty; $elem_count], - other: () - } - let mut array = W { other: () }; - for i in 0..$elem_count { - let default: $elem_ty = Default::default(); - // note: array.other is the active member and initialized - // so we can take a reference to it: - let p = unsafe { &mut array.other as *mut () as *mut $elem_ty }; - // note: default is a valid bit-pattern for $elem_ty: - unsafe { ::ptr::write(p.wrapping_add(i), default) }; - } - // note: the array variant of the union is properly initialized: - let mut array = unsafe { array.array }; + // FIXME: Workaround for arrays with more than 32 elements. + // + // Safe because we never take a reference to any uninitialized element. + union W { + array: [$elem_ty; $elem_count], + other: () + } + let mut array = W { other: () }; + for i in 0..$elem_count { + let default: $elem_ty = Default::default(); + // note: array.other is the active member and initialized + // so we can take a reference to it: + let p = unsafe { &mut array.other as *mut () as *mut $elem_ty }; + // note: default is a valid bit-pattern for $elem_ty: + unsafe { ::ptr::write(p.wrapping_add(i), default) }; + } + // note: the array variant of the union is properly initialized: + let mut array = unsafe { array.array }; - array[0] = $non_default_array; - let vec = vec.replace(0, $non_default_vec); + array[0] = $non_default_array; + let vec = vec.replace(0, $non_default_vec); - let vec_from_array = $id::from(array); - assert_eq!(vec_from_array, vec); - let array_from_vec = <[$elem_ty; $elem_count]>::from(vec); - // FIXME: Workaround for arrays with more than 32 elements. - for i in 0..$elem_count { - assert_eq!(array_from_vec[[i]], array[[i]]); - } + let vec_from_array = $id::from(array); + assert_eq!(vec_from_array, vec); + let array_from_vec = <[$elem_ty; $elem_count]>::from(vec); + // FIXME: Workaround for arrays with more than 32 elements. + for i in 0..$elem_count { + assert_eq!(array_from_vec[[i]], array[[i]]); + } - let vec_from_into_array: $id = array.into(); - assert_eq!(vec_from_into_array, vec); - let array_from_into_vec: [$elem_ty; $elem_count] = vec.into(); - // FIXME: Workaround for arrays with more than 32 elements. - for i in 0..$elem_count { - assert_eq!(array_from_into_vec[[i]], array[[i]]); + let vec_from_into_array: $id = array.into(); + assert_eq!(vec_from_into_array, vec); + let array_from_into_vec: [$elem_ty; $elem_count] = vec.into(); + // FIXME: Workaround for arrays with more than 32 elements. + for i in 0..$elem_count { + assert_eq!(array_from_into_vec[[i]], array[[i]]); + } } } } diff --git a/src/api/from/from_vector.rs b/src/api/from/from_vector.rs index f1a77217c..c573800e3 100644 --- a/src/api/from/from_vector.rs +++ b/src/api/from/from_vector.rs @@ -1,7 +1,7 @@ //! Implements `From` and `Into` for vector types. macro_rules! impl_from_vector { - ([$elem_ty:ident; $elem_count:expr]: $id:ident | $source:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $source:ident) => { impl From<$source> for $id { #[inline] fn from(source: $source) -> Self { @@ -30,21 +30,23 @@ macro_rules! impl_from_vector { } */ - #[cfg(test)] - interpolate_idents! { - mod [$id _from_ $source] { - use super::*; - #[test] - fn from() { - assert_eq!($id::lanes(), $source::lanes()); - let source: $source = Default::default(); - let vec: $id = Default::default(); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from_ $source] { + use super::*; + #[test] + fn from() { + assert_eq!($id::lanes(), $source::lanes()); + let source: $source = Default::default(); + let vec: $id = Default::default(); - let e = $id::from(source); - assert_eq!(e, vec); + let e = $id::from(source); + assert_eq!(e, vec); - let e: $id = source.into(); - assert_eq!(e, vec); + let e: $id = source.into(); + assert_eq!(e, vec); + } } } } @@ -52,9 +54,9 @@ macro_rules! impl_from_vector { } macro_rules! impl_from_vectors { - ([$elem_ty:ident; $elem_count:expr]: $id:ident | $($source:ident),*) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $($source:ident),*) => { $( - impl_from_vector!([$elem_ty; $elem_count]: $id | $source); + impl_from_vector!([$elem_ty; $elem_count]: $id | $test_tt | $source); )* } } diff --git a/src/api/hash.rs b/src/api/hash.rs index 2467e1b74..426879120 100644 --- a/src/api/hash.rs +++ b/src/api/hash.rs @@ -1,7 +1,7 @@ //! Implements `Hash` for vector types. macro_rules! impl_hash { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::hash::Hash for $id { #[inline] fn hash(&self, state: &mut H) { @@ -15,26 +15,28 @@ macro_rules! impl_hash { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _hash] { - use super::*; - #[test] - fn hash() { - use ::hash::{Hash, Hasher}; - #[allow(deprecated)] - use ::hash::{SipHasher13}; - type A = [$elem_ty; $id::lanes()]; - let a: A = [42 as $elem_ty; $id::lanes()]; - assert!(mem::size_of::() == mem::size_of::<$id>()); - #[allow(deprecated)] - let mut a_hash = SipHasher13::new(); - let mut v_hash = a_hash.clone(); - a.hash(&mut a_hash); + test_if! { + $test_tt: + interpolate_idents! { + mod [$id _hash] { + use super::*; + #[test] + fn hash() { + use ::hash::{Hash, Hasher}; + #[allow(deprecated)] + use ::hash::{SipHasher13}; + type A = [$elem_ty; $id::lanes()]; + let a: A = [42 as $elem_ty; $id::lanes()]; + assert!(mem::size_of::() == mem::size_of::<$id>()); + #[allow(deprecated)] + let mut a_hash = SipHasher13::new(); + let mut v_hash = a_hash.clone(); + a.hash(&mut a_hash); - let v = $id::splat(42 as $elem_ty); - v.hash(&mut v_hash); - assert_eq!(a_hash.finish(), v_hash.finish()); + let v = $id::splat(42 as $elem_ty); + v.hash(&mut v_hash); + assert_eq!(a_hash.finish(), v_hash.finish()); + } } } } diff --git a/src/api/into_bits/arch_specific.rs b/src/api/into_bits/arch_specific.rs index 4625c5561..82dab4b9a 100644 --- a/src/api/into_bits/arch_specific.rs +++ b/src/api/into_bits/arch_specific.rs @@ -7,48 +7,74 @@ #[allow(unused)] use crate::*; -/// This macro implements FromBits for the portable and the architecture specific vector types +/// This macro implements FromBits for the portable and the architecture +/// specific vector types. /// /// The "leaf" case is at the bottom, and the most generic case is at the top. /// The generic case is split into smaller cases recursively. macro_rules! impl_arch { ([$arch_head_i:ident[$arch_head_tt:tt]: $($arch_head_ty:ident),*], $([$arch_tail_i:ident[$arch_tail_tt:tt]: $($arch_tail_ty:ident),*]),* | - from: $($from_ty:ident),* | into: $($into_ty:ident),*) => { + from: $($from_ty:ident),* | into: $($into_ty:ident),* | + test: $test_tt:tt) => { impl_arch!( [$arch_head_i[$arch_head_tt]: $($arch_head_ty),*] | from: $($from_ty),* | - into: $($into_ty),* + into: $($into_ty),* | + test: $test_tt ); impl_arch!( $([$arch_tail_i[$arch_tail_tt]: $($arch_tail_ty),*]),* | from: $($from_ty),* | - into: $($into_ty),* + into: $($into_ty),* | + test: $test_tt ); }; ([$arch:ident[$arch_tt:tt]: $($arch_ty:ident),*] | - from: $($from_ty:ident),* | into: $($into_ty:ident),*) => { - // note: If the target is "arm", "+v7,+neon" must be enabled - #[cfg(any(not(target_arch = "arm"), - all(target_feature = "v7", target_feature = "neon")))] + from: $($from_ty:ident),* | into: $($into_ty:ident),* | + test: $test_tt:tt) => { + // note: if target is "arm", "+v7,+neon" must be enabled + // and the std library must be recompiled with them + #[cfg(any( + not(target_arch = "arm"), + all(target_feature = "v7", target_feature = "neon", + feature = "coresimd")) + )] + // note: if target is "powerpc", "altivec" must be enabled + // and the std library must be recompiled with it + #[cfg(any( + not(target_arch = "powerpc"), + all(target_feature = "altivec", feature = "coresimd"), + ))] #[cfg(target_arch = $arch_tt)] use crate::arch::$arch::{ $($arch_ty),* }; - #[cfg(any(not(target_arch = "arm"), - all(target_feature = "v7", target_feature = "neon")))] + #[cfg(any( + not(target_arch = "arm"), + all(target_feature = "v7", target_feature = "neon", + feature = "coresimd")) + )] + #[cfg(any( + not(target_arch = "powerpc"), + all(target_feature = "altivec", feature = "coresimd"), + ))] #[cfg(target_arch = $arch_tt)] - impl_arch!($($arch_ty),* | $($from_ty),* | $($into_ty),*); + impl_arch!($($arch_ty),* | $($from_ty),* | $($into_ty),* | + test: $test_tt); }; ($arch_head:ident, $($arch_tail:ident),* | $($from_ty:ident),* - | $($into_ty:ident),*) => { - impl_arch!($arch_head | $($from_ty),* | $($into_ty),*); - impl_arch!($($arch_tail),* | $($from_ty),* | $($into_ty),*); + | $($into_ty:ident),* | test: $test_tt:tt) => { + impl_arch!($arch_head | $($from_ty),* | $($into_ty),* | + test: $test_tt); + impl_arch!($($arch_tail),* | $($from_ty),* | $($into_ty),* | + test: $test_tt); }; - ($arch_head:ident | $($from_ty:ident),* | $($into_ty:ident),*) => { - impl_from_bits!($arch_head: $($from_ty),*); - impl_into_bits!($arch_head: $($into_ty),*); + ($arch_head:ident | $($from_ty:ident),* | $($into_ty:ident),* | + test: $test_tt:tt) => { + impl_from_bits!($arch_head[$test_tt]: $($from_ty),*); + impl_into_bits!($arch_head[$test_tt]: $($into_ty),*); }; } @@ -59,22 +85,15 @@ macro_rules! impl_arch { // FIXME: arm/aarch float16x4_t missing impl_arch!( [x86["x86"]: __m64], [x86_64["x86_64"]: __m64], + [arm["arm"]: int8x8_t, uint8x8_t, poly8x8_t, int16x4_t, uint16x4_t, + poly16x4_t, int32x2_t, uint32x2_t, float32x2_t, int64x1_t, + uint64x1_t], [aarch64["aarch64"]: int8x8_t, uint8x8_t, poly8x8_t, int16x4_t, uint16x4_t, poly16x4_t, int32x2_t, uint32x2_t, float32x2_t, int64x1_t, uint64x1_t, float64x1_t] | from: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2 | - into: i8x8, u8x8, i16x4, u16x4, i32x2, u32x2, f32x2 -); - -// FIXME: arm vector types require v7+neon and a re-compiled std library -#[cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon", - feature = "coresimd"))] -impl_arch!( - [arm["arm"]: int8x8_t, uint8x8_t, poly8x8_t, int16x4_t, uint16x4_t, - poly16x4_t, int32x2_t, uint32x2_t, float32x2_t, int64x1_t, - uint64x1_t] | - from: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2 | - into: i8x8, u8x8, i16x4, u16x4, i32x2, u32x2, f32x2 + into: i8x8, u8x8, i16x4, u16x4, i32x2, u32x2, f32x2 | + test: test_v64 ); //////////////////////////////////////////////////////////////////////////////// @@ -88,17 +107,6 @@ impl_arch!( // FIXME: ppc64 vector_bool_long_long missing // FIXME: ppc64 vector_signed___int128 missing // FIXME: ppc64 vector_unsigned___int128 missing -#[cfg(any( - // FIXME: arm vector types require v7+neon and a re-compiled std library - not(target_arch = "arm"), - all(target_feature = "v7", target_feature = "neon", - feature = "coresimd") -))] -#[cfg(any( - // FIXME: powerpc vector types require altivec and a re-compiled std library - not(target_arch = "powerpc"), - all(target_feature = "altivec", feature = "coresimd"), -))] impl_arch!( [x86["x86"]: __m128, __m128i, __m128d], [x86_64["x86_64"]: __m128, __m128i, __m128d], @@ -117,14 +125,10 @@ impl_arch!( from: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1 | into: i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4, i64x2, u64x2, f64x2, - i128x1, u128x1 + i128x1, u128x1 | + test: test_v128 ); -#[cfg(any( - // FIXME: powerpc vector types require altivec and a re-compiled std library - not(target_arch = "powerpc"), - all(target_feature = "altivec", feature = "coresimd"), -))] impl_arch!( [powerpc["powerpc"]: vector_bool_char], [powerpc64["powerpc64"]: vector_bool_char] | @@ -132,14 +136,10 @@ impl_arch!( into: i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4, i64x2, u64x2, f64x2, i128x1, u128x1, // Masks: - m8x16 + m8x16 | + test: test_v128 ); -#[cfg(any( - // FIXME: powerpc vector types require altivec and a re-compiled std library - not(target_arch = "powerpc"), - all(target_feature = "altivec", feature = "coresimd"), -))] impl_arch!( [powerpc["powerpc"]: vector_bool_short], [powerpc64["powerpc64"]: vector_bool_short] | @@ -147,14 +147,10 @@ impl_arch!( into: i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4, i64x2, u64x2, f64x2, i128x1, u128x1, // Masks: - m8x16, m16x8 + m8x16, m16x8 | + test: test_v128 ); -#[cfg(any( - // FIXME: powerpc vector types require altivec and a re-compiled std library - not(target_arch = "powerpc"), - all(target_feature = "altivec", feature = "coresimd"), -))] impl_arch!( [powerpc["powerpc"]: vector_bool_int], [powerpc64["powerpc64"]: vector_bool_int] | @@ -162,7 +158,8 @@ impl_arch!( into: i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4, i64x2, u64x2, f64x2, i128x1, u128x1, // Masks: - m8x16, m16x8, m32x4 + m8x16, m16x8, m32x4 | + test: test_v128 ); impl_arch!( @@ -171,7 +168,8 @@ impl_arch!( into: i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4, i64x2, u64x2, f64x2, i128x1, u128x1, // Masks: - m8x16, m16x8, m32x4, m64x2 + m8x16, m16x8, m32x4, m64x2 | + test: test_v128 ); //////////////////////////////////////////////////////////////////////////////// @@ -184,7 +182,8 @@ impl_arch!( i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2 | into: i8x32, u8x32, i16x16, u16x16, i32x8, u32x8, f32x8, - i64x4, u64x4, f64x4, i128x2, u128x2 + i64x4, u64x4, f64x4, i128x2, u128x2 | + test: test_v256 ); //////////////////////////////////////////////////////////////////////////////// diff --git a/src/api/into_bits/macros.rs b/src/api/into_bits/macros.rs index 2a4ba8b8b..37a7b7ead 100644 --- a/src/api/into_bits/macros.rs +++ b/src/api/into_bits/macros.rs @@ -1,7 +1,7 @@ //! Macros implementing `FromBits` macro_rules! impl_from_bits_ { - ($id:ident: $from_ty:ident) => { + ($id:ident[$test_tt:tt]: $from_ty:ident) => { impl crate::api::into_bits::FromBits<$from_ty> for $id { #[inline] fn from_bits(x: $from_ty) -> Self { @@ -9,32 +9,34 @@ macro_rules! impl_from_bits_ { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _from_bits_ $from_ty] { - use super::*; - #[test] - fn test() { - use ::{ptr::{read_unaligned}, mem::{size_of, zeroed}}; - use ::IntoBits; - assert_eq!(size_of::<$id>(), - size_of::<$from_ty>()); - // This is safe becasue we never create a reference - // to uninitialized memory: - let a: $from_ty = unsafe { zeroed() }; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _from_bits_ $from_ty] { + use super::*; + #[test] + fn test() { + use ::{ptr::{read_unaligned}, mem::{size_of, zeroed}}; + use ::IntoBits; + assert_eq!(size_of::<$id>(), + size_of::<$from_ty>()); + // This is safe becasue we never create a reference + // to uninitialized memory: + let a: $from_ty = unsafe { zeroed() }; - let b_0: $id = ::FromBits::from_bits(a); - let b_1: $id = a.into_bits(); + let b_0: $id = ::FromBits::from_bits(a); + let b_1: $id = a.into_bits(); - // Check that these are byte-wise equal, that is, - // that the bit patterns are identical: - for i in 0..size_of::<$id>() { - // This is safe because we only read initialized memory in bounds. Also, - // taking a reference to `b_i` is ok because the fields are initialized. - unsafe { - let b_0_v: u8 = read_unaligned((&b_0 as *const $id as *const u8).wrapping_add(i)); - let b_1_v: u8 = read_unaligned((&b_1 as *const $id as *const u8).wrapping_add(i)); - assert_eq!(b_0_v, b_1_v); + // Check that these are byte-wise equal, that is, + // that the bit patterns are identical: + for i in 0..size_of::<$id>() { + // This is safe because we only read initialized memory in bounds. Also, + // taking a reference to `b_i` is ok because the fields are initialized. + unsafe { + let b_0_v: u8 = read_unaligned((&b_0 as *const $id as *const u8).wrapping_add(i)); + let b_1_v: u8 = read_unaligned((&b_1 as *const $id as *const u8).wrapping_add(i)); + assert_eq!(b_0_v, b_1_v); + } } } } @@ -44,18 +46,18 @@ macro_rules! impl_from_bits_ { } macro_rules! impl_from_bits { - ($id:ident: $($from_ty:ident),*) => { + ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { $( - impl_from_bits_!($id: $from_ty); + impl_from_bits_!($id[$test_tt]: $from_ty); )* } } #[allow(unused)] macro_rules! impl_into_bits { - ($id:ident: $($from_ty:ident),*) => { + ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { $( - impl_from_bits_!($from_ty: $id); + impl_from_bits_!($from_ty[$test_tt]: $id); )* } } diff --git a/src/api/into_bits/v128.rs b/src/api/into_bits/v128.rs index 569dbe39f..f146b079c 100644 --- a/src/api/into_bits/v128.rs +++ b/src/api/into_bits/v128.rs @@ -3,25 +3,25 @@ use crate::v128::*; -impl_from_bits!(i8x16: u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(u8x16: i8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(m8x16: m16x8, m32x4, m64x2, m128x1); +impl_from_bits!(i8x16[test_v128]: u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(u8x16[test_v128]: i8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(m8x16[test_v128]: m16x8, m32x4, m64x2, m128x1); -impl_from_bits!(i16x8: i8x16, u8x16, m8x16, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(u16x8: i8x16, u8x16, m8x16, i16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(m16x8: m32x4, m64x2, m128x1); +impl_from_bits!(i16x8[test_v128]: i8x16, u8x16, m8x16, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(u16x8[test_v128]: i8x16, u8x16, m8x16, i16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(m16x8[test_v128]: m32x4, m64x2, m128x1); -impl_from_bits!(i32x4: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(u32x4: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(f32x4: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(m32x4: m64x2, m128x1); +impl_from_bits!(i32x4[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(u32x4[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(f32x4[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(m32x4[test_v128]: m64x2, m128x1); -impl_from_bits!(i64x2: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(u64x2: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, f64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(f64x2: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, m64x2, i128x1, u128x1, m128x1); -impl_from_bits!(m64x2: m128x1); +impl_from_bits!(i64x2[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, u64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(u64x2[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, f64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(f64x2[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, m64x2, i128x1, u128x1, m128x1); +impl_from_bits!(m64x2[test_v128]: m128x1); -impl_from_bits!(i128x1: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, u128x1, m128x1); -impl_from_bits!(u128x1: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, m128x1); +impl_from_bits!(i128x1[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, u128x1, m128x1); +impl_from_bits!(u128x1[test_v128]: i8x16, u8x16, m8x16, i16x8, u16x8, m16x8, i32x4, u32x4, f32x4, m32x4, i64x2, u64x2, f64x2, m64x2, i128x1, m128x1); // note: m128x1 cannot be constructed from all the other masks bit patterns in here diff --git a/src/api/into_bits/v16.rs b/src/api/into_bits/v16.rs index e1ffdc1c6..3013e9716 100644 --- a/src/api/into_bits/v16.rs +++ b/src/api/into_bits/v16.rs @@ -3,6 +3,6 @@ use crate::v16::*; -impl_from_bits!(i8x2: u8x2, m8x2); -impl_from_bits!(u8x2: i8x2, m8x2); +impl_from_bits!(i8x2[test_v16]: u8x2, m8x2); +impl_from_bits!(u8x2[test_v16]: i8x2, m8x2); // note: m8x2 cannot be constructed from all i8x2 or u8x2 bit patterns diff --git a/src/api/into_bits/v256.rs b/src/api/into_bits/v256.rs index 2e868c002..85762a61e 100644 --- a/src/api/into_bits/v256.rs +++ b/src/api/into_bits/v256.rs @@ -3,24 +3,24 @@ use crate::v256::*; -impl_from_bits!(i8x32: u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(u8x32: i8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(m8x32: m16x16, m32x8, m64x4, m128x2); +impl_from_bits!(i8x32[test_v256]: u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(u8x32[test_v256]: i8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(m8x32[test_v256]: m16x16, m32x8, m64x4, m128x2); -impl_from_bits!(i16x16: i8x32, u8x32, m8x32, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(u16x16: i8x32, u8x32, m8x32, i16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(m16x16: m32x8, m64x4, m128x2); +impl_from_bits!(i16x16[test_v256]: i8x32, u8x32, m8x32, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(u16x16[test_v256]: i8x32, u8x32, m8x32, i16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(m16x16[test_v256]: m32x8, m64x4, m128x2); -impl_from_bits!(i32x8: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(u32x8: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(f32x8: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(m32x8: m64x4, m128x2); +impl_from_bits!(i32x8[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(u32x8[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(f32x8[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(m32x8[test_v256]: m64x4, m128x2); -impl_from_bits!(i64x4: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(u64x4: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, f64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(f64x4: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, m64x4, i128x2, u128x2, m128x2); -impl_from_bits!(m64x4: m128x2); +impl_from_bits!(i64x4[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, u64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(u64x4[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, f64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(f64x4[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, m64x4, i128x2, u128x2, m128x2); +impl_from_bits!(m64x4[test_v256]: m128x2); -impl_from_bits!(i128x2: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, u128x2, m128x2); -impl_from_bits!(u128x2: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, m128x2); +impl_from_bits!(i128x2[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, u128x2, m128x2); +impl_from_bits!(u128x2[test_v256]: i8x32, u8x32, m8x32, i16x16, u16x16, m16x16, i32x8, u32x8, f32x8, m32x8, i64x4, u64x4, f64x4, m64x4, i128x2, m128x2); // note: m128x2 cannot be constructed from all the other masks bit patterns in here diff --git a/src/api/into_bits/v32.rs b/src/api/into_bits/v32.rs index 743060e4b..42ab4c7d7 100644 --- a/src/api/into_bits/v32.rs +++ b/src/api/into_bits/v32.rs @@ -3,10 +3,10 @@ use crate::v32::*; -impl_from_bits!(i8x4: u8x4, m8x4, i16x2, u16x2, m16x2); -impl_from_bits!(u8x4: i8x4, m8x4, i16x2, u16x2, m16x2); -impl_from_bits!(m8x4: m16x2); +impl_from_bits!(i8x4[test_v32]: u8x4, m8x4, i16x2, u16x2, m16x2); +impl_from_bits!(u8x4[test_v32]: i8x4, m8x4, i16x2, u16x2, m16x2); +impl_from_bits!(m8x4[test_v32]: m16x2); -impl_from_bits!(i16x2: i8x4, u8x4, m8x4, u16x2, m16x2); -impl_from_bits!(u16x2: i8x4, u8x4, m8x4, i16x2, m16x2); +impl_from_bits!(i16x2[test_v32]: i8x4, u8x4, m8x4, u16x2, m16x2); +impl_from_bits!(u16x2[test_v32]: i8x4, u8x4, m8x4, i16x2, m16x2); // note: m16x2 cannot be constructed from all m8x4 bit patterns diff --git a/src/api/into_bits/v512.rs b/src/api/into_bits/v512.rs index a1811831d..dfacaa7eb 100644 --- a/src/api/into_bits/v512.rs +++ b/src/api/into_bits/v512.rs @@ -3,24 +3,24 @@ use crate::v512::*; -impl_from_bits!(i8x64: u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(u8x64: i8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(m8x64: m16x32, m32x16, m64x8, m128x4); +impl_from_bits!(i8x64[test_v512]: u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(u8x64[test_v512]: i8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(m8x64[test_v512]: m16x32, m32x16, m64x8, m128x4); -impl_from_bits!(i16x32: i8x64, u8x64, m8x64, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(u16x32: i8x64, u8x64, m8x64, i16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(m16x32: m32x16, m64x8, m128x4); +impl_from_bits!(i16x32[test_v512]: i8x64, u8x64, m8x64, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(u16x32[test_v512]: i8x64, u8x64, m8x64, i16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(m16x32[test_v512]: m32x16, m64x8, m128x4); -impl_from_bits!(i32x16: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(u32x16: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(f32x16: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(m32x16: m64x8, m128x4); +impl_from_bits!(i32x16[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(u32x16[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(f32x16[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(m32x16[test_v512]: m64x8, m128x4); -impl_from_bits!(i64x8: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(u64x8: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, f64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(f64x8: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, m64x8, i128x4, u128x4, m128x4); -impl_from_bits!(m64x8: m128x4); +impl_from_bits!(i64x8[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, u64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(u64x8[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, f64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(f64x8[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, m64x8, i128x4, u128x4, m128x4); +impl_from_bits!(m64x8[test_v512]: m128x4); -impl_from_bits!(i128x4: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, u128x4, m128x4); -impl_from_bits!(u128x4: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, m128x4); +impl_from_bits!(i128x4[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, u128x4, m128x4); +impl_from_bits!(u128x4[test_v512]: i8x64, u8x64, m8x64, i16x32, u16x32, m16x32, i32x16, u32x16, f32x16, m32x16, i64x8, u64x8, f64x8, m64x8, i128x4, m128x4); // note: m128x4 cannot be constructed from all the other masks bit patterns in here diff --git a/src/api/into_bits/v64.rs b/src/api/into_bits/v64.rs index 326f81e65..4226d89ac 100644 --- a/src/api/into_bits/v64.rs +++ b/src/api/into_bits/v64.rs @@ -3,15 +3,15 @@ use crate::v64::*; -impl_from_bits!(i8x8: u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); -impl_from_bits!(u8x8: i8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); -impl_from_bits!(m8x8: m16x4, m32x2); +impl_from_bits!(i8x8[test_v64]: u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); +impl_from_bits!(u8x8[test_v64]: i8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); +impl_from_bits!(m8x8[test_v64]: m16x4, m32x2); -impl_from_bits!(i16x4: i8x8, u8x8, m8x8, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); -impl_from_bits!(u16x4: i8x8, u8x8, m8x8, i16x4, m16x4, i32x2, u32x2, f32x2, m32x2); -impl_from_bits!(m16x4: m32x2); +impl_from_bits!(i16x4[test_v64]: i8x8, u8x8, m8x8, u16x4, m16x4, i32x2, u32x2, f32x2, m32x2); +impl_from_bits!(u16x4[test_v64]: i8x8, u8x8, m8x8, i16x4, m16x4, i32x2, u32x2, f32x2, m32x2); +impl_from_bits!(m16x4[test_v64]: m32x2); -impl_from_bits!(i32x2: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, u32x2, f32x2, m32x2); -impl_from_bits!(u32x2: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, f32x2, m32x2); -impl_from_bits!(f32x2: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, m32x2); +impl_from_bits!(i32x2[test_v64]: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, u32x2, f32x2, m32x2); +impl_from_bits!(u32x2[test_v64]: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, f32x2, m32x2); +impl_from_bits!(f32x2[test_v64]: i8x8, u8x8, m8x8, i16x4, u16x4, m16x4, i32x2, u32x2, m32x2); // note: m32x2 cannot be constructed from all m16x4 or m8x8 bit patterns diff --git a/src/api/math/float/abs.rs b/src/api/math/float/abs.rs index 4c944bae7..3acc30fd9 100644 --- a/src/api/math/float/abs.rs +++ b/src/api/math/float/abs.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `abs`. macro_rules! impl_math_float_abs { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Absolute value. #[inline] @@ -11,17 +11,19 @@ macro_rules! impl_math_float_abs { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_abs] { - use super::*; - #[test] - fn abs() { - let o = $id::splat(1 as $elem_ty); - assert_eq!(o, o.abs()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_abs] { + use super::*; + #[test] + fn abs() { + let o = $id::splat(1 as $elem_ty); + assert_eq!(o, o.abs()); - let mo = $id::splat(-1 as $elem_ty); - assert_eq!(o, mo.abs()); + let mo = $id::splat(-1 as $elem_ty); + assert_eq!(o, mo.abs()); + } } } } diff --git a/src/api/math/float/cos.rs b/src/api/math/float/cos.rs index ec3bc0c35..1d0e992e0 100644 --- a/src/api/math/float/cos.rs +++ b/src/api/math/float/cos.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `cos`. macro_rules! impl_math_float_cos { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Cosine. #[inline] @@ -11,23 +11,25 @@ macro_rules! impl_math_float_cos { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_cos] { - use super::*; - #[test] - fn cos() { - use $elem_ty::consts::PI; - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let p = $id::splat(PI as $elem_ty); - let ph = $id::splat(PI as $elem_ty / 2.); - let z_r = $id::splat((PI as $elem_ty / 2.).cos()); - let o_r = $id::splat((PI as $elem_ty).cos()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_cos] { + use super::*; + #[test] + fn cos() { + use $elem_ty::consts::PI; + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let p = $id::splat(PI as $elem_ty); + let ph = $id::splat(PI as $elem_ty / 2.); + let z_r = $id::splat((PI as $elem_ty / 2.).cos()); + let o_r = $id::splat((PI as $elem_ty).cos()); - assert_eq!(o, z.cos()); - assert_eq!(z_r, ph.cos()); - assert_eq!(o_r, p.cos()); + assert_eq!(o, z.cos()); + assert_eq!(z_r, ph.cos()); + assert_eq!(o_r, p.cos()); + } } } } diff --git a/src/api/math/float/fma.rs b/src/api/math/float/fma.rs index 3a0c27210..ec8f4e4a0 100644 --- a/src/api/math/float/fma.rs +++ b/src/api/math/float/fma.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `fma`. macro_rules! impl_math_float_fma { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Fused multiply add: `self * y + z` #[inline] @@ -11,30 +11,32 @@ macro_rules! impl_math_float_fma { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_fma] { - use super::*; - #[test] - fn fma() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let t3 = $id::splat(3 as $elem_ty); - let f = $id::splat(4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_fma] { + use super::*; + #[test] + fn fma() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let t3 = $id::splat(3 as $elem_ty); + let f = $id::splat(4 as $elem_ty); - assert_eq!(z, z.fma(z, z)); - assert_eq!(o, o.fma(o, z)); - assert_eq!(o, o.fma(z, o)); - assert_eq!(o, z.fma(o, o)); + assert_eq!(z, z.fma(z, z)); + assert_eq!(o, o.fma(o, z)); + assert_eq!(o, o.fma(z, o)); + assert_eq!(o, z.fma(o, o)); - assert_eq!(t, o.fma(o, o)); - assert_eq!(t, o.fma(t, z)); - assert_eq!(t, t.fma(o, z)); + assert_eq!(t, o.fma(o, o)); + assert_eq!(t, o.fma(t, z)); + assert_eq!(t, t.fma(o, z)); - assert_eq!(f, t.fma(t, z)); - assert_eq!(f, t.fma(o, t)); - assert_eq!(t3, t.fma(o, o)); + assert_eq!(f, t.fma(t, z)); + assert_eq!(f, t.fma(o, t)); + assert_eq!(t3, t.fma(o, o)); + } } } } diff --git a/src/api/math/float/recpre.rs b/src/api/math/float/recpre.rs index 7e1bec378..4a491ddb3 100644 --- a/src/api/math/float/recpre.rs +++ b/src/api/math/float/recpre.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `recpre`. macro_rules! impl_math_float_recpre { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Reciprocal estimate: `~= 1. / self`. /// @@ -12,21 +12,23 @@ macro_rules! impl_math_float_recpre { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_recpre] { - use super::*; - #[test] - fn recpre() { - let tol = $id::splat(2.4e-4 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let error = (o - o.recpre()).abs(); - assert!(error.le(tol).all()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_recpre] { + use super::*; + #[test] + fn recpre() { + let tol = $id::splat(2.4e-4 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let error = (o - o.recpre()).abs(); + assert!(error.le(tol).all()); - let t = $id::splat(2 as $elem_ty); - let e = 0.5; - let error = (e - t.recpre()).abs(); - assert!(error.le(tol).all()); + let t = $id::splat(2 as $elem_ty); + let e = 0.5; + let error = (e - t.recpre()).abs(); + assert!(error.le(tol).all()); + } } } } diff --git a/src/api/math/float/rsqrte.rs b/src/api/math/float/rsqrte.rs index f58a72843..72216cf3e 100644 --- a/src/api/math/float/rsqrte.rs +++ b/src/api/math/float/rsqrte.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `rsqrte`. macro_rules! impl_math_float_rsqrte { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Reciprocal square-root estimate: `~= 1. / self.sqrt()`. /// @@ -15,22 +15,24 @@ macro_rules! impl_math_float_rsqrte { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_rsqrte] { - use super::*; - #[test] - fn rsqrte() { - use $elem_ty::consts::SQRT_2; - let tol = $id::splat(2.4e-4 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let error = (o - o.rsqrte()).abs(); - assert!(error.le(tol).all()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_rsqrte] { + use super::*; + #[test] + fn rsqrte() { + use $elem_ty::consts::SQRT_2; + let tol = $id::splat(2.4e-4 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let error = (o - o.rsqrte()).abs(); + assert!(error.le(tol).all()); - let t = $id::splat(2 as $elem_ty); - let e = 1. / SQRT_2; - let error = (e - t.rsqrte()).abs(); - assert!(error.le(tol).all()); + let t = $id::splat(2 as $elem_ty); + let e = 1. / SQRT_2; + let error = (e - t.rsqrte()).abs(); + assert!(error.le(tol).all()); + } } } } diff --git a/src/api/math/float/sin.rs b/src/api/math/float/sin.rs index 4152b1c1f..19b1d76c0 100644 --- a/src/api/math/float/sin.rs +++ b/src/api/math/float/sin.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `sin`. macro_rules! impl_math_float_sin { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Sine. #[inline] @@ -11,22 +11,24 @@ macro_rules! impl_math_float_sin { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_sin] { - use super::*; - #[test] - fn sin() { - use $elem_ty::consts::PI; - let z = $id::splat(0 as $elem_ty); - let p = $id::splat(PI as $elem_ty); - let ph = $id::splat(PI as $elem_ty / 2.); - let o_r = $id::splat((PI as $elem_ty / 2.).sin()); - let z_r = $id::splat((PI as $elem_ty).sin()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_sin] { + use super::*; + #[test] + fn sin() { + use $elem_ty::consts::PI; + let z = $id::splat(0 as $elem_ty); + let p = $id::splat(PI as $elem_ty); + let ph = $id::splat(PI as $elem_ty / 2.); + let o_r = $id::splat((PI as $elem_ty / 2.).sin()); + let z_r = $id::splat((PI as $elem_ty).sin()); - assert_eq!(z, z.sin()); - assert_eq!(o_r, ph.sin()); - assert_eq!(z_r, p.sin()); + assert_eq!(z, z.sin()); + assert_eq!(o_r, ph.sin()); + assert_eq!(z_r, p.sin()); + } } } } diff --git a/src/api/math/float/sqrt.rs b/src/api/math/float/sqrt.rs index fcc2a817e..76c7f8c69 100644 --- a/src/api/math/float/sqrt.rs +++ b/src/api/math/float/sqrt.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `sqrt`. macro_rules! impl_math_float_sqrt { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { #[inline] pub fn sqrt(self) -> Self { @@ -10,22 +10,24 @@ macro_rules! impl_math_float_sqrt { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_sqrt] { - use super::*; - #[test] - fn sqrt() { - use $elem_ty::consts::SQRT_2; - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - assert_eq!(z, z.sqrt()); - assert_eq!(o, o.sqrt()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_sqrt] { + use super::*; + #[test] + fn sqrt() { + use $elem_ty::consts::SQRT_2; + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + assert_eq!(z, z.sqrt()); + assert_eq!(o, o.sqrt()); - let t = $id::splat(2 as $elem_ty); - let e = $id::splat(SQRT_2); - assert_eq!(e, t.sqrt()); + let t = $id::splat(2 as $elem_ty); + let e = $id::splat(SQRT_2); + assert_eq!(e, t.sqrt()); + } } } } diff --git a/src/api/math/float/sqrte.rs b/src/api/math/float/sqrte.rs index 9bee5501e..024eebe31 100644 --- a/src/api/math/float/sqrte.rs +++ b/src/api/math/float/sqrte.rs @@ -1,7 +1,7 @@ //! Implements vertical (lane-wise) floating-point `sqrte`. macro_rules! impl_math_float_sqrte { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Square-root estimate. /// @@ -13,28 +13,30 @@ macro_rules! impl_math_float_sqrte { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _math_sqrte] { - use super::*; - #[test] - fn sqrte() { - use $elem_ty::consts::SQRT_2; - let tol = $id::splat(2.4e-4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _math_sqrte] { + use super::*; + #[test] + fn sqrte() { + use $elem_ty::consts::SQRT_2; + let tol = $id::splat(2.4e-4 as $elem_ty); - let z = $id::splat(0 as $elem_ty); - let error = (z - z.sqrte()).abs(); - assert!(error.le(tol).all()); + let z = $id::splat(0 as $elem_ty); + let error = (z - z.sqrte()).abs(); + assert!(error.le(tol).all()); - let o = $id::splat(1 as $elem_ty); - let error = (o - o.sqrte()).abs(); - assert!(error.le(tol).all()); + let o = $id::splat(1 as $elem_ty); + let error = (o - o.sqrte()).abs(); + assert!(error.le(tol).all()); - let t = $id::splat(2 as $elem_ty); - let e = $id::splat(SQRT_2 as $elem_ty); - let error = (e - t.sqrte()).abs(); + let t = $id::splat(2 as $elem_ty); + let e = $id::splat(SQRT_2 as $elem_ty); + let error = (e - t.sqrte()).abs(); - assert!(error.le(tol).all()); + assert!(error.le(tol).all()); + } } } } diff --git a/src/api/minimal/iuf.rs b/src/api/minimal/iuf.rs index 0c19c0601..d5a20435a 100644 --- a/src/api/minimal/iuf.rs +++ b/src/api/minimal/iuf.rs @@ -1,7 +1,7 @@ //! Minimal API of signed integer, unsigned integer, and floating-point vectors. macro_rules! impl_minimal_iuf { - ([$elem_ty:ident; $elem_count:expr]: $id:ident | + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $($elem_name:ident),+ | $(#[$doc:meta])*) => { @@ -91,55 +91,59 @@ macro_rules! impl_minimal_iuf { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _minimal] { - use super::*; - #[test] - fn minimal() { - // lanes: - assert_eq!($elem_count, $id::lanes()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _minimal] { + use super::*; + #[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) }); - } + // 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)); + // 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)); + 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)); + } } } - } - #[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()); - } - #[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); + #[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()); + } + #[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); + } } } } diff --git a/src/api/minimal/mask.rs b/src/api/minimal/mask.rs index 57677d7f8..07fcf8737 100644 --- a/src/api/minimal/mask.rs +++ b/src/api/minimal/mask.rs @@ -1,7 +1,7 @@ //! Minimal API of mask vectors. macro_rules! impl_minimal_mask { - ([$elem_ty:ident; $elem_count:expr]: $id:ident | $ielem_ty:ident | + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | $ielem_ty:ident | $($elem_name:ident),+ | $(#[$doc:meta])*) => { @@ -97,53 +97,55 @@ macro_rules! impl_minimal_mask { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _minimal] { - use super::*; - #[test] - fn minimal() { - // TODO: test new + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _minimal] { + use super::*; + #[test] + fn minimal() { + // TODO: test new - // lanes: - assert_eq!($elem_count, $id::lanes()); + // lanes: + assert_eq!($elem_count, $id::lanes()); - // splat and extract / extract_unchecked: - let vec = $id::splat(true); - for i in 0..$id::lanes() { - assert_eq!(true, vec.extract(i)); - assert_eq!(true, unsafe { vec.extract_unchecked(i) }); - } + // splat and extract / extract_unchecked: + let vec = $id::splat(true); + for i in 0..$id::lanes() { + assert_eq!(true, vec.extract(i)); + assert_eq!(true, unsafe { vec.extract_unchecked(i) }); + } - // replace / replace_unchecked - let new_vec = vec.replace(0, false); - for i in 0..$id::lanes() { - if i == 0 { - assert_eq!(false, new_vec.extract(i)); - } else { - assert_eq!(true, new_vec.extract(i)); + // replace / replace_unchecked + let new_vec = vec.replace(0, false); + for i in 0..$id::lanes() { + if i == 0 { + assert_eq!(false, new_vec.extract(i)); + } else { + assert_eq!(true, new_vec.extract(i)); + } } - } - let new_vec = unsafe { vec.replace_unchecked(0, false) }; - for i in 0..$id::lanes() { - if i == 0 { - assert_eq!(false, new_vec.extract(i)); - } else { - assert_eq!(true, new_vec.extract(i)); + let new_vec = unsafe { vec.replace_unchecked(0, false) }; + for i in 0..$id::lanes() { + if i == 0 { + assert_eq!(false, new_vec.extract(i)); + } else { + assert_eq!(true, new_vec.extract(i)); + } } } - } - #[test] - #[should_panic] - fn extract_panic_oob() { - let vec = $id::splat(false); - let _ = vec.extract($id::lanes()); - } - #[test] - #[should_panic] - fn replace_panic_oob() { - let vec = $id::splat(false); - let _ = vec.replace($id::lanes(), true); + #[test] + #[should_panic] + fn extract_panic_oob() { + let vec = $id::splat(false); + let _ = vec.extract($id::lanes()); + } + #[test] + #[should_panic] + fn replace_panic_oob() { + let vec = $id::splat(false); + let _ = vec.replace($id::lanes(), true); + } } } } diff --git a/src/api/ops/scalar_arithmetic.rs b/src/api/ops/scalar_arithmetic.rs index 122d8f594..8c6778a0c 100644 --- a/src/api/ops/scalar_arithmetic.rs +++ b/src/api/ops/scalar_arithmetic.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector-scalar / scalar-vector arithmetic operations. macro_rules! impl_ops_scalar_arithmetic { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::ops::Add<$elem_ty> for $id { type Output = Self; #[inline] @@ -112,87 +112,89 @@ macro_rules! impl_ops_scalar_arithmetic { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_scalar_arith] { - use super::*; - #[test] - fn ops_scalar_arithmetic() { - let zi = 0 as $elem_ty; - let oi = 1 as $elem_ty; - let ti = 2 as $elem_ty; - let fi = 4 as $elem_ty; - let z = $id::splat(zi); - let o = $id::splat(oi); - let t = $id::splat(ti); - let f = $id::splat(fi); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_scalar_arith] { + use super::*; + #[test] + fn ops_scalar_arithmetic() { + let zi = 0 as $elem_ty; + let oi = 1 as $elem_ty; + let ti = 2 as $elem_ty; + let fi = 4 as $elem_ty; + let z = $id::splat(zi); + let o = $id::splat(oi); + let t = $id::splat(ti); + let f = $id::splat(fi); - // add - assert_eq!(zi + z, z); - assert_eq!(z + zi, z); - assert_eq!(oi + z, o); - assert_eq!(o + zi, o); - assert_eq!(ti + z, t); - assert_eq!(t + zi, t); - assert_eq!(ti + t, f); - assert_eq!(t + ti, f); - // sub - assert_eq!(zi - z, z); - assert_eq!(z - zi, z); - assert_eq!(oi - z, o); - assert_eq!(o - zi, o); - assert_eq!(ti - z, t); - assert_eq!(t - zi, t); - assert_eq!(fi - t, t); - assert_eq!(f - ti, t); - assert_eq!(f - o - o, t); - assert_eq!(f - oi - oi, t); - // mul - assert_eq!(zi * z, z); - assert_eq!(z * zi, z); - assert_eq!(zi * o, z); - assert_eq!(z * oi, z); - assert_eq!(zi * t, z); - assert_eq!(z * ti, z); - assert_eq!(oi * t, t); - assert_eq!(o * ti, t); - assert_eq!(ti * t, f); - assert_eq!(t * ti, f); - // div - assert_eq!(zi / o, z); - assert_eq!(z / oi, z); - assert_eq!(ti / o, t); - assert_eq!(t / oi, t); - assert_eq!(fi / o, f); - assert_eq!(f / oi, f); - assert_eq!(ti / t, o); - assert_eq!(t / ti, o); - assert_eq!(fi / t, t); - assert_eq!(f / ti, t); - // rem - assert_eq!(oi % o, z); - assert_eq!(o % oi, z); - assert_eq!(fi % t, z); - assert_eq!(f % ti, z); + // add + assert_eq!(zi + z, z); + assert_eq!(z + zi, z); + assert_eq!(oi + z, o); + assert_eq!(o + zi, o); + assert_eq!(ti + z, t); + assert_eq!(t + zi, t); + assert_eq!(ti + t, f); + assert_eq!(t + ti, f); + // sub + assert_eq!(zi - z, z); + assert_eq!(z - zi, z); + assert_eq!(oi - z, o); + assert_eq!(o - zi, o); + assert_eq!(ti - z, t); + assert_eq!(t - zi, t); + assert_eq!(fi - t, t); + assert_eq!(f - ti, t); + assert_eq!(f - o - o, t); + assert_eq!(f - oi - oi, t); + // mul + assert_eq!(zi * z, z); + assert_eq!(z * zi, z); + assert_eq!(zi * o, z); + assert_eq!(z * oi, z); + assert_eq!(zi * t, z); + assert_eq!(z * ti, z); + assert_eq!(oi * t, t); + assert_eq!(o * ti, t); + assert_eq!(ti * t, f); + assert_eq!(t * ti, f); + // div + assert_eq!(zi / o, z); + assert_eq!(z / oi, z); + assert_eq!(ti / o, t); + assert_eq!(t / oi, t); + assert_eq!(fi / o, f); + assert_eq!(f / oi, f); + assert_eq!(ti / t, o); + assert_eq!(t / ti, o); + assert_eq!(fi / t, t); + assert_eq!(f / ti, t); + // rem + assert_eq!(oi % o, z); + assert_eq!(o % oi, z); + assert_eq!(fi % t, z); + assert_eq!(f % ti, z); - { - let mut v = z; - assert_eq!(v, z); - v += oi; // add_assign - assert_eq!(v, o); - v -= oi; // sub_assign - assert_eq!(v, z); - v = t; - v *= oi; // mul_assign - assert_eq!(v, t); - v *= ti; - assert_eq!(v, f); - v /= oi; // div_assign - assert_eq!(v, f); - v /= ti; - assert_eq!(v, t); - v %= ti; // rem_assign - assert_eq!(v, z); + { + let mut v = z; + assert_eq!(v, z); + v += oi; // add_assign + assert_eq!(v, o); + v -= oi; // sub_assign + assert_eq!(v, z); + v = t; + v *= oi; // mul_assign + assert_eq!(v, t); + v *= ti; + assert_eq!(v, f); + v /= oi; // div_assign + assert_eq!(v, f); + v /= ti; + assert_eq!(v, t); + v %= ti; // rem_assign + assert_eq!(v, z); + } } } } diff --git a/src/api/ops/scalar_bitwise.rs b/src/api/ops/scalar_bitwise.rs index 3e182643b..1b542f5ea 100644 --- a/src/api/ops/scalar_bitwise.rs +++ b/src/api/ops/scalar_bitwise.rs @@ -3,7 +3,7 @@ macro_rules! impl_ops_scalar_bitwise { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl ::ops::BitXor<$elem_ty> for $id { @@ -70,91 +70,92 @@ macro_rules! impl_ops_scalar_bitwise { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_scalar_bitwise] { - use super::*; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_scalar_bitwise] { + use super::*; - #[test] - fn ops_scalar_bitwise() { - let zi = 0 as $elem_ty; - let oi = 1 as $elem_ty; - let ti = 2 as $elem_ty; - let z = $id::splat(zi); - let o = $id::splat(oi); - let t = $id::splat(ti); + #[test] + fn ops_scalar_bitwise() { + let zi = 0 as $elem_ty; + let oi = 1 as $elem_ty; + let ti = 2 as $elem_ty; + let z = $id::splat(zi); + let o = $id::splat(oi); + let t = $id::splat(ti); - // BitAnd: - assert_eq!(oi & o, o); - assert_eq!(o & oi, o); - assert_eq!(oi & z, z); - assert_eq!(o & zi, z); - assert_eq!(zi & o, z); - assert_eq!(z & oi, z); - assert_eq!(zi & z, z); - assert_eq!(z & zi, z); + // BitAnd: + assert_eq!(oi & o, o); + assert_eq!(o & oi, o); + assert_eq!(oi & z, z); + assert_eq!(o & zi, z); + assert_eq!(zi & o, z); + assert_eq!(z & oi, z); + assert_eq!(zi & z, z); + assert_eq!(z & zi, z); - assert_eq!(ti & t, t); - assert_eq!(t & ti, t); - assert_eq!(ti & o, z); - assert_eq!(t & oi, z); - assert_eq!(oi & t, z); - assert_eq!(o & ti, z); + assert_eq!(ti & t, t); + assert_eq!(t & ti, t); + assert_eq!(ti & o, z); + assert_eq!(t & oi, z); + assert_eq!(oi & t, z); + assert_eq!(o & ti, z); - // BitOr: - assert_eq!(oi | o, o); - assert_eq!(o | oi, o); - assert_eq!(oi | z, o); - assert_eq!(o | zi, o); - assert_eq!(zi | o, o); - assert_eq!(z | oi, o); - assert_eq!(zi | z, z); - assert_eq!(z | zi, z); + // BitOr: + assert_eq!(oi | o, o); + assert_eq!(o | oi, o); + assert_eq!(oi | z, o); + assert_eq!(o | zi, o); + assert_eq!(zi | o, o); + assert_eq!(z | oi, o); + assert_eq!(zi | z, z); + assert_eq!(z | zi, z); - assert_eq!(ti | t, t); - assert_eq!(t | ti, t); - assert_eq!(zi | t, t); - assert_eq!(z | ti, t); - assert_eq!(ti | z, t); - assert_eq!(t | zi, t); + assert_eq!(ti | t, t); + assert_eq!(t | ti, t); + assert_eq!(zi | t, t); + assert_eq!(z | ti, t); + assert_eq!(ti | z, t); + assert_eq!(t | zi, t); - // BitXOR: - assert_eq!(oi ^ o, z); - assert_eq!(o ^ oi, z); - assert_eq!(zi ^ z, z); - assert_eq!(z ^ zi, z); - assert_eq!(zi ^ o, o); - assert_eq!(z ^ oi, o); - assert_eq!(oi ^ z, o); - assert_eq!(o ^ zi, o); + // BitXOR: + assert_eq!(oi ^ o, z); + assert_eq!(o ^ oi, z); + assert_eq!(zi ^ z, z); + assert_eq!(z ^ zi, z); + assert_eq!(zi ^ o, o); + assert_eq!(z ^ oi, o); + assert_eq!(oi ^ z, o); + assert_eq!(o ^ zi, o); - assert_eq!(ti ^ t, z); - assert_eq!(t ^ ti, z); - assert_eq!(ti ^ z, t); - assert_eq!(t ^ zi, t); - assert_eq!(zi ^ t, t); - assert_eq!(z ^ ti, t); + assert_eq!(ti ^ t, z); + assert_eq!(t ^ ti, z); + assert_eq!(ti ^ z, t); + assert_eq!(t ^ zi, t); + assert_eq!(zi ^ t, t); + assert_eq!(z ^ ti, t); - { - // AndAssign: - let mut v = o; - v &= ti; - assert_eq!(v, z); - } - { - // OrAssign: - let mut v = z; - v |= oi; - assert_eq!(v, o); - } - { - // XORAssign: - let mut v = z; - v ^= oi; - assert_eq!(v, o); + { + // AndAssign: + let mut v = o; + v &= ti; + assert_eq!(v, z); + } + { + // OrAssign: + let mut v = z; + v |= oi; + assert_eq!(v, o); + } + { + // XORAssign: + let mut v = z; + v ^= oi; + assert_eq!(v, o); + } } } - } } }; diff --git a/src/api/ops/scalar_mask_bitwise.rs b/src/api/ops/scalar_mask_bitwise.rs index b615f4be5..e4726c01a 100644 --- a/src/api/ops/scalar_mask_bitwise.rs +++ b/src/api/ops/scalar_mask_bitwise.rs @@ -3,7 +3,7 @@ macro_rules! impl_ops_scalar_mask_bitwise { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl ::ops::BitXor for $id { @@ -70,66 +70,68 @@ macro_rules! impl_ops_scalar_mask_bitwise { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_scalar_mask_bitwise] { - use super::*; - #[test] - fn ops_scalar_mask_bitwise() { - let ti = true; - let fi = false; - let t = $id::splat(ti); - let f = $id::splat(fi); - assert!(t != f); - assert!(!(t == f)); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_scalar_mask_bitwise] { + use super::*; + #[test] + fn ops_scalar_mask_bitwise() { + let ti = true; + let fi = false; + let t = $id::splat(ti); + let f = $id::splat(fi); + assert!(t != f); + assert!(!(t == f)); - // BitAnd: - assert_eq!(ti & f, f); - assert_eq!(t & fi, f); - assert_eq!(fi & t, f); - assert_eq!(f & ti, f); - assert_eq!(ti & t, t); - assert_eq!(t & ti, t); - assert_eq!(fi & f, f); - assert_eq!(f & fi, f); + // BitAnd: + assert_eq!(ti & f, f); + assert_eq!(t & fi, f); + assert_eq!(fi & t, f); + assert_eq!(f & ti, f); + assert_eq!(ti & t, t); + assert_eq!(t & ti, t); + assert_eq!(fi & f, f); + assert_eq!(f & fi, f); - // BitOr: - assert_eq!(ti | f, t); - assert_eq!(t | fi, t); - assert_eq!(fi | t, t); - assert_eq!(f | ti, t); - assert_eq!(ti | t, t); - assert_eq!(t | ti, t); - assert_eq!(fi | f, f); - assert_eq!(f | fi, f); + // BitOr: + assert_eq!(ti | f, t); + assert_eq!(t | fi, t); + assert_eq!(fi | t, t); + assert_eq!(f | ti, t); + assert_eq!(ti | t, t); + assert_eq!(t | ti, t); + assert_eq!(fi | f, f); + assert_eq!(f | fi, f); - // BitXOR: - assert_eq!(ti ^ f, t); - assert_eq!(t ^ fi, t); - assert_eq!(fi ^ t, t); - assert_eq!(f ^ ti, t); - assert_eq!(ti ^ t, f); - assert_eq!(t ^ ti, f); - assert_eq!(fi ^ f, f); - assert_eq!(f ^ fi, f); + // BitXOR: + assert_eq!(ti ^ f, t); + assert_eq!(t ^ fi, t); + assert_eq!(fi ^ t, t); + assert_eq!(f ^ ti, t); + assert_eq!(ti ^ t, f); + assert_eq!(t ^ ti, f); + assert_eq!(fi ^ f, f); + assert_eq!(f ^ fi, f); - { - // AndAssign: - let mut v = f; - v &= ti; - assert_eq!(v, f); - } - { - // OrAssign: - let mut v = f; - v |= ti; - assert_eq!(v, t); - } - { - // XORAssign: - let mut v = f; - v ^= ti; - assert_eq!(v, t); + { + // AndAssign: + let mut v = f; + v &= ti; + assert_eq!(v, f); + } + { + // OrAssign: + let mut v = f; + v |= ti; + assert_eq!(v, t); + } + { + // XORAssign: + let mut v = f; + v ^= ti; + assert_eq!(v, t); + } } } } diff --git a/src/api/ops/scalar_rotates.rs b/src/api/ops/scalar_rotates.rs index b2601c059..1bd0d6377 100644 --- a/src/api/ops/scalar_rotates.rs +++ b/src/api/ops/scalar_rotates.rs @@ -2,7 +2,7 @@ #![allow(unused)] macro_rules! impl_ops_scalar_rotates { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Shifts the bits of each lane to the left by the specified amount in /// the corresponding lane of `n`, wrapping the truncated bits to @@ -35,6 +35,8 @@ macro_rules! impl_ops_scalar_rotates { }; } +// FIXME: never used +// https://github.com/rust-lang-nursery/packed_simd/issues/63 #[cfg(test)] macro_rules! test_scalar_rotate_ops { ($id:ident, $elem_ty:ident) => { diff --git a/src/api/ops/scalar_shifts.rs b/src/api/ops/scalar_shifts.rs index 14b1fb79a..3d78dc9cb 100644 --- a/src/api/ops/scalar_shifts.rs +++ b/src/api/ops/scalar_shifts.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector-scalar shifts operations. macro_rules! impl_ops_scalar_shifts { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::ops::Shl for $id { type Output = Self; #[inline] @@ -29,68 +29,70 @@ macro_rules! impl_ops_scalar_shifts { *self = *self >> other; } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_scalar_shifts] { - use super::*; - #[test] - #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), - allow(unreachable_code, unused_variables))] - fn ops_scalar_shifts() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let f = $id::splat(4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_scalar_shifts] { + use super::*; + #[test] + #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), + allow(unreachable_code, unused_variables))] + fn ops_scalar_shifts() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); - { - let zi = 0 as u32; - let oi = 1 as u32; - let ti = 2 as u32; - let maxi = (mem::size_of::<$elem_ty>() * 8 - 1) as u32; + { + let zi = 0 as u32; + let oi = 1 as u32; + let ti = 2 as u32; + let maxi = (mem::size_of::<$elem_ty>() * 8 - 1) as u32; - // shr - assert_eq!(z >> zi, z); - assert_eq!(z >> oi, z); - assert_eq!(z >> ti, z); - assert_eq!(z >> ti, z); + // shr + assert_eq!(z >> zi, z); + assert_eq!(z >> oi, z); + assert_eq!(z >> ti, z); + assert_eq!(z >> ti, z); - #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { - // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/13 - return; - } + #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { + // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/13 + return; + } - assert_eq!(o >> zi, o); - assert_eq!(t >> zi, t); - assert_eq!(f >> zi, f); - assert_eq!(f >> maxi, z); + assert_eq!(o >> zi, o); + assert_eq!(t >> zi, t); + assert_eq!(f >> zi, f); + assert_eq!(f >> maxi, z); - assert_eq!(o >> oi, z); - assert_eq!(t >> oi, o); - assert_eq!(t >> ti, z); - assert_eq!(f >> oi, t); - assert_eq!(f >> ti, o); - assert_eq!(f >> maxi, z); + assert_eq!(o >> oi, z); + assert_eq!(t >> oi, o); + assert_eq!(t >> ti, z); + assert_eq!(f >> oi, t); + assert_eq!(f >> ti, o); + assert_eq!(f >> maxi, z); - // shl - assert_eq!(z << zi, z); - assert_eq!(o << zi, o); - assert_eq!(t << zi, t); - assert_eq!(f << zi, f); - assert_eq!(f << maxi, z); + // shl + assert_eq!(z << zi, z); + assert_eq!(o << zi, o); + assert_eq!(t << zi, t); + assert_eq!(f << zi, f); + assert_eq!(f << maxi, z); - assert_eq!(o << oi, t); - assert_eq!(o << ti, f); - assert_eq!(t << oi, f); + assert_eq!(o << oi, t); + assert_eq!(o << ti, f); + assert_eq!(t << oi, f); - { // shr_assign - let mut v = o; - v >>= oi; - assert_eq!(v, z); - } - { // shl_assign - let mut v = o; - v <<= oi; - assert_eq!(v, t); + { // shr_assign + let mut v = o; + v >>= oi; + assert_eq!(v, z); + } + { // shl_assign + let mut v = o; + v <<= oi; + assert_eq!(v, t); + } } } } diff --git a/src/api/ops/vector_arithmetic.rs b/src/api/ops/vector_arithmetic.rs index 5c4beb957..2838c78a7 100644 --- a/src/api/ops/vector_arithmetic.rs +++ b/src/api/ops/vector_arithmetic.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector-vector arithmetic operations. macro_rules! impl_ops_vector_arithmetic { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::ops::Add for $id { type Output = Self; #[inline] @@ -82,62 +82,64 @@ macro_rules! impl_ops_vector_arithmetic { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_arith] { - use super::*; - #[test] - fn ops_vector_arithmetic() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let f = $id::splat(4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_arith] { + use super::*; + #[test] + fn ops_vector_arithmetic() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); - // add - assert_eq!(z + z, z); - assert_eq!(o + z, o); - assert_eq!(t + z, t); - assert_eq!(t + t, f); - // sub - assert_eq!(z - z, z); - assert_eq!(o - z, o); - assert_eq!(t - z, t); - assert_eq!(f - t, t); - assert_eq!(f - o - o, t); - // mul - assert_eq!(z * z, z); - assert_eq!(z * o, z); - assert_eq!(z * t, z); - assert_eq!(o * t, t); - assert_eq!(t * t, f); - // div - assert_eq!(z / o, z); - assert_eq!(t / o, t); - assert_eq!(f / o, f); - assert_eq!(t / t, o); - assert_eq!(f / t, t); - // rem - assert_eq!(o % o, z); - assert_eq!(f % t, z); + // add + assert_eq!(z + z, z); + assert_eq!(o + z, o); + assert_eq!(t + z, t); + assert_eq!(t + t, f); + // sub + assert_eq!(z - z, z); + assert_eq!(o - z, o); + assert_eq!(t - z, t); + assert_eq!(f - t, t); + assert_eq!(f - o - o, t); + // mul + assert_eq!(z * z, z); + assert_eq!(z * o, z); + assert_eq!(z * t, z); + assert_eq!(o * t, t); + assert_eq!(t * t, f); + // div + assert_eq!(z / o, z); + assert_eq!(t / o, t); + assert_eq!(f / o, f); + assert_eq!(t / t, o); + assert_eq!(f / t, t); + // rem + assert_eq!(o % o, z); + assert_eq!(f % t, z); - { - let mut v = z; - assert_eq!(v, z); - v += o; // add_assign - assert_eq!(v, o); - v -= o; // sub_assign - assert_eq!(v, z); - v = t; - v *= o; // mul_assign - assert_eq!(v, t); - v *= t; - assert_eq!(v, f); - v /= o; // div_assign - assert_eq!(v, f); - v /= t; - assert_eq!(v, t); - v %= t; // rem_assign - assert_eq!(v, z); + { + let mut v = z; + assert_eq!(v, z); + v += o; // add_assign + assert_eq!(v, o); + v -= o; // sub_assign + assert_eq!(v, z); + v = t; + v *= o; // mul_assign + assert_eq!(v, t); + v *= t; + assert_eq!(v, f); + v /= o; // div_assign + assert_eq!(v, f); + v /= t; + assert_eq!(v, t); + v %= t; // rem_assign + assert_eq!(v, z); + } } } } diff --git a/src/api/ops/vector_bitwise.rs b/src/api/ops/vector_bitwise.rs index 6d6681353..ab8e06ad0 100644 --- a/src/api/ops/vector_bitwise.rs +++ b/src/api/ops/vector_bitwise.rs @@ -3,7 +3,7 @@ macro_rules! impl_ops_vector_bitwise { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl ::ops::Not for $id { @@ -56,69 +56,71 @@ macro_rules! impl_ops_vector_bitwise { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_bitwise] { - use super::*; - #[test] - fn ops_vector_bitwise() { + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_bitwise] { + use super::*; + #[test] + fn ops_vector_bitwise() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let m = $id::splat(!z.extract(0)); + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let m = $id::splat(!z.extract(0)); - // Not: - assert_eq!(!z, m); - assert_eq!(!m, z); + // Not: + assert_eq!(!z, m); + assert_eq!(!m, z); - // BitAnd: - assert_eq!(o & o, o); - assert_eq!(o & z, z); - assert_eq!(z & o, z); - assert_eq!(z & z, z); + // BitAnd: + assert_eq!(o & o, o); + assert_eq!(o & z, z); + assert_eq!(z & o, z); + assert_eq!(z & z, z); - assert_eq!(t & t, t); - assert_eq!(t & o, z); - assert_eq!(o & t, z); + assert_eq!(t & t, t); + assert_eq!(t & o, z); + assert_eq!(o & t, z); - // BitOr: - assert_eq!(o | o, o); - assert_eq!(o | z, o); - assert_eq!(z | o, o); - assert_eq!(z | z, z); + // BitOr: + assert_eq!(o | o, o); + assert_eq!(o | z, o); + assert_eq!(z | o, o); + assert_eq!(z | z, z); - assert_eq!(t | t, t); - assert_eq!(z | t, t); - assert_eq!(t | z, t); + assert_eq!(t | t, t); + assert_eq!(z | t, t); + assert_eq!(t | z, t); - // BitXOR: - assert_eq!(o ^ o, z); - assert_eq!(z ^ z, z); - assert_eq!(z ^ o, o); - assert_eq!(o ^ z, o); + // BitXOR: + assert_eq!(o ^ o, z); + assert_eq!(z ^ z, z); + assert_eq!(z ^ o, o); + assert_eq!(o ^ z, o); - assert_eq!(t ^ t, z); - assert_eq!(t ^ z, t); - assert_eq!(z ^ t, t); + assert_eq!(t ^ t, z); + assert_eq!(t ^ z, t); + assert_eq!(z ^ t, t); - { - // AndAssign: - let mut v = o; - v &= t; - assert_eq!(v, z); - } - { - // OrAssign: - let mut v = z; - v |= o; - assert_eq!(v, o); - } - { - // XORAssign: - let mut v = z; - v ^= o; - assert_eq!(v, o); + { + // AndAssign: + let mut v = o; + v &= t; + assert_eq!(v, z); + } + { + // OrAssign: + let mut v = z; + v |= o; + assert_eq!(v, o); + } + { + // XORAssign: + let mut v = z; + v ^= o; + assert_eq!(v, o); + } } } } diff --git a/src/api/ops/vector_float_min_max.rs b/src/api/ops/vector_float_min_max.rs index 585c6101d..7f7d9a0e4 100644 --- a/src/api/ops/vector_float_min_max.rs +++ b/src/api/ops/vector_float_min_max.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector `min` and `max` for floating-point vectors. macro_rules! impl_ops_vector_float_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Minimum of two vectors. /// @@ -23,43 +23,45 @@ macro_rules! impl_ops_vector_float_min_max { unsafe { Simd(simd_fmax(self.0, x.0)) } } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_min_max] { - use super::*; - #[test] - fn min_max() { - let n = $elem_ty::NAN; - let o = $id::splat(1. as $elem_ty); - let t = $id::splat(2. as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_min_max] { + use super::*; + #[test] + fn min_max() { + let n = $elem_ty::NAN; + let o = $id::splat(1. as $elem_ty); + let t = $id::splat(2. as $elem_ty); - let mut m = o; // [1., 2., 1., 2., ...] - let mut on = o; - for i in 0..$id::lanes() { - if i % 2 == 0 { - m = m.replace(i, 2. as $elem_ty); - on = on.replace(i, n); + let mut m = o; // [1., 2., 1., 2., ...] + let mut on = o; + for i in 0..$id::lanes() { + if i % 2 == 0 { + m = m.replace(i, 2. as $elem_ty); + on = on.replace(i, n); + } } - } - assert_eq!(o.min(t), o); - assert_eq!(t.min(o), o); - assert_eq!(m.min(o), o); - assert_eq!(o.min(m), o); - assert_eq!(m.min(t), m); - assert_eq!(t.min(m), m); + assert_eq!(o.min(t), o); + assert_eq!(t.min(o), o); + assert_eq!(m.min(o), o); + assert_eq!(o.min(m), o); + assert_eq!(m.min(t), m); + assert_eq!(t.min(m), m); - assert_eq!(o.max(t), t); - assert_eq!(t.max(o), t); - assert_eq!(m.max(o), m); - assert_eq!(o.max(m), m); - assert_eq!(m.max(t), t); - assert_eq!(t.max(m), t); + assert_eq!(o.max(t), t); + assert_eq!(t.max(o), t); + assert_eq!(m.max(o), m); + assert_eq!(o.max(m), m); + assert_eq!(m.max(t), t); + assert_eq!(t.max(m), t); - assert_eq!(on.min(o), o); - assert_eq!(o.min(on), o); - assert_eq!(on.max(o), o); - assert_eq!(o.max(on), o); + assert_eq!(on.min(o), o); + assert_eq!(o.min(on), o); + assert_eq!(on.max(o), o); + assert_eq!(o.max(on), o); + } } } } diff --git a/src/api/ops/vector_int_min_max.rs b/src/api/ops/vector_int_min_max.rs index e75eb759f..6c2822cff 100644 --- a/src/api/ops/vector_int_min_max.rs +++ b/src/api/ops/vector_int_min_max.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector `min` and `max` for integer vectors. macro_rules! impl_ops_vector_int_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Minimum of two vectors. /// @@ -21,7 +21,7 @@ macro_rules! impl_ops_vector_int_min_max { self.gt(x).select(self, x) } } - #[cfg(test)] + test_if!{$test_tt: interpolate_idents! { mod [$id _ops_vector_min_max] { use super::*; @@ -52,5 +52,6 @@ macro_rules! impl_ops_vector_int_min_max { } } } + } }; } diff --git a/src/api/ops/vector_mask_bitwise.rs b/src/api/ops/vector_mask_bitwise.rs index effa96acd..fca3a7016 100644 --- a/src/api/ops/vector_mask_bitwise.rs +++ b/src/api/ops/vector_mask_bitwise.rs @@ -3,7 +3,7 @@ macro_rules! impl_ops_vector_mask_bitwise { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl ::ops::Not for $id { @@ -56,56 +56,58 @@ macro_rules! impl_ops_vector_mask_bitwise { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_mask_bitwise] { - use super::*; - #[test] - fn ops_vector_mask_bitwise() { - let t = $id::splat(true); - let f = $id::splat(false); - assert!(t != f); - assert!(!(t == f)); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_mask_bitwise] { + use super::*; + #[test] + fn ops_vector_mask_bitwise() { + let t = $id::splat(true); + let f = $id::splat(false); + assert!(t != f); + assert!(!(t == f)); - // Not: - assert_eq!(!t, f); - assert_eq!(t, !f); + // Not: + assert_eq!(!t, f); + assert_eq!(t, !f); - // BitAnd: - assert_eq!(t & f, f); - assert_eq!(f & t, f); - assert_eq!(t & t, t); - assert_eq!(f & f, f); + // BitAnd: + assert_eq!(t & f, f); + assert_eq!(f & t, f); + assert_eq!(t & t, t); + assert_eq!(f & f, f); - // BitOr: - assert_eq!(t | f, t); - assert_eq!(f | t, t); - assert_eq!(t | t, t); - assert_eq!(f | f, f); + // BitOr: + assert_eq!(t | f, t); + assert_eq!(f | t, t); + assert_eq!(t | t, t); + assert_eq!(f | f, f); - // BitXOR: - assert_eq!(t ^ f, t); - assert_eq!(f ^ t, t); - assert_eq!(t ^ t, f); - assert_eq!(f ^ f, f); + // BitXOR: + assert_eq!(t ^ f, t); + assert_eq!(f ^ t, t); + assert_eq!(t ^ t, f); + assert_eq!(f ^ f, f); - { - // AndAssign: - let mut v = f; - v &= t; - assert_eq!(v, f); - } - { - // OrAssign: - let mut v = f; - v |= t; - assert_eq!(v, t); - } - { - // XORAssign: - let mut v = f; - v ^= t; - assert_eq!(v, t); + { + // AndAssign: + let mut v = f; + v &= t; + assert_eq!(v, f); + } + { + // OrAssign: + let mut v = f; + v |= t; + assert_eq!(v, t); + } + { + // XORAssign: + let mut v = f; + v ^= t; + assert_eq!(v, t); + } } } } diff --git a/src/api/ops/vector_neg.rs b/src/api/ops/vector_neg.rs index c7f446ec8..d31b7feb4 100644 --- a/src/api/ops/vector_neg.rs +++ b/src/api/ops/vector_neg.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector `Neg`. macro_rules! impl_ops_vector_neg { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::ops::Neg for $id { type Output = Self; #[inline] @@ -9,31 +9,33 @@ macro_rules! impl_ops_vector_neg { Self::splat(-1 as $elem_ty) * self } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_neg] { - use super::*; - #[test] - fn neg() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let f = $id::splat(4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_neg] { + use super::*; + #[test] + fn neg() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); - let nz = $id::splat(-(0 as $elem_ty)); - let no = $id::splat(-(1 as $elem_ty)); - let nt = $id::splat(-(2 as $elem_ty)); - let nf = $id::splat(-(4 as $elem_ty)); + let nz = $id::splat(-(0 as $elem_ty)); + let no = $id::splat(-(1 as $elem_ty)); + let nt = $id::splat(-(2 as $elem_ty)); + let nf = $id::splat(-(4 as $elem_ty)); - assert_eq!(-z, nz); - assert_eq!(-o, no); - assert_eq!(-t, nt); - assert_eq!(-f, nf); + assert_eq!(-z, nz); + assert_eq!(-o, no); + assert_eq!(-t, nt); + assert_eq!(-f, nf); - assert_eq!(z, -nz); - assert_eq!(o, -no); - assert_eq!(t, -nt); - assert_eq!(f, -nf); + assert_eq!(z, -nz); + assert_eq!(o, -no); + assert_eq!(t, -nt); + assert_eq!(f, -nf); + } } } } diff --git a/src/api/ops/vector_shifts.rs b/src/api/ops/vector_shifts.rs index 54f99c840..45a98b47b 100644 --- a/src/api/ops/vector_shifts.rs +++ b/src/api/ops/vector_shifts.rs @@ -1,7 +1,7 @@ //! Vertical (lane-wise) vector-vector shifts operations. macro_rules! impl_ops_vector_shifts { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl ::ops::Shl<$id> for $id { type Output = Self; #[inline] @@ -30,68 +30,70 @@ macro_rules! impl_ops_vector_shifts { *self = *self >> other; } } - #[cfg(test)] - interpolate_idents! { - mod [$id _ops_vector_shifts] { - use super::*; - #[test] - #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), - allow(unreachable_code, unused_variables))] - fn ops_vector_shifts() { - let z = $id::splat(0 as $elem_ty); - let o = $id::splat(1 as $elem_ty); - let t = $id::splat(2 as $elem_ty); - let f = $id::splat(4 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _ops_vector_shifts] { + use super::*; + #[test] + #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), + allow(unreachable_code, unused_variables))] + fn ops_vector_shifts() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); - let max = - $id::splat((mem::size_of::<$elem_ty>() * 8 - 1) as $elem_ty); + let max = + $id::splat((mem::size_of::<$elem_ty>() * 8 - 1) as $elem_ty); - // shr - assert_eq!(z >> z, z); - assert_eq!(z >> o, z); - assert_eq!(z >> t, z); - assert_eq!(z >> t, z); + // shr + assert_eq!(z >> z, z); + assert_eq!(z >> o, z); + assert_eq!(z >> t, z); + assert_eq!(z >> t, z); - #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { - // FIXME: rust produces bad codegen for shifts: - // https://github.com/rust-lang-nursery/packed_simd/issues/13 - return; - } + #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { + // FIXME: rust produces bad codegen for shifts: + // https://github.com/rust-lang-nursery/packed_simd/issues/13 + return; + } - assert_eq!(o >> z, o); - assert_eq!(t >> z, t); - assert_eq!(f >> z, f); - assert_eq!(f >> max, z); + assert_eq!(o >> z, o); + assert_eq!(t >> z, t); + assert_eq!(f >> z, f); + assert_eq!(f >> max, z); - assert_eq!(o >> o, z); - assert_eq!(t >> o, o); - assert_eq!(t >> t, z); - assert_eq!(f >> o, t); - assert_eq!(f >> t, o); - assert_eq!(f >> max, z); + assert_eq!(o >> o, z); + assert_eq!(t >> o, o); + assert_eq!(t >> t, z); + assert_eq!(f >> o, t); + assert_eq!(f >> t, o); + assert_eq!(f >> max, z); - // shl - assert_eq!(z << z, z); - assert_eq!(o << z, o); - assert_eq!(t << z, t); - assert_eq!(f << z, f); - assert_eq!(f << max, z); + // shl + assert_eq!(z << z, z); + assert_eq!(o << z, o); + assert_eq!(t << z, t); + assert_eq!(f << z, f); + assert_eq!(f << max, z); - assert_eq!(o << o, t); - assert_eq!(o << t, f); - assert_eq!(t << o, f); + assert_eq!(o << o, t); + assert_eq!(o << t, f); + assert_eq!(t << o, f); - { - // shr_assign - let mut v = o; - v >>= o; - assert_eq!(v, z); - } - { - // shl_assign - let mut v = o; - v <<= o; - assert_eq!(v, t); + { + // shr_assign + let mut v = o; + v >>= o; + assert_eq!(v, z); + } + { + // shl_assign + let mut v = o; + v <<= o; + assert_eq!(v, t); + } } } } diff --git a/src/api/reductions/bitwise.rs b/src/api/reductions/bitwise.rs index 7363a38af..caed3ebff 100644 --- a/src/api/reductions/bitwise.rs +++ b/src/api/reductions/bitwise.rs @@ -4,7 +4,7 @@ macro_rules! impl_reduction_bitwise { ( [$elem_ty:ident; $elem_count:expr]: - $id:ident | + $id:ident | $test_tt:tt | $ielem_ty:ident | ($convert:expr) | ($true:expr, $false:expr) @@ -83,65 +83,67 @@ macro_rules! impl_reduction_bitwise { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _reduction_bitwise] { - use super::*; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _reduction_bitwise] { + use super::*; - #[test] - fn and() { - let v = $id::splat($false); - assert_eq!(v.and(), $false); - let v = $id::splat($true); - assert_eq!(v.and(), $true); - let v = $id::splat($false); - let v = v.replace(0, $true); - if $id::lanes() > 1 { + #[test] + fn and() { + let v = $id::splat($false); assert_eq!(v.and(), $false); - } else { + let v = $id::splat($true); assert_eq!(v.and(), $true); - } - let v = $id::splat($true); - let v = v.replace(0, $false); - assert_eq!(v.and(), $false); + let v = $id::splat($false); + let v = v.replace(0, $true); + if $id::lanes() > 1 { + assert_eq!(v.and(), $false); + } else { + assert_eq!(v.and(), $true); + } + let v = $id::splat($true); + let v = v.replace(0, $false); + assert_eq!(v.and(), $false); - } - #[test] - fn or() { - let v = $id::splat($false); - assert_eq!(v.or(), $false); - let v = $id::splat($true); - assert_eq!(v.or(), $true); - let v = $id::splat($false); - let v = v.replace(0, $true); - assert_eq!(v.or(), $true); - let v = $id::splat($true); - let v = v.replace(0, $false); - if $id::lanes() > 1 { - assert_eq!(v.or(), $true); - } else { + } + #[test] + fn or() { + let v = $id::splat($false); assert_eq!(v.or(), $false); + let v = $id::splat($true); + assert_eq!(v.or(), $true); + let v = $id::splat($false); + let v = v.replace(0, $true); + assert_eq!(v.or(), $true); + let v = $id::splat($true); + let v = v.replace(0, $false); + if $id::lanes() > 1 { + assert_eq!(v.or(), $true); + } else { + assert_eq!(v.or(), $false); + } } - } - #[test] - fn xor() { - let v = $id::splat($false); - assert_eq!(v.xor(), $false); - let v = $id::splat($true); - if $id::lanes() > 1 { + #[test] + fn xor() { + let v = $id::splat($false); assert_eq!(v.xor(), $false); - } else { + let v = $id::splat($true); + if $id::lanes() > 1 { + assert_eq!(v.xor(), $false); + } else { + assert_eq!(v.xor(), $true); + } + let v = $id::splat($false); + let v = v.replace(0, $true); assert_eq!(v.xor(), $true); - } - let v = $id::splat($false); - let v = v.replace(0, $true); - assert_eq!(v.xor(), $true); - let v = $id::splat($true); - let v = v.replace(0, $false); - if $id::lanes() > 1 { - assert_eq!(v.xor(), $true); - } else { - assert_eq!(v.xor(), $false); + let v = $id::splat($true); + let v = v.replace(0, $false); + if $id::lanes() > 1 { + assert_eq!(v.xor(), $true); + } else { + assert_eq!(v.xor(), $false); + } } } } diff --git a/src/api/reductions/float_arithmetic.rs b/src/api/reductions/float_arithmetic.rs index 26e0f2231..7b1af1488 100644 --- a/src/api/reductions/float_arithmetic.rs +++ b/src/api/reductions/float_arithmetic.rs @@ -1,7 +1,7 @@ //! Implements portable horizontal float vector arithmetic reductions. macro_rules! impl_reduction_float_arithmetic { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Horizontal sum of the vector elements. /// @@ -58,200 +58,202 @@ macro_rules! impl_reduction_float_arithmetic { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _reduction_float_arith] { - use super::*; - fn alternating(x: usize) -> $id { - let mut v = $id::splat(1 as $elem_ty); - for i in 0..$id::lanes() { - if i % x == 0 { - v = v.replace(i, 2 as $elem_ty); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _reduction_float_arith] { + use super::*; + fn alternating(x: usize) -> $id { + let mut v = $id::splat(1 as $elem_ty); + for i in 0..$id::lanes() { + if i % x == 0 { + v = v.replace(i, 2 as $elem_ty); + } } + v } - v - } - #[test] - fn sum() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.sum(), 0 as $elem_ty); - let v = $id::splat(1 as $elem_ty); - assert_eq!(v.sum(), $id::lanes() as $elem_ty); - let v = alternating(2); - assert_eq!(v.sum(), ($id::lanes() / 2 + $id::lanes()) as $elem_ty); - } - #[test] - fn product() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.product(), 0 as $elem_ty); - let v = $id::splat(1 as $elem_ty); - assert_eq!(v.product(), 1 as $elem_ty); - let f = match $id::lanes() { - 64 => 16, - 32 => 8, - 16 => 4, - _ => 2, - }; - let v = alternating(f); - assert_eq!( - v.product(), - (2_usize.pow(($id::lanes() / f) as u32) as $elem_ty) - ); - } + #[test] + fn sum() { + let v = $id::splat(0 as $elem_ty); + assert_eq!(v.sum(), 0 as $elem_ty); + let v = $id::splat(1 as $elem_ty); + assert_eq!(v.sum(), $id::lanes() as $elem_ty); + let v = alternating(2); + assert_eq!(v.sum(), ($id::lanes() / 2 + $id::lanes()) as $elem_ty); + } + #[test] + fn product() { + let v = $id::splat(0 as $elem_ty); + assert_eq!(v.product(), 0 as $elem_ty); + let v = $id::splat(1 as $elem_ty); + assert_eq!(v.product(), 1 as $elem_ty); + let f = match $id::lanes() { + 64 => 16, + 32 => 8, + 16 => 4, + _ => 2, + }; + let v = alternating(f); + assert_eq!( + v.product(), + (2_usize.pow(($id::lanes() / f) as u32) as $elem_ty) + ); + } - #[test] - #[allow(unreachable_code)] - fn sum_nan() { - // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36732 - // https://github.com/rust-lang-nursery/stdsimd/issues/409 - return; + #[test] + #[allow(unreachable_code)] + fn sum_nan() { + // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36732 + // https://github.com/rust-lang-nursery/packed_simd/issues/6 + return; - let n0 = $elem_ty::NAN; - let v0 = $id::splat(-3.0); - for i in 0..$id::lanes() { - let mut v = v0.replace(i, n0); - // If the vector contains a NaN the result is NaN: - assert!( - v.sum().is_nan(), - "nan at {} => {} | {:?}", - i, - v.sum(), - v - ); - for j in 0..i { - v = v.replace(j, n0); - assert!(v.sum().is_nan()); + let n0 = $elem_ty::NAN; + let v0 = $id::splat(-3.0); + for i in 0..$id::lanes() { + let mut v = v0.replace(i, n0); + // If the vector contains a NaN the result is NaN: + assert!( + v.sum().is_nan(), + "nan at {} => {} | {:?}", + i, + v.sum(), + v + ); + for j in 0..i { + v = v.replace(j, n0); + assert!(v.sum().is_nan()); + } } + let v = $id::splat(n0); + assert!(v.sum().is_nan(), "all nans | {:?}", v); } - let v = $id::splat(n0); - assert!(v.sum().is_nan(), "all nans | {:?}", v); - } - #[test] - #[allow(unreachable_code)] - fn product_nan() { - // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36732 - // https://github.com/rust-lang-nursery/stdsimd/issues/409 - return; + #[test] + #[allow(unreachable_code)] + fn product_nan() { + // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36732 + // https://github.com/rust-lang-nursery/packed_simd/issues/6 + return; - let n0 = $elem_ty::NAN; - let v0 = $id::splat(-3.0); - for i in 0..$id::lanes() { - let mut v = v0.replace(i, n0); - // If the vector contains a NaN the result is NaN: - assert!( - v.product().is_nan(), - "nan at {} => {} | {:?}", - i, - v.product(), - v - ); - for j in 0..i { - v = v.replace(j, n0); - assert!(v.product().is_nan()); + let n0 = $elem_ty::NAN; + let v0 = $id::splat(-3.0); + for i in 0..$id::lanes() { + let mut v = v0.replace(i, n0); + // If the vector contains a NaN the result is NaN: + assert!( + v.product().is_nan(), + "nan at {} => {} | {:?}", + i, + v.product(), + v + ); + for j in 0..i { + v = v.replace(j, n0); + assert!(v.product().is_nan()); + } } + let v = $id::splat(n0); + assert!(v.product().is_nan(), "all nans | {:?}", v); } - let v = $id::splat(n0); - assert!(v.product().is_nan(), "all nans | {:?}", v); - } - #[test] - #[allow(unused, dead_code)] - fn sum_roundoff() { - // Performs a tree-reduction - fn tree_reduce_sum(a: &[[$elem_ty]]) -> $elem_ty { - assert!(!a.is_empty()); - if a.len() == 1 { - a[0] - } else if a.len() == 2 { - a[0] + a[1] - } else { - let mid = a.len() / 2; - let (left, right) = a.split_at(mid); - tree_reduce_sum(left) + tree_reduce_sum(right) + #[test] + #[allow(unused, dead_code)] + fn sum_roundoff() { + // Performs a tree-reduction + fn tree_reduce_sum(a: &[[$elem_ty]]) -> $elem_ty { + assert!(!a.is_empty()); + if a.len() == 1 { + a[0] + } else if a.len() == 2 { + a[0] + a[1] + } else { + let mid = a.len() / 2; + let (left, right) = a.split_at(mid); + tree_reduce_sum(left) + tree_reduce_sum(right) + } } - } - let mut start = $elem_ty::EPSILON; - let mut scalar_reduction = 0. as $elem_ty; + let mut start = $elem_ty::EPSILON; + let mut scalar_reduction = 0. as $elem_ty; - let mut v = $id::splat(0. as $elem_ty); - for i in 0..$id::lanes() { - let c = if i % 2 == 0 { 1e3 } else { -1. }; - start *= 3.14 * c; - scalar_reduction += start; - v = v.replace(i, start); - } - let simd_reduction = v.sum(); + let mut v = $id::splat(0. as $elem_ty); + for i in 0..$id::lanes() { + let c = if i % 2 == 0 { 1e3 } else { -1. }; + start *= 3.14 * c; + scalar_reduction += start; + v = v.replace(i, start); + } + let simd_reduction = v.sum(); - let mut a = [0. as $elem_ty; $id::lanes()]; - v.write_to_slice_unaligned(&mut a); - let tree_reduction = tree_reduce_sum(&a); + let mut a = [0. as $elem_ty; $id::lanes()]; + v.write_to_slice_unaligned(&mut a); + let tree_reduction = tree_reduce_sum(&a); - // tolerate 1 ULP difference: - assert!( - if simd_reduction.to_bits() > tree_reduction.to_bits() { - simd_reduction.to_bits() - tree_reduction.to_bits() < 2 - } else { - tree_reduction.to_bits() - simd_reduction.to_bits() < 2 - }, - "vector: {:?} | simd_reduction: {:?} | \ - tree_reduction: {} | scalar_reduction: {}", - v, - simd_reduction, - tree_reduction, - scalar_reduction - ); - } + // tolerate 1 ULP difference: + assert!( + if simd_reduction.to_bits() > tree_reduction.to_bits() { + simd_reduction.to_bits() - tree_reduction.to_bits() < 2 + } else { + tree_reduction.to_bits() - simd_reduction.to_bits() < 2 + }, + "vector: {:?} | simd_reduction: {:?} | \ + tree_reduction: {} | scalar_reduction: {}", + v, + simd_reduction, + tree_reduction, + scalar_reduction + ); + } - #[test] - #[allow(unused, dead_code)] - fn product_roundoff() { - // Performs a tree-reduction - fn tree_reduce_product(a: &[[$elem_ty]]) -> $elem_ty { - assert!(!a.is_empty()); - if a.len() == 1 { - a[0] - } else if a.len() == 2 { - a[0] * a[1] - } else { - let mid = a.len() / 2; - let (left, right) = a.split_at(mid); - tree_reduce_product(left) * tree_reduce_product(right) + #[test] + #[allow(unused, dead_code)] + fn product_roundoff() { + // Performs a tree-reduction + fn tree_reduce_product(a: &[[$elem_ty]]) -> $elem_ty { + assert!(!a.is_empty()); + if a.len() == 1 { + a[0] + } else if a.len() == 2 { + a[0] * a[1] + } else { + let mid = a.len() / 2; + let (left, right) = a.split_at(mid); + tree_reduce_product(left) * tree_reduce_product(right) + } } - } - let mut start = $elem_ty::EPSILON; - let mut scalar_reduction = 1. as $elem_ty; + let mut start = $elem_ty::EPSILON; + let mut scalar_reduction = 1. as $elem_ty; - let mut v = $id::splat(0. as $elem_ty); - for i in 0..$id::lanes() { - let c = if i % 2 == 0 { 1e3 } else { -1. }; - start *= 3.14 * c; - scalar_reduction *= start; - v = v.replace(i, start); - } - let simd_reduction = v.product(); + let mut v = $id::splat(0. as $elem_ty); + for i in 0..$id::lanes() { + let c = if i % 2 == 0 { 1e3 } else { -1. }; + start *= 3.14 * c; + scalar_reduction *= start; + v = v.replace(i, start); + } + let simd_reduction = v.product(); - let mut a = [0. as $elem_ty; $id::lanes()]; - v.write_to_slice_unaligned(&mut a); - let tree_reduction = tree_reduce_product(&a); + let mut a = [0. as $elem_ty; $id::lanes()]; + v.write_to_slice_unaligned(&mut a); + let tree_reduction = tree_reduce_product(&a); - // tolerate 1 ULP difference: - assert!( - if simd_reduction.to_bits() > tree_reduction.to_bits() { - simd_reduction.to_bits() - tree_reduction.to_bits() < 2 - } else { - tree_reduction.to_bits() - simd_reduction.to_bits() < 2 - }, - "vector: {:?} | simd_reduction: {:?} | \ - tree_reduction: {} | scalar_reduction: {}", - v, - simd_reduction, - tree_reduction, - scalar_reduction - ); + // tolerate 1 ULP difference: + assert!( + if simd_reduction.to_bits() > tree_reduction.to_bits() { + simd_reduction.to_bits() - tree_reduction.to_bits() < 2 + } else { + tree_reduction.to_bits() - simd_reduction.to_bits() < 2 + }, + "vector: {:?} | simd_reduction: {:?} | \ + tree_reduction: {} | scalar_reduction: {}", + v, + simd_reduction, + tree_reduction, + scalar_reduction + ); + } } } } diff --git a/src/api/reductions/integer_arithmetic.rs b/src/api/reductions/integer_arithmetic.rs index 2db29560e..6d553149f 100644 --- a/src/api/reductions/integer_arithmetic.rs +++ b/src/api/reductions/integer_arithmetic.rs @@ -1,7 +1,7 @@ //! Implements portable horizontal integer vector arithmetic reductions. macro_rules! impl_reduction_integer_arithmetic { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Horizontal wrapping sum of the vector elements. /// @@ -60,94 +60,96 @@ macro_rules! impl_reduction_integer_arithmetic { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _reduction_int_arith] { - use super::*; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _reduction_int_arith] { + use super::*; - fn alternating(x: usize) -> $id { - let mut v = $id::splat(1 as $elem_ty); - for i in 0..$id::lanes() { - if i % x == 0 { - v = v.replace(i, 2 as $elem_ty); + fn alternating(x: usize) -> $id { + let mut v = $id::splat(1 as $elem_ty); + for i in 0..$id::lanes() { + if i % x == 0 { + v = v.replace(i, 2 as $elem_ty); + } } + v } - v - } - #[test] - fn wrapping_sum() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.wrapping_sum(), 0 as $elem_ty); - let v = $id::splat(1 as $elem_ty); - assert_eq!(v.wrapping_sum(), $id::lanes() as $elem_ty); - let v = alternating(2); - if $id::lanes() > 1 { - assert_eq!( - v.wrapping_sum(), - ($id::lanes() / 2 + $id::lanes()) as $elem_ty - ); - } else { - assert_eq!( - v.wrapping_sum(), - 2 as $elem_ty - ); + #[test] + fn wrapping_sum() { + let v = $id::splat(0 as $elem_ty); + assert_eq!(v.wrapping_sum(), 0 as $elem_ty); + let v = $id::splat(1 as $elem_ty); + assert_eq!(v.wrapping_sum(), $id::lanes() as $elem_ty); + let v = alternating(2); + if $id::lanes() > 1 { + assert_eq!( + v.wrapping_sum(), + ($id::lanes() / 2 + $id::lanes()) as $elem_ty + ); + } else { + assert_eq!( + v.wrapping_sum(), + 2 as $elem_ty + ); + } } - } - #[test] - fn wrapping_sum_overflow() { - let start = $elem_ty::max_value() - - ($id::lanes() as $elem_ty / 2); + #[test] + fn wrapping_sum_overflow() { + let start = $elem_ty::max_value() + - ($id::lanes() as $elem_ty / 2); - let v = $id::splat(start as $elem_ty); - let vwrapping_sum = v.wrapping_sum(); + let v = $id::splat(start as $elem_ty); + let vwrapping_sum = v.wrapping_sum(); - let mut wrapping_sum = start; - for _ in 1..$id::lanes() { - wrapping_sum = wrapping_sum.wrapping_add(start); + let mut wrapping_sum = start; + for _ in 1..$id::lanes() { + wrapping_sum = wrapping_sum.wrapping_add(start); + } + assert_eq!(wrapping_sum, vwrapping_sum, "v = {:?}", v); } - assert_eq!(wrapping_sum, vwrapping_sum, "v = {:?}", v); - } - #[test] - fn wrapping_product() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.wrapping_product(), 0 as $elem_ty); - let v = $id::splat(1 as $elem_ty); - assert_eq!(v.wrapping_product(), 1 as $elem_ty); - let f = match $id::lanes() { - 64 => 16, - 32 => 8, - 16 => 4, - _ => 2, - }; - let v = alternating(f); - if $id::lanes() > 1 { - assert_eq!( - v.wrapping_product(), - (2_usize.pow(($id::lanes() / f) as u32) as $elem_ty) - ); - } else { - assert_eq!( - v.wrapping_product(), - 2 as $elem_ty - ); + #[test] + fn wrapping_product() { + let v = $id::splat(0 as $elem_ty); + assert_eq!(v.wrapping_product(), 0 as $elem_ty); + let v = $id::splat(1 as $elem_ty); + assert_eq!(v.wrapping_product(), 1 as $elem_ty); + let f = match $id::lanes() { + 64 => 16, + 32 => 8, + 16 => 4, + _ => 2, + }; + let v = alternating(f); + if $id::lanes() > 1 { + assert_eq!( + v.wrapping_product(), + (2_usize.pow(($id::lanes() / f) as u32) as $elem_ty) + ); + } else { + assert_eq!( + v.wrapping_product(), + 2 as $elem_ty + ); + } } - } - #[test] - fn wrapping_product_overflow() { - let start = $elem_ty::max_value() - - ($id::lanes() as $elem_ty / 2); + #[test] + fn wrapping_product_overflow() { + let start = $elem_ty::max_value() + - ($id::lanes() as $elem_ty / 2); - let v = $id::splat(start as $elem_ty); - let vmul = v.wrapping_product(); + let v = $id::splat(start as $elem_ty); + let vmul = v.wrapping_product(); - let mut mul = start; - for _ in 1..$id::lanes() { - mul = mul.wrapping_mul(start); + let mut mul = start; + for _ in 1..$id::lanes() { + mul = mul.wrapping_mul(start); + } + assert_eq!(mul, vmul, "v = {:?}", v); } - assert_eq!(mul, vmul, "v = {:?}", v); } } } diff --git a/src/api/reductions/mask.rs b/src/api/reductions/mask.rs index c4050b053..0816639ad 100644 --- a/src/api/reductions/mask.rs +++ b/src/api/reductions/mask.rs @@ -1,7 +1,7 @@ //! Implements portable horizontal mask reductions. macro_rules! impl_reduction_mask { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Are `all` vector lanes `true`? #[inline] @@ -20,61 +20,63 @@ macro_rules! impl_reduction_mask { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _reduction] { - use super::*; - #[test] - fn all() { - let a = $id::splat(true); - assert!(a.all()); - let a = $id::splat(false); - assert!(!a.all()); + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _reduction] { + use super::*; + #[test] + fn all() { + let a = $id::splat(true); + assert!(a.all()); + let a = $id::splat(false); + assert!(!a.all()); - if $id::lanes() > 1 { - for i in 0..$id::lanes() { - let mut a = $id::splat(true); - a = a.replace(i, false); - assert!(!a.all()); - let mut a = $id::splat(false); - a = a.replace(i, true); - assert!(!a.all()); + if $id::lanes() > 1 { + for i in 0..$id::lanes() { + let mut a = $id::splat(true); + a = a.replace(i, false); + assert!(!a.all()); + let mut a = $id::splat(false); + a = a.replace(i, true); + assert!(!a.all()); + } } } - } - #[test] - fn any() { - let a = $id::splat(true); - assert!(a.any()); - let a = $id::splat(false); - assert!(!a.any()); + #[test] + fn any() { + let a = $id::splat(true); + assert!(a.any()); + let a = $id::splat(false); + assert!(!a.any()); - if $id::lanes() > 1 { - for i in 0..$id::lanes() { - let mut a = $id::splat(true); - a = a.replace(i, false); - assert!(a.any()); - let mut a = $id::splat(false); - a = a.replace(i, true); - assert!(a.any()); + if $id::lanes() > 1 { + for i in 0..$id::lanes() { + let mut a = $id::splat(true); + a = a.replace(i, false); + assert!(a.any()); + let mut a = $id::splat(false); + a = a.replace(i, true); + assert!(a.any()); + } } } - } - #[test] - fn none() { - let a = $id::splat(true); - assert!(!a.none()); - let a = $id::splat(false); - assert!(a.none()); + #[test] + fn none() { + let a = $id::splat(true); + assert!(!a.none()); + let a = $id::splat(false); + assert!(a.none()); - if $id::lanes() > 1 { - for i in 0..$id::lanes() { - let mut a = $id::splat(true); - a = a.replace(i, false); - assert!(!a.none()); - let mut a = $id::splat(false); - a = a.replace(i, true); - assert!(!a.none()); + if $id::lanes() > 1 { + for i in 0..$id::lanes() { + let mut a = $id::splat(true); + a = a.replace(i, false); + assert!(!a.none()); + let mut a = $id::splat(false); + a = a.replace(i, true); + assert!(!a.none()); + } } } } diff --git a/src/api/reductions/min_max.rs b/src/api/reductions/min_max.rs index ad44fb0d8..0fb9fffe1 100644 --- a/src/api/reductions/min_max.rs +++ b/src/api/reductions/min_max.rs @@ -1,7 +1,7 @@ //! Implements portable horizontal vector min/max reductions. macro_rules! impl_reduction_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Largest vector element value. #[inline] @@ -66,7 +66,7 @@ macro_rules! impl_reduction_min_max { } } } - #[cfg(test)] + test_if!{$test_tt: interpolate_idents! { mod [$id _reduction_min_max] { use super::*; @@ -105,221 +105,224 @@ macro_rules! impl_reduction_min_max { } } } + } }; } macro_rules! test_reduction_float_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { - #[cfg(test)] - interpolate_idents! { - mod [$id _reduction_min_max_nan] { - use super::*; - #[test] - fn min_element_test() { - let n = $elem_ty::NAN; + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _reduction_min_max_nan] { + use super::*; + #[test] + fn min_element_test() { + let n = $elem_ty::NAN; + + assert_eq!(n.min(-3.), -3.); + assert_eq!((-3. as $elem_ty).min(n), -3.); + + let v0 = $id::splat(-3.); + + let target_with_broken_last_lane_nan = !cfg!(any( + target_arch = "arm", target_arch = "aarch64", + all(target_arch = "x86", not(target_feature = "sse2")), + target_arch = "powerpc64", + )); - assert_eq!(n.min(-3.), -3.); - assert_eq!((-3. as $elem_ty).min(n), -3.); + // The vector is initialized to `-3.`s: [-3, -3, -3, -3] + for i in 0..$id::lanes() { + // We replace the i-th element of the vector with `NaN`: [-3, -3, -3, NaN] + let mut v = v0.replace(i, n); - let v0 = $id::splat(-3.); + // If the NaN is in the last place, the LLVM implementation of these methods + // is broken on some targets: + if i == $id::lanes() - 1 && target_with_broken_last_lane_nan { + // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/5 + // + // If there is a NaN, the result should always the smallest element, + // but currently when the last element is NaN the current + // implementation incorrectly returns NaN. + // + // The targets mentioned above use different codegen that + // produces the correct result. + // + // These asserts detect if this behavior changes + assert!(v.min_element().is_nan(), // FIXME: should be -3. + "[A]: nan at {} => {} | {:?}", + i, v.min_element(), v); - let target_with_broken_last_lane_nan = !cfg!(any( - target_arch = "arm", target_arch = "aarch64", - all(target_arch = "x86", not(target_feature = "sse2")), - target_arch = "powerpc64", - )); - - // The vector is initialized to `-3.`s: [-3, -3, -3, -3] - for i in 0..$id::lanes() { - // We replace the i-th element of the vector with `NaN`: [-3, -3, -3, NaN] - let mut v = v0.replace(i, n); - - // If the NaN is in the last place, the LLVM implementation of these methods - // is broken on some targets: - if i == $id::lanes() - 1 && target_with_broken_last_lane_nan { - // FIXME (https://github.com/rust-lang-nursery/stdsimd/issues/408): - // - // If there is a NaN, the result should always the smallest element, - // but currently when the last element is NaN the current - // implementation incorrectly returns NaN. - // - // The targets mentioned above use different codegen that - // produces the correct result. - // - // These asserts detect if this behavior changes - assert!(v.min_element().is_nan(), // FIXME: should be -3. - "[A]: nan at {} => {} | {:?}", - i, v.min_element(), v); + // If we replace all the elements in the vector up-to the `i-th` lane + // with `NaN`s, the result is still always `-3.` unless all + // elements of the vector are `NaN`s: + // + // This is also broken: + for j in 0..i { + v = v.replace(j, n); + assert!(v.min_element().is_nan(), // FIXME: should be -3. + "[B]: nan at {} => {} | {:?}", + i, v.min_element(), v); + } + + // We are done here, since we were in the last lane which + // is the last iteration of the loop. + break + } + + // We are not in the last lane, and there is only one `NaN` + // in the vector. + + // If the vector has one lane, the result is `NaN`: + if $id::lanes() == 1 { + assert!(v.min_element().is_nan(), + "[C]: all nans | v={:?} | min={} | is_nan: {}", + v, v.min_element(), v.min_element().is_nan()); + + // And we are done, since the vector only has one lane anyways. + break; + } + + // The vector has more than one lane, since there is only + // one `NaN` in the vector, the result is always `-3`. + assert_eq!(v.min_element(), -3., + "[D]: nan at {} => {} | {:?}", + i, v.min_element(), v); // If we replace all the elements in the vector up-to the `i-th` lane // with `NaN`s, the result is still always `-3.` unless all // elements of the vector are `NaN`s: - // - // This is also broken: for j in 0..i { v = v.replace(j, n); - assert!(v.min_element().is_nan(), // FIXME: should be -3. - "[B]: nan at {} => {} | {:?}", - i, v.min_element(), v); - } - // We are done here, since we were in the last lane which - // is the last iteration of the loop. - break + if i == $id::lanes() - 1 && j == i - 1 { + // All elements of the vector are `NaN`s, therefore the + // result is NaN as well. + // + // Note: the #lanes of the vector is > 1, so "i - 1" does not + // overflow. + assert!(v.min_element().is_nan(), + "[E]: all nans | v={:?} | min={} | is_nan: {}", + v, v.min_element(), v.min_element().is_nan()); + } else { + // There are non-`NaN` elements in the vector, therefore + // the result is `-3.`: + assert_eq!(v.min_element(), -3., + "[F]: nan at {} => {} | {:?}", + i, v.min_element(), v); + } + } } - // We are not in the last lane, and there is only one `NaN` - // in the vector. + // If the vector contains all NaNs the result is NaN: + assert!($id::splat(n).min_element().is_nan(), + "all nans | v={:?} | min={} | is_nan: {}", + $id::splat(n), $id::splat(n).min_element(), + $id::splat(n).min_element().is_nan()); + } + #[test] + fn max_element_test() { + let n = $elem_ty::NAN; - // If the vector has one lane, the result is `NaN`: - if $id::lanes() == 1 { - assert!(v.min_element().is_nan(), - "[C]: all nans | v={:?} | min={} | is_nan: {}", - v, v.min_element(), v.min_element().is_nan()); + assert_eq!(n.max(-3.), -3.); + assert_eq!((-3. as $elem_ty).max(n), -3.); - // And we are done, since the vector only has one lane anyways. - break; - } + let v0 = $id::splat(-3.); + + let target_with_broken_last_lane_nan = !cfg!(any( + target_arch = "arm", target_arch = "aarch64", + target_arch = "powerpc64", + )); + + // The vector is initialized to `-3.`s: [-3, -3, -3, -3] + for i in 0..$id::lanes() { + // We replace the i-th element of the vector with `NaN`: [-3, -3, -3, NaN] + let mut v = v0.replace(i, n); - // The vector has more than one lane, since there is only - // one `NaN` in the vector, the result is always `-3`. - assert_eq!(v.min_element(), -3., - "[D]: nan at {} => {} | {:?}", - i, v.min_element(), v); - - // If we replace all the elements in the vector up-to the `i-th` lane - // with `NaN`s, the result is still always `-3.` unless all - // elements of the vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - - if i == $id::lanes() - 1 && j == i - 1 { - // All elements of the vector are `NaN`s, therefore the - // result is NaN as well. + // If the NaN is in the last place, the LLVM implementation of these methods + // is broken on some targets: + if i == $id::lanes() - 1 && target_with_broken_last_lane_nan { + // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/5 // - // Note: the #lanes of the vector is > 1, so "i - 1" does not - // overflow. - assert!(v.min_element().is_nan(), - "[E]: all nans | v={:?} | min={} | is_nan: {}", - v, v.min_element(), v.min_element().is_nan()); - } else { - // There are non-`NaN` elements in the vector, therefore - // the result is `-3.`: - assert_eq!(v.min_element(), -3., - "[F]: nan at {} => {} | {:?}", - i, v.min_element(), v); + // If there is a NaN, the result should always the largest element, + // but currently when the last element is NaN the current + // implementation incorrectly returns NaN. + // + // The targets mentioned above use different codegen that + // produces the correct result. + // + // These asserts detect if this behavior changes + assert!(v.max_element().is_nan(), // FIXME: should be -3. + "[A]: nan at {} => {} | {:?}", + i, v.max_element(), v); + + // If we replace all the elements in the vector up-to the `i-th` lane + // with `NaN`s, the result is still always `-3.` unless all + // elements of the vector are `NaN`s: + // + // This is also broken: + for j in 0..i { + v = v.replace(j, n); + assert!(v.max_element().is_nan(), // FIXME: should be -3. + "[B]: nan at {} => {} | {:?}", + i, v.max_element(), v); + } + + // We are done here, since we were in the last lane which + // is the last iteration of the loop. + break } - } - } - // If the vector contains all NaNs the result is NaN: - assert!($id::splat(n).min_element().is_nan(), - "all nans | v={:?} | min={} | is_nan: {}", - $id::splat(n), $id::splat(n).min_element(), - $id::splat(n).min_element().is_nan()); - } - #[test] - fn max_element_test() { - let n = $elem_ty::NAN; + // We are not in the last lane, and there is only one `NaN` + // in the vector. - assert_eq!(n.max(-3.), -3.); - assert_eq!((-3. as $elem_ty).max(n), -3.); + // If the vector has one lane, the result is `NaN`: + if $id::lanes() == 1 { + assert!(v.max_element().is_nan(), + "[C]: all nans | v={:?} | min={} | is_nan: {}", + v, v.max_element(), v.max_element().is_nan()); - let v0 = $id::splat(-3.); + // And we are done, since the vector only has one lane anyways. + break; + } - let target_with_broken_last_lane_nan = !cfg!(any( - target_arch = "arm", target_arch = "aarch64", - target_arch = "powerpc64", - )); - - // The vector is initialized to `-3.`s: [-3, -3, -3, -3] - for i in 0..$id::lanes() { - // We replace the i-th element of the vector with `NaN`: [-3, -3, -3, NaN] - let mut v = v0.replace(i, n); - - // If the NaN is in the last place, the LLVM implementation of these methods - // is broken on some targets: - if i == $id::lanes() - 1 && target_with_broken_last_lane_nan { - // FIXME (https://github.com/rust-lang-nursery/stdsimd/issues/408): - // - // If there is a NaN, the result should always the largest element, - // but currently when the last element is NaN the current - // implementation incorrectly returns NaN. - // - // The targets mentioned above use different codegen that - // produces the correct result. - // - // These asserts detect if this behavior changes - assert!(v.max_element().is_nan(), // FIXME: should be -3. - "[A]: nan at {} => {} | {:?}", - i, v.max_element(), v); + // The vector has more than one lane, since there is only + // one `NaN` in the vector, the result is always `-3`. + assert_eq!(v.max_element(), -3., + "[D]: nan at {} => {} | {:?}", + i, v.max_element(), v); // If we replace all the elements in the vector up-to the `i-th` lane // with `NaN`s, the result is still always `-3.` unless all // elements of the vector are `NaN`s: - // - // This is also broken: for j in 0..i { v = v.replace(j, n); - assert!(v.max_element().is_nan(), // FIXME: should be -3. - "[B]: nan at {} => {} | {:?}", - i, v.max_element(), v); - } - - // We are done here, since we were in the last lane which - // is the last iteration of the loop. - break - } - - // We are not in the last lane, and there is only one `NaN` - // in the vector. - - // If the vector has one lane, the result is `NaN`: - if $id::lanes() == 1 { - assert!(v.max_element().is_nan(), - "[C]: all nans | v={:?} | min={} | is_nan: {}", - v, v.max_element(), v.max_element().is_nan()); - // And we are done, since the vector only has one lane anyways. - break; - } - - // The vector has more than one lane, since there is only - // one `NaN` in the vector, the result is always `-3`. - assert_eq!(v.max_element(), -3., - "[D]: nan at {} => {} | {:?}", - i, v.max_element(), v); - - // If we replace all the elements in the vector up-to the `i-th` lane - // with `NaN`s, the result is still always `-3.` unless all - // elements of the vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - - if i == $id::lanes() - 1 && j == i - 1 { - // All elements of the vector are `NaN`s, therefore the - // result is NaN as well. - // - // Note: the #lanes of the vector is > 1, so "i - 1" does not - // overflow. - assert!(v.max_element().is_nan(), - "[E]: all nans | v={:?} | max={} | is_nan: {}", - v, v.max_element(), v.max_element().is_nan()); - } else { - // There are non-`NaN` elements in the vector, therefore - // the result is `-3.`: - assert_eq!(v.max_element(), -3., - "[F]: nan at {} => {} | {:?}", - i, v.max_element(), v); + if i == $id::lanes() - 1 && j == i - 1 { + // All elements of the vector are `NaN`s, therefore the + // result is NaN as well. + // + // Note: the #lanes of the vector is > 1, so "i - 1" does not + // overflow. + assert!(v.max_element().is_nan(), + "[E]: all nans | v={:?} | max={} | is_nan: {}", + v, v.max_element(), v.max_element().is_nan()); + } else { + // There are non-`NaN` elements in the vector, therefore + // the result is `-3.`: + assert_eq!(v.max_element(), -3., + "[F]: nan at {} => {} | {:?}", + i, v.max_element(), v); + } } } - } - // If the vector contains all NaNs the result is NaN: - assert!($id::splat(n).max_element().is_nan(), - "all nans | v={:?} | max={} | is_nan: {}", - $id::splat(n), $id::splat(n).max_element(), - $id::splat(n).max_element().is_nan()); + // If the vector contains all NaNs the result is NaN: + assert!($id::splat(n).max_element().is_nan(), + "all nans | v={:?} | max={} | is_nan: {}", + $id::splat(n), $id::splat(n).max_element(), + $id::splat(n).max_element().is_nan()); + } } } } diff --git a/src/api/select.rs b/src/api/select.rs index 526e63e17..d3091df22 100644 --- a/src/api/select.rs +++ b/src/api/select.rs @@ -2,7 +2,7 @@ /// Implements mask select method macro_rules! impl_select { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Selects elements of `a` and `b` using mask. /// @@ -19,7 +19,7 @@ macro_rules! impl_select { } } - test_select!(bool, $id, $id, (false, true)); + test_select!(bool, $id, $id, (false, true) | $test_tt); }; } @@ -27,42 +27,45 @@ macro_rules! test_select { ( $elem_ty:ident, $mask_ty:ident, - $vec_ty:ident,($small:expr, $large:expr) + $vec_ty:ident,($small:expr, $large:expr) | + $test_tt:tt ) => { - #[cfg(test)] - interpolate_idents! { - mod [$vec_ty _select] { - use super::*; + test_if! { + $test_tt: + interpolate_idents! { + mod [$vec_ty _select] { + use super::*; - #[test] - fn select() { - let o = $small as $elem_ty; - let t = $large as $elem_ty; + #[test] + fn select() { + let o = $small as $elem_ty; + let t = $large as $elem_ty; - let a = $vec_ty::splat(o); - let b = $vec_ty::splat(t); - let m = a.lt(b); - assert_eq!(m.select(a, b), a); + let a = $vec_ty::splat(o); + let b = $vec_ty::splat(t); + let m = a.lt(b); + assert_eq!(m.select(a, b), a); - let m = b.lt(a); - assert_eq!(m.select(b, a), a); + let m = b.lt(a); + assert_eq!(m.select(b, a), a); - let mut c = a; - let mut d = b; - let mut m_e = $mask_ty::splat(false); - for i in 0..$vec_ty::lanes() { - if i % 2 == 0 { - let c_tmp = c.extract(i); - c = c.replace(i, d.extract(i)); - d = d.replace(i, c_tmp); - } else { - m_e = m_e.replace(i, true); + let mut c = a; + let mut d = b; + let mut m_e = $mask_ty::splat(false); + for i in 0..$vec_ty::lanes() { + if i % 2 == 0 { + let c_tmp = c.extract(i); + c = c.replace(i, d.extract(i)); + d = d.replace(i, c_tmp); + } else { + m_e = m_e.replace(i, true); + } } - } - let m = c.lt(d); - assert_eq!(m_e, m); - assert_eq!(m.select(c, d), a); + let m = c.lt(d); + assert_eq!(m_e, m); + assert_eq!(m.select(c, d), a); + } } } } diff --git a/src/api/shuffle_bytes.rs b/src/api/shuffle_bytes.rs index 9de73e428..d4fa6a971 100644 --- a/src/api/shuffle_bytes.rs +++ b/src/api/shuffle_bytes.rs @@ -1,7 +1,7 @@ //! Shuffle bytes with run-time indices macro_rules! impl_shuffle_bytes { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Shuffles the bytes of the vector according to `indices`. #[inline] @@ -10,44 +10,46 @@ macro_rules! impl_shuffle_bytes { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _shuffle_bytes] { - use super::*; - #[test] - fn shuffle_bytes() { - let increasing = { - let mut v = $id::splat(0); - for i in 0..$id::lanes() { - v = v.replace(i, i as $elem_ty); - } - v - }; - let decreasing = { - let mut v = $id::splat(0); - for i in 0..$id::lanes() { - v = v.replace(i, ($id::lanes() - 1 - i) as $elem_ty); - } - v - }; + test_if! { + $test_tt: + interpolate_idents! { + mod [$id _shuffle_bytes] { + use super::*; + #[test] + fn shuffle_bytes() { + let increasing = { + let mut v = $id::splat(0); + for i in 0..$id::lanes() { + v = v.replace(i, i as $elem_ty); + } + v + }; + let decreasing = { + let mut v = $id::splat(0); + for i in 0..$id::lanes() { + v = v.replace(i, ($id::lanes() - 1 - i) as $elem_ty); + } + v + }; - assert_eq!(increasing.shuffle_bytes(increasing), increasing); - assert_eq!(decreasing.shuffle_bytes(increasing), decreasing); - assert_eq!(increasing.shuffle_bytes(decreasing), decreasing); - assert_eq!(decreasing.shuffle_bytes(decreasing), increasing); + assert_eq!(increasing.shuffle_bytes(increasing), increasing); + assert_eq!(decreasing.shuffle_bytes(increasing), decreasing); + assert_eq!(increasing.shuffle_bytes(decreasing), decreasing); + assert_eq!(decreasing.shuffle_bytes(decreasing), increasing); - for i in 0..$id::lanes() { - assert_eq!(increasing.shuffle_bytes($id::splat(i as $elem_ty)), - $id::splat(increasing.extract(i))); - assert_eq!(decreasing.shuffle_bytes($id::splat(i as $elem_ty)), - $id::splat(decreasing.extract(i))); + for i in 0..$id::lanes() { + assert_eq!(increasing.shuffle_bytes($id::splat(i as $elem_ty)), + $id::splat(increasing.extract(i))); + assert_eq!(decreasing.shuffle_bytes($id::splat(i as $elem_ty)), + $id::splat(decreasing.extract(i))); - assert_eq!($id::splat(i as $elem_ty).shuffle_bytes(increasing), - $id::splat(i as $elem_ty)); - assert_eq!($id::splat(i as $elem_ty).shuffle_bytes(decreasing), - $id::splat(i as $elem_ty)); - } + assert_eq!($id::splat(i as $elem_ty).shuffle_bytes(increasing), + $id::splat(i as $elem_ty)); + assert_eq!($id::splat(i as $elem_ty).shuffle_bytes(decreasing), + $id::splat(i as $elem_ty)); + } + } } } } diff --git a/src/api/slice/from_slice.rs b/src/api/slice/from_slice.rs index e705b74a0..d8b13bc1e 100644 --- a/src/api/slice/from_slice.rs +++ b/src/api/slice/from_slice.rs @@ -1,7 +1,7 @@ //! Implements methods to read a vector type from a slice. macro_rules! impl_slice_from_slice { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Instantiates a new vector with the values of the `slice`. /// @@ -70,98 +70,100 @@ macro_rules! impl_slice_from_slice { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _slice_from_slice] { - use super::*; - use iter::Iterator; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _slice_from_slice] { + use super::*; + use iter::Iterator; - #[test] - fn from_slice_unaligned() { - let mut unaligned = [42 as $elem_ty; $id::lanes() + 1]; - unaligned[0] = 0 as $elem_ty; - let vec = $id::from_slice_unaligned(&unaligned[1..]); - for (index, &b) in unaligned.iter().enumerate() { - if index == 0 { - assert_eq!(b, 0 as $elem_ty); - } else { - assert_eq!(b, vec.extract(index - 1)); + #[test] + fn from_slice_unaligned() { + let mut unaligned = [42 as $elem_ty; $id::lanes() + 1]; + unaligned[0] = 0 as $elem_ty; + let vec = $id::from_slice_unaligned(&unaligned[1..]); + for (index, &b) in unaligned.iter().enumerate() { + if index == 0 { + assert_eq!(b, 0 as $elem_ty); + } else { + assert_eq!(b, vec.extract(index - 1)); + } } } - } - #[test] - #[should_panic] - fn from_slice_unaligned_fail() { - let mut unaligned = [42 as $elem_ty; $id::lanes() + 1]; - unaligned[0] = 0 as $elem_ty; - let _vec = $id::from_slice_unaligned(&unaligned[2..]); - } + #[test] + #[should_panic] + fn from_slice_unaligned_fail() { + let mut unaligned = [42 as $elem_ty; $id::lanes() + 1]; + unaligned[0] = 0 as $elem_ty; + let _vec = $id::from_slice_unaligned(&unaligned[2..]); + } - union A { - data: [$elem_ty; 2 * $id::lanes()], - _vec: $id, - } + union A { + data: [$elem_ty; 2 * $id::lanes()], + _vec: $id, + } - #[test] - fn from_slice_aligned() { - let mut aligned = A { - data: [0 as $elem_ty; 2 * $id::lanes()], - }; - for i in $id::lanes()..(2 * $id::lanes()) { - unsafe { - aligned.data[[i]] = 42 as $elem_ty; + #[test] + fn from_slice_aligned() { + let mut aligned = A { + data: [0 as $elem_ty; 2 * $id::lanes()], + }; + for i in $id::lanes()..(2 * $id::lanes()) { + unsafe { + aligned.data[[i]] = 42 as $elem_ty; + } } - } - let vec = - unsafe { $id::from_slice_aligned(&aligned.data[$id::lanes()..]) }; - for (index, &b) in unsafe { aligned.data.iter().enumerate() } { - if index < $id::lanes() { - assert_eq!(b, 0 as $elem_ty); - } else { - assert_eq!(b, vec.extract(index - $id::lanes())); + let vec = + unsafe { $id::from_slice_aligned(&aligned.data[$id::lanes()..]) }; + for (index, &b) in unsafe { aligned.data.iter().enumerate() } { + if index < $id::lanes() { + assert_eq!(b, 0 as $elem_ty); + } else { + assert_eq!(b, vec.extract(index - $id::lanes())); + } } } - } - - #[test] - #[should_panic] - fn from_slice_aligned_fail_lanes() { - let aligned = A { - data: [0 as $elem_ty; 2 * $id::lanes()], - }; - let _vec = unsafe { - $id::from_slice_aligned(&aligned.data[2 * $id::lanes()..]) - }; - } - #[test] - #[should_panic] - fn from_slice_aligned_fail_align() { - unsafe { + #[test] + #[should_panic] + fn from_slice_aligned_fail_lanes() { let aligned = A { data: [0 as $elem_ty; 2 * $id::lanes()], }; + let _vec = unsafe { + $id::from_slice_aligned(&aligned.data[2 * $id::lanes()..]) + }; + } - // get a pointer to the front of data - let ptr: *const $elem_ty = aligned.data.as_ptr() as *const $elem_ty; - // offset pointer by one element - let ptr = ptr.wrapping_add(1); + #[test] + #[should_panic] + fn from_slice_aligned_fail_align() { + unsafe { + let aligned = A { + data: [0 as $elem_ty; 2 * $id::lanes()], + }; - if ptr.align_offset(mem::align_of::<$id>()) == 0 { - // the pointer is properly aligned, so from_slice_aligned - // won't fail here (e.g. this can happen for i128x1). So - // we panic to make the "should_fail" test pass: - panic!("ok"); - } + // get a pointer to the front of data + let ptr: *const $elem_ty = aligned.data.as_ptr() as *const $elem_ty; + // offset pointer by one element + let ptr = ptr.wrapping_add(1); - // create a slice - this is safe, because the elements - // of the slice exist, are properly initialized, and properly aligned: - let s: &[[$elem_ty]] = slice::from_raw_parts(ptr, $id::lanes()); - // this should always panic because the slice alignment does not match - // the alignment requirements for the vector type: - let _vec = $id::from_slice_aligned(s); + if ptr.align_offset(mem::align_of::<$id>()) == 0 { + // the pointer is properly aligned, so from_slice_aligned + // won't fail here (e.g. this can happen for i128x1). So + // we panic to make the "should_fail" test pass: + panic!("ok"); + } + + // create a slice - this is safe, because the elements + // of the slice exist, are properly initialized, and properly aligned: + let s: &[[$elem_ty]] = slice::from_raw_parts(ptr, $id::lanes()); + // this should always panic because the slice alignment does not match + // the alignment requirements for the vector type: + let _vec = $id::from_slice_aligned(s); + } } } } diff --git a/src/api/slice/write_to_slice.rs b/src/api/slice/write_to_slice.rs index 8d0d3457a..1e0b57d29 100644 --- a/src/api/slice/write_to_slice.rs +++ b/src/api/slice/write_to_slice.rs @@ -1,7 +1,7 @@ //! Implements methods to write a vector type to a slice. macro_rules! impl_slice_write_to_slice { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Writes the values of the vector to the `slice`. /// @@ -73,97 +73,98 @@ macro_rules! impl_slice_write_to_slice { } - #[cfg(test)] - interpolate_idents! { - mod [$id _slice_write_to_slice] { - use super::*; - use iter::Iterator; + test_if!{ + $test_tt: + interpolate_idents! { + mod [$id _slice_write_to_slice] { + use super::*; + use iter::Iterator; - #[test] - fn write_to_slice_unaligned() { - let mut unaligned = [0 as $elem_ty; $id::lanes() + 1]; - let vec = $id::splat(42 as $elem_ty); - vec.write_to_slice_unaligned(&mut unaligned[1..]); - for (index, &b) in unaligned.iter().enumerate() { - if index == 0 { - assert_eq!(b, 0 as $elem_ty); - } else { - assert_eq!(b, vec.extract(index - 1)); + #[test] + fn write_to_slice_unaligned() { + let mut unaligned = [0 as $elem_ty; $id::lanes() + 1]; + let vec = $id::splat(42 as $elem_ty); + vec.write_to_slice_unaligned(&mut unaligned[1..]); + for (index, &b) in unaligned.iter().enumerate() { + if index == 0 { + assert_eq!(b, 0 as $elem_ty); + } else { + assert_eq!(b, vec.extract(index - 1)); + } } } - } - #[test] - #[should_panic] - fn write_to_slice_unaligned_fail() { - let mut unaligned = [0 as $elem_ty; $id::lanes() + 1]; - let vec = $id::splat(42 as $elem_ty); - vec.write_to_slice_unaligned(&mut unaligned[2..]); - } + #[test] + #[should_panic] + fn write_to_slice_unaligned_fail() { + let mut unaligned = [0 as $elem_ty; $id::lanes() + 1]; + let vec = $id::splat(42 as $elem_ty); + vec.write_to_slice_unaligned(&mut unaligned[2..]); + } - union A { - data: [$elem_ty; 2 * $id::lanes()], - _vec: $id, - } + union A { + data: [$elem_ty; 2 * $id::lanes()], + _vec: $id, + } - #[test] - fn write_to_slice_aligned() { - let mut aligned = A { - data: [0 as $elem_ty; 2 * $id::lanes()], - }; - let vec = $id::splat(42 as $elem_ty); - unsafe { vec.write_to_slice_aligned(&mut aligned.data[$id::lanes()..]) }; - for (index, &b) in unsafe { aligned.data.iter().enumerate() } { - if index < $id::lanes() { - assert_eq!(b, 0 as $elem_ty); - } else { - assert_eq!(b, vec.extract(index - $id::lanes())); + #[test] + fn write_to_slice_aligned() { + let mut aligned = A { + data: [0 as $elem_ty; 2 * $id::lanes()], + }; + let vec = $id::splat(42 as $elem_ty); + unsafe { vec.write_to_slice_aligned(&mut aligned.data[$id::lanes()..]) }; + for (index, &b) in unsafe { aligned.data.iter().enumerate() } { + if index < $id::lanes() { + assert_eq!(b, 0 as $elem_ty); + } else { + assert_eq!(b, vec.extract(index - $id::lanes())); + } } } - } - - #[test] - #[should_panic] - fn write_to_slice_aligned_fail_lanes() { - let mut aligned = A { - data: [0 as $elem_ty; 2 * $id::lanes()], - }; - let vec = $id::splat(42 as $elem_ty); - unsafe { - vec.write_to_slice_aligned(&mut aligned.data[2 * $id::lanes()..]) - }; - } - #[test] - #[should_panic] - fn write_to_slice_aligned_fail_align() { - unsafe { + #[test] + #[should_panic] + fn write_to_slice_aligned_fail_lanes() { let mut aligned = A { data: [0 as $elem_ty; 2 * $id::lanes()], }; + let vec = $id::splat(42 as $elem_ty); + unsafe { + vec.write_to_slice_aligned(&mut aligned.data[2 * $id::lanes()..]) + }; + } - // get a pointer to the front of data - let ptr: *mut $elem_ty = aligned.data.as_mut_ptr() as *mut $elem_ty; - // offset pointer by one element - let ptr = ptr.wrapping_add(1); - - if ptr.align_offset(mem::align_of::<$id>()) == 0 { - // the pointer is properly aligned, so write_to_slice_aligned - // won't fail here (e.g. this can happen for i128x1). So - // we panic to make the "should_fail" test pass: - panic!("ok"); + #[test] + #[should_panic] + fn write_to_slice_aligned_fail_align() { + unsafe { + let mut aligned = A { + data: [0 as $elem_ty; 2 * $id::lanes()], + }; + + // get a pointer to the front of data + let ptr: *mut $elem_ty = aligned.data.as_mut_ptr() as *mut $elem_ty; + // offset pointer by one element + let ptr = ptr.wrapping_add(1); + + if ptr.align_offset(mem::align_of::<$id>()) == 0 { + // the pointer is properly aligned, so write_to_slice_aligned + // won't fail here (e.g. this can happen for i128x1). So + // we panic to make the "should_fail" test pass: + panic!("ok"); + } + + // create a slice - this is safe, because the elements + // of the slice exist, are properly initialized, and properly aligned: + let s: &mut [[$elem_ty]] = slice::from_raw_parts_mut(ptr, $id::lanes()); + // this should always panic because the slice alignment does not match + // the alignment requirements for the vector type: + let vec = $id::splat(42 as $elem_ty); + vec.write_to_slice_aligned(s); } - - // create a slice - this is safe, because the elements - // of the slice exist, are properly initialized, and properly aligned: - let s: &mut [[$elem_ty]] = slice::from_raw_parts_mut(ptr, $id::lanes()); - // this should always panic because the slice alignment does not match - // the alignment requirements for the vector type: - let vec = $id::splat(42 as $elem_ty); - vec.write_to_slice_aligned(s); } } - } } }; diff --git a/src/api/swap_bytes.rs b/src/api/swap_bytes.rs index 2a9326827..e9d0d9e06 100644 --- a/src/api/swap_bytes.rs +++ b/src/api/swap_bytes.rs @@ -1,7 +1,7 @@ //! Horizontal swap bytes macro_rules! impl_swap_bytes { - ([$elem_ty:ident; $elem_count:expr]: $id:ident) => { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Reverses the byte order of the vector. #[inline] @@ -42,83 +42,85 @@ macro_rules! impl_swap_bytes { } } - #[cfg(test)] - interpolate_idents! { - mod [$id _swap_bytes] { - use super::*; - - const BYTES: [u8; 64] = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - ]; - - macro_rules! swap { - ($func: ident) => {{ - // catch possible future >512 vectors - assert!(mem::size_of::<$id>() <= 64); - - let mut actual = BYTES; - let elems: &mut [[$elem_ty]] = unsafe { - slice::from_raw_parts_mut( - actual.as_mut_ptr() as *mut $elem_ty, - $id::lanes(), - ) - }; - - let vec = $id::from_slice_unaligned(elems); - vec.$func().write_to_slice_unaligned(elems); - - actual - }}; - } - - macro_rules! test_swap { - ($func: ident) => {{ - let actual = swap!($func); - let expected = - BYTES.iter().rev().skip(64 - mem::size_of::<$id>()); - - assert!(actual.iter().zip(expected).all(|(x, y)| x == y)); - }}; - } + test_if! { + $test_tt: + interpolate_idents! { + mod [$id _swap_bytes] { + use super::*; + + const BYTES: [u8; 64] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + ]; + + macro_rules! swap { + ($func: ident) => {{ + // catch possible future >512 vectors + assert!(mem::size_of::<$id>() <= 64); + + let mut actual = BYTES; + let elems: &mut [[$elem_ty]] = unsafe { + slice::from_raw_parts_mut( + actual.as_mut_ptr() as *mut $elem_ty, + $id::lanes(), + ) + }; + + let vec = $id::from_slice_unaligned(elems); + vec.$func().write_to_slice_unaligned(elems); + + actual + }}; + } - macro_rules! test_no_swap { - ($func: ident) => {{ - let actual = swap!($func); - let expected = BYTES.iter().take(mem::size_of::<$id>()); + macro_rules! test_swap { + ($func: ident) => {{ + let actual = swap!($func); + let expected = + BYTES.iter().rev().skip(64 - mem::size_of::<$id>()); - assert!(actual.iter().zip(expected).all(|(x, y)| x == y)); - }}; - } + assert!(actual.iter().zip(expected).all(|(x, y)| x == y)); + }}; + } - #[test] - fn swap_bytes() { - test_swap!(swap_bytes); - } + macro_rules! test_no_swap { + ($func: ident) => {{ + let actual = swap!($func); + let expected = BYTES.iter().take(mem::size_of::<$id>()); - #[test] - fn to_le() { - #[cfg(target_endian = "little")] - { - test_no_swap!(to_le); + assert!(actual.iter().zip(expected).all(|(x, y)| x == y)); + }}; } - #[cfg(not(target_endian = "little"))] - { - test_swap!(to_le); + + #[test] + fn swap_bytes() { + test_swap!(swap_bytes); } - } - #[test] - fn to_be() { - #[cfg(target_endian = "big")] - { - test_no_swap!(to_be); + #[test] + fn to_le() { + #[cfg(target_endian = "little")] + { + test_no_swap!(to_le); + } + #[cfg(not(target_endian = "little"))] + { + test_swap!(to_le); + } } - #[cfg(not(target_endian = "big"))] - { - test_swap!(to_be); + + #[test] + fn to_be() { + #[cfg(target_endian = "big")] + { + test_no_swap!(to_be); + } + #[cfg(not(target_endian = "big"))] + { + test_swap!(to_be); + } } } } diff --git a/src/lib.rs b/src/lib.rs index 619b8e117..f527c18f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -250,14 +250,14 @@ use core::{ ops, ptr, slice, }; +#[macro_use] +mod testing; + #[macro_use] mod api; mod codegen; mod sealed; -#[cfg(test)] -mod test_utils; - /// Packed SIMD vector type. /// /// # Examples diff --git a/src/testing.rs b/src/testing.rs new file mode 100644 index 000000000..f6427787d --- /dev/null +++ b/src/testing.rs @@ -0,0 +1,7 @@ +//! Testing macros and other utilities. + +#[macro_use] +mod macros; + +#[cfg(test)] +crate mod utils; diff --git a/src/testing/macros.rs b/src/testing/macros.rs new file mode 100644 index 000000000..01df1114c --- /dev/null +++ b/src/testing/macros.rs @@ -0,0 +1,28 @@ +//! Testing macros + +macro_rules! test_if { + ($cfg_tt:tt: $it:item) => { + #[cfg(any( + // Test everything if: + // + // * tests are enabled, + // * no features about exclusively testing + // specific vector classes are enabled + all(test, not(any( + test_v16, + test_v32, + test_v64, + test_v128, + test_v256, + test_v512, + test_none, + ))), + // Test if: + // + // * tests are enabled + // * a particular cfg token tree returns true + all(test, $cfg_tt), + ))] + $it + }; +} diff --git a/src/test_utils.rs b/src/testing/utils.rs similarity index 98% rename from src/test_utils.rs rename to src/testing/utils.rs index e3bcfcc6f..122efe7f9 100644 --- a/src/test_utils.rs +++ b/src/testing/utils.rs @@ -1,4 +1,6 @@ -//! Test utilities +//! Testing utilities + +#![allow(dead_code)] use crate::{cmp::PartialOrd, fmt::Debug, PartiallyOrdered}; diff --git a/src/v128.rs b/src/v128.rs index bfb06ee0d..301b249dd 100644 --- a/src/v128.rs +++ b/src/v128.rs @@ -2,78 +2,78 @@ use crate::*; -impl_i!([i8; 16]: i8x16, m8x16 | +impl_i!([i8; 16]: i8x16, m8x16 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: | /// A 128-bit vector with 16 `i8` lanes. ); -impl_u!([u8; 16]: u8x16, m8x16 | +impl_u!([u8; 16]: u8x16, m8x16 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: | /// A 128-bit vector with 16 `u8` lanes. ); -impl_m!([m8; 16]: m8x16 | i8 | +impl_m!([m8; 16]: m8x16 | i8 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: m16x16 | /// A 128-bit vector mask with 16 `m8` lanes. ); -impl_i!([i16; 8]: i16x8, m16x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_i!([i16; 8]: i16x8, m16x8 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7 | From: i8x8, u8x8 | /// A 128-bit vector with 8 `i16` lanes. ); -impl_u!([u16; 8]: u16x8, m16x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_u!([u16; 8]: u16x8, m16x8 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7 | From: u8x8 | /// A 128-bit vector with 8 `u16` lanes. ); -impl_m!([m16; 8]: m16x8 | i16 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_m!([m16; 8]: m16x8 | i16 | test_v128 | x0, x1, x2, x3, x4, x5, x6, x7 | From: m8x8, m32x8 | /// A 128-bit vector mask with 8 `m16` lanes. ); -impl_i!([i32; 4]: i32x4, m32x4 | x0, x1, x2, x3 | +impl_i!([i32; 4]: i32x4, m32x4 | test_v128 | x0, x1, x2, x3 | From: i8x4, u8x4, i16x4, u16x4 | /// A 128-bit vector with 4 `i32` lanes. ); -impl_u!([u32; 4]: u32x4, m32x4 | x0, x1, x2, x3 | +impl_u!([u32; 4]: u32x4, m32x4 | test_v128 | x0, x1, x2, x3 | From: u8x4, u16x4 | /// A 128-bit vector with 4 `u32` lanes. ); -impl_f!([f32; 4]: f32x4, m32x4 | x0, x1, x2, x3 | +impl_f!([f32; 4]: f32x4, m32x4 | test_v128 | x0, x1, x2, x3 | From: i8x4, u8x4, i16x4, u16x4 | /// A 128-bit vector with 4 `f32` lanes. ); -impl_m!([m32; 4]: m32x4 | i32 | x0, x1, x2, x3 | +impl_m!([m32; 4]: m32x4 | i32 | test_v128 | x0, x1, x2, x3 | From: m8x4, m16x4, m64x4 | /// A 128-bit vector mask with 4 `m32` lanes. ); -impl_i!([i64; 2]: i64x2, m64x2 | x0, x1 | +impl_i!([i64; 2]: i64x2, m64x2 | test_v128 | x0, x1 | From: i8x2, u8x2, i16x2, u16x2, i32x2, u32x2 | /// A 128-bit vector with 2 `i64` lanes. ); -impl_u!([u64; 2]: u64x2, m64x2 | x0, x1 | +impl_u!([u64; 2]: u64x2, m64x2 | test_v128 | x0, x1 | From: u8x2, u16x2, u32x2 | /// A 128-bit vector with 2 `u64` lanes. ); -impl_f!([f64; 2]: f64x2, m64x2 | x0, x1 | +impl_f!([f64; 2]: f64x2, m64x2 | test_v128 | x0, x1 | From: i8x2, u8x2, i16x2, u16x2, i32x2, u32x2, f32x2 | /// A 128-bit vector with 2 `f64` lanes. ); -impl_m!([m64; 2]: m64x2 | i64 | x0, x1 | +impl_m!([m64; 2]: m64x2 | i64 | test_v128 | x0, x1 | From: m8x2, m16x2, m32x2, m128x2 | /// A 128-bit vector mask with 2 `m64` lanes. ); -impl_i!([i128; 1]: i128x1, m128x1 | x0 | +impl_i!([i128; 1]: i128x1, m128x1 | test_v128 | x0 | From: /*i8x1, u8x1, i16x1, u16x1, i32x1, u32x1, i64x1, u64x1 */ | // FIXME: unary small vector types /// A 128-bit vector with 1 `i128` lane. ); -impl_u!([u128; 1]: u128x1, m128x1 | x0 | +impl_u!([u128; 1]: u128x1, m128x1 | test_v128 | x0 | From: /*u8x1, u16x1, u32x1, u64x1 */ | // FIXME: unary small vector types /// A 128-bit vector with 1 `u128` lane. ); -impl_m!([m128; 1]: m128x1 | i128 | x0 | +impl_m!([m128; 1]: m128x1 | i128 | test_v128 | x0 | From: /*m8x1, m16x1, m32x1, m64x1 */ | // FIXME: unary small vector types /// A 128-bit vector mask with 1 `m128` lane. ); diff --git a/src/v16.rs b/src/v16.rs index df2795ff2..100e3d91a 100644 --- a/src/v16.rs +++ b/src/v16.rs @@ -2,15 +2,15 @@ use crate::*; -impl_i!([i8; 2]: i8x2, m8x2 | x0, x1 | +impl_i!([i8; 2]: i8x2, m8x2 | test_v16 | x0, x1 | From: | /// A 16-bit vector with 2 `i8` lanes. ); -impl_u!([u8; 2]: u8x2, m8x2 | x0, x1 | +impl_u!([u8; 2]: u8x2, m8x2 | test_v16 | x0, x1 | From: | /// A 16-bit vector with 2 `u8` lanes. ); -impl_m!([m8; 2]: m8x2 | i8 | x0, x1 | +impl_m!([m8; 2]: m8x2 | i8 | test_v16 | x0, x1 | From: m16x2, m32x2, m64x2, m128x2 | /// A 16-bit vector mask with 2 `m8` lanes. ); diff --git a/src/v256.rs b/src/v256.rs index 86fcd0dc2..d9e358f2d 100644 --- a/src/v256.rs +++ b/src/v256.rs @@ -2,84 +2,84 @@ use crate::*; -impl_i!([i8; 32]: i8x32, m8x32 | +impl_i!([i8; 32]: i8x32, m8x32 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: | /// A 256-bit vector with 32 `i8` lanes. ); -impl_u!([u8; 32]: u8x32, m8x32 | +impl_u!([u8; 32]: u8x32, m8x32 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: | /// A 256-bit vector with 32 `u8` lanes. ); -impl_m!([m8; 32]: m8x32 | i8 | +impl_m!([m8; 32]: m8x32 | i8 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: | /// A 256-bit vector mask with 32 `m8` lanes. ); -impl_i!([i16; 16]: i16x16, m16x16 | +impl_i!([i16; 16]: i16x16, m16x16 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: i8x16, u8x16 | /// A 256-bit vector with 16 `i16` lanes. ); -impl_u!([u16; 16]: u16x16, m16x16 | +impl_u!([u16; 16]: u16x16, m16x16 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: u8x16 | /// A 256-bit vector with 16 `u16` lanes. ); -impl_m!([m16; 16]: m16x16 | i16 | +impl_m!([m16; 16]: m16x16 | i16 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: m8x16 | /// A 256-bit vector mask with 16 `m16` lanes. ); -impl_i!([i32; 8]: i32x8, m32x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_i!([i32; 8]: i32x8, m32x8 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7 | From: i8x8, u8x8, i16x8, u16x8 | /// A 256-bit vector with 8 `i32` lanes. ); -impl_u!([u32; 8]: u32x8, m32x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_u!([u32; 8]: u32x8, m32x8 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7 | From: u8x8, u16x8 | /// A 256-bit vector with 8 `u32` lanes. ); -impl_f!([f32; 8]: f32x8, m32x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_f!([f32; 8]: f32x8, m32x8 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7 | From: i8x8, u8x8, i16x8, u16x8 | /// A 256-bit vector with 8 `f32` lanes. ); -impl_m!([m32; 8]: m32x8 | i32 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_m!([m32; 8]: m32x8 | i32 | test_v256 | x0, x1, x2, x3, x4, x5, x6, x7 | From: m8x8, m16x8 | /// A 256-bit vector mask with 8 `m32` lanes. ); -impl_i!([i64; 4]: i64x4, m64x4 | x0, x1, x2, x3 | +impl_i!([i64; 4]: i64x4, m64x4 | test_v256 | x0, x1, x2, x3 | From: i8x4, u8x4, i16x4, u16x4, i32x4, u32x4 | /// A 256-bit vector with 4 `i64` lanes. ); -impl_u!([u64; 4]: u64x4, m64x4 | x0, x1, x2, x3 | +impl_u!([u64; 4]: u64x4, m64x4 | test_v256 | x0, x1, x2, x3 | From: u8x4, u16x4, u32x4 | /// A 256-bit vector with 4 `u64` lanes. ); -impl_f!([f64; 4]: f64x4, m64x4 | x0, x1, x2, x3 | +impl_f!([f64; 4]: f64x4, m64x4 | test_v256 | x0, x1, x2, x3 | From: i8x4, u8x4, i16x4, u16x4, i32x4, u32x4, f32x4 | /// A 256-bit vector with 4 `f64` lanes. ); -impl_m!([m64; 4]: m64x4 | i64 | x0, x1, x2, x3 | +impl_m!([m64; 4]: m64x4 | i64 | test_v256 | x0, x1, x2, x3 | From: m8x4, m16x4, m32x4 | /// A 256-bit vector mask with 4 `m64` lanes. ); -impl_i!([i128; 2]: i128x2, m128x2 | x0, x1 | +impl_i!([i128; 2]: i128x2, m128x2 | test_v256 | x0, x1 | From: i8x2, u8x2, i16x2, u16x2, i32x2, u32x2, i64x2, u64x2 | /// A 256-bit vector with 2 `i128` lanes. ); -impl_u!([u128; 2]: u128x2, m128x2 | x0, x1 | +impl_u!([u128; 2]: u128x2, m128x2 | test_v256 | x0, x1 | From: u8x2, u16x2, u32x2, u64x2 | /// A 256-bit vector with 2 `u128` lanes. ); -impl_m!([m128; 2]: m128x2 | i128 | x0, x1 | +impl_m!([m128; 2]: m128x2 | i128 | test_v256 | x0, x1 | From: m8x2, m16x2, m32x2, m64x2 | /// A 256-bit vector mask with 2 `m128` lanes. ); diff --git a/src/v32.rs b/src/v32.rs index 03557f105..e5b35d549 100644 --- a/src/v32.rs +++ b/src/v32.rs @@ -2,28 +2,28 @@ use crate::*; -impl_i!([i8; 4]: i8x4, m8x4 | x0, x1, x2, x3 | +impl_i!([i8; 4]: i8x4, m8x4 | test_v32 | x0, x1, x2, x3 | From: | /// A 32-bit vector with 4 `i8` lanes. ); -impl_u!([u8; 4]: u8x4, m8x4 | x0, x1, x2, x3 | +impl_u!([u8; 4]: u8x4, m8x4 | test_v32 | x0, x1, x2, x3 | From: | /// A 32-bit vector with 4 `u8` lanes. ); -impl_m!([m8; 4]: m8x4 | i8 | x0, x1, x2, x3 | +impl_m!([m8; 4]: m8x4 | i8 | test_v32 | x0, x1, x2, x3 | From: m16x4, m32x4, m64x4 | /// A 32-bit vector mask with 4 `m8` lanes. ); -impl_i!([i16; 2]: i16x2, m16x2 | x0, x1 | +impl_i!([i16; 2]: i16x2, m16x2 | test_v32 | x0, x1 | From: i8x2, u8x2 | /// A 32-bit vector with 2 `i16` lanes. ); -impl_u!([u16; 2]: u16x2, m16x2 | x0, x1 | +impl_u!([u16; 2]: u16x2, m16x2 | test_v32 | x0, x1 | From: u8x2 | /// A 32-bit vector with 2 `u16` lanes. ); -impl_m!([m16; 2]: m16x2 | i16 | x0, x1 | +impl_m!([m16; 2]: m16x2 | i16 | test_v32 | x0, x1 | From: m8x2, m32x2, m64x2, m128x2 | /// A 32-bit vector mask with 2 `m16` lanes. ); diff --git a/src/v512.rs b/src/v512.rs index bbe0ea023..08ac3b494 100644 --- a/src/v512.rs +++ b/src/v512.rs @@ -2,7 +2,7 @@ use crate::*; -impl_i!([i8; 64]: i8x64, m8x64 | +impl_i!([i8; 64]: i8x64, m8x64 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, @@ -10,7 +10,7 @@ impl_i!([i8; 64]: i8x64, m8x64 | From: | /// A 512-bit vector with 64 `i8` lanes. ); -impl_u!([u8; 64]: u8x64, m8x64 | +impl_u!([u8; 64]: u8x64, m8x64 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, @@ -18,7 +18,7 @@ impl_u!([u8; 64]: u8x64, m8x64 | From: | /// A 512-bit vector with 64 `u8` lanes. ); -impl_m!([m8; 64]: m8x64 | i8 | +impl_m!([m8; 64]: m8x64 | i8 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, @@ -27,72 +27,72 @@ impl_m!([m8; 64]: m8x64 | i8 | /// A 512-bit vector mask with 64 `m8` lanes. ); -impl_i!([i16; 32]: i16x32, m16x32 | +impl_i!([i16; 32]: i16x32, m16x32 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: i8x32, u8x32 | /// A 512-bit vector with 32 `i16` lanes. ); -impl_u!([u16; 32]: u16x32, m16x32 | +impl_u!([u16; 32]: u16x32, m16x32 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: u8x32 | /// A 512-bit vector with 32 `u16` lanes. ); -impl_m!([m16; 32]: m16x32 | i16 | +impl_m!([m16; 32]: m16x32 | i16 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31 | From: m8x32 | /// A 512-bit vector mask with 32 `m16` lanes. ); -impl_i!([i32; 16]: i32x16, m32x16 | +impl_i!([i32; 16]: i32x16, m32x16 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: i8x16, u8x16, i16x16, u16x16 | /// A 512-bit vector with 16 `i32` lanes. ); -impl_u!([u32; 16]: u32x16, m32x16 | +impl_u!([u32; 16]: u32x16, m32x16 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: u8x16, u16x16 | /// A 512-bit vector with 16 `u32` lanes. ); -impl_f!([f32; 16]: f32x16, m32x16 | +impl_f!([f32; 16]: f32x16, m32x16 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: i8x16, u8x16, i16x16, u16x16 | /// A 512-bit vector with 16 `f32` lanes. ); -impl_m!([m32; 16]: m32x16 | i32 | +impl_m!([m32; 16]: m32x16 | i32 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 | From: m8x16, m16x16 | /// A 512-bit vector mask with 16 `m32` lanes. ); -impl_i!([i64; 8]: i64x8, m64x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_i!([i64; 8]: i64x8, m64x8 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7 | From: i8x8, u8x8, i16x8, u16x8, i32x8, u32x8 | /// A 512-bit vector with 8 `i64` lanes. ); -impl_u!([u64; 8]: u64x8, m64x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_u!([u64; 8]: u64x8, m64x8 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7 | From: u8x8, u16x8, u32x8 | /// A 512-bit vector with 8 `u64` lanes. ); -impl_f!([f64; 8]: f64x8, m64x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_f!([f64; 8]: f64x8, m64x8 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7 | From: i8x8, u8x8, i16x8, u16x8, i32x8, u32x8, f32x8 | /// A 512-bit vector with 8 `f64` lanes. ); -impl_m!([m64; 8]: m64x8 | i64 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_m!([m64; 8]: m64x8 | i64 | test_v512 | x0, x1, x2, x3, x4, x5, x6, x7 | From: m8x8, m16x8, m32x8 | /// A 512-bit vector mask with 8 `m64` lanes. ); -impl_i!([i128; 4]: i128x4, m128x4 | x0, x1, x2, x3 | +impl_i!([i128; 4]: i128x4, m128x4 | test_v512 | x0, x1, x2, x3 | From: i8x4, u8x4, i16x4, u16x4, i32x4, u32x4, i64x4, u64x4 | /// A 512-bit vector with 4 `i128` lanes. ); -impl_u!([u128; 4]: u128x4, m128x4 | x0, x1, x2, x3 | +impl_u!([u128; 4]: u128x4, m128x4 | test_v512 | x0, x1, x2, x3 | From: u8x4, u16x4, u32x4, u64x4 | /// A 512-bit vector with 4 `u128` lanes. ); -impl_m!([m128; 4]: m128x4 | i128 | x0, x1, x2, x3 | +impl_m!([m128; 4]: m128x4 | i128 | test_v512 | x0, x1, x2, x3 | From: m8x4, m16x4, m32x4, m64x4 | /// A 512-bit vector mask with 4 `m128` lanes. ); diff --git a/src/v64.rs b/src/v64.rs index ec4bc6801..fc3c9c4b5 100644 --- a/src/v64.rs +++ b/src/v64.rs @@ -2,63 +2,63 @@ use crate::*; -impl_i!([i8; 8]: i8x8, m8x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_i!([i8; 8]: i8x8, m8x8 | test_v64 | x0, x1, x2, x3, x4, x5, x6, x7 | From: | /// A 64-bit vector with 8 `i8` lanes. ); -impl_u!([u8; 8]: u8x8, m8x8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_u!([u8; 8]: u8x8, m8x8 | test_v64 | x0, x1, x2, x3, x4, x5, x6, x7 | From: | /// A 64-bit vector with 8 `u8` lanes. ); -impl_m!([m8; 8]: m8x8 | i8 | x0, x1, x2, x3, x4, x5, x6, x7 | +impl_m!([m8; 8]: m8x8 | i8 | test_v64 | x0, x1, x2, x3, x4, x5, x6, x7 | From: m16x8, m32x8 | /// A 64-bit vector mask with 8 `m8` lanes. ); -impl_i!([i16; 4]: i16x4, m16x4 | x0, x1, x2, x3 | +impl_i!([i16; 4]: i16x4, m16x4 | test_v64 | x0, x1, x2, x3 | From: i8x4, u8x4 | /// A 64-bit vector with 4 `i16` lanes. ); -impl_u!([u16; 4]: u16x4, m16x4 | x0, x1, x2, x3 | +impl_u!([u16; 4]: u16x4, m16x4 | test_v64 | x0, x1, x2, x3 | From: u8x4 | /// A 64-bit vector with 4 `u16` lanes. ); -impl_m!([m16; 4]: m16x4 | i16 | x0, x1, x2, x3 | +impl_m!([m16; 4]: m16x4 | i16 | test_v64 | x0, x1, x2, x3 | From: m8x4, m32x4, m64x4 | /// A 64-bit vector mask with 4 `m16` lanes. ); -impl_i!([i32; 2]: i32x2, m32x2 | x0, x1 | +impl_i!([i32; 2]: i32x2, m32x2 | test_v64 | x0, x1 | From: i8x2, u8x2, i16x2, u16x2 | /// A 64-bit vector with 2 `i32` lanes. ); -impl_u!([u32; 2]: u32x2, m32x2 | x0, x1 | +impl_u!([u32; 2]: u32x2, m32x2 | test_v64 | x0, x1 | From: u8x2, u16x2 | /// A 64-bit vector with 2 `u32` lanes. ); -impl_m!([m32; 2]: m32x2 | i32 | x0, x1 | +impl_m!([m32; 2]: m32x2 | i32 | test_v64 | x0, x1 | From: m8x2, m16x2, m64x2, m128x2 | /// A 64-bit vector mask with 2 `m32` lanes. ); -impl_f!([f32; 2]: f32x2, m32x2 | x0, x1 | +impl_f!([f32; 2]: f32x2, m32x2 | test_v64 | x0, x1 | From: i8x2, u8x2, i16x2, u16x2 | /// A 64-bit vector with 2 `f32` lanes. ); /* -impl_i!([i64; 1]: i64x1, m64x1 | x0 | +impl_i!([i64; 1]: i64x1, m64x1 | test_v64 | x0 | From: /*i8x1, u8x1, i16x1, u16x1, i32x1, u32x1*/ | // FIXME: primitive to vector conversion /// A 64-bit vector with 1 `i64` lanes. ); -impl_u!([u64; 1]: u64x1, m64x1 | x0 | +impl_u!([u64; 1]: u64x1, m64x1 | test_v64 | x0 | From: /*u8x1, u16x1, u32x1*/ | // FIXME: primitive to vector conversion /// A 64-bit vector with 1 `u64` lanes. ); -impl_m!([m64; 1]: m64x1 | i64 | x0 | +impl_m!([m64; 1]: m64x1 | i64 | test_v64 | x0 | From: /*m8x1, m16x1, m32x1, */ m128x1 | // FIXME: unary small vector types /// A 64-bit vector mask with 1 `m64` lanes. ); -impl_f!([f64; 1]: f64x1, m64x1 | x0 | +impl_f!([f64; 1]: f64x1, m64x1 | test_v64 | x0 | From: /*i8x1, u8x1, i16x1, u16x1, i32x1, u32x1, f32x1*/ | // FIXME: unary small vector types /// A 64-bit vector with 1 `f64` lanes. );