summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/core_arch/src/powerpc/vsx.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /library/stdarch/crates/core_arch/src/powerpc/vsx.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/stdarch/crates/core_arch/src/powerpc/vsx.rs')
-rw-r--r--library/stdarch/crates/core_arch/src/powerpc/vsx.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/powerpc/vsx.rs b/library/stdarch/crates/core_arch/src/powerpc/vsx.rs
new file mode 100644
index 000000000..3141bc8bc
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/powerpc/vsx.rs
@@ -0,0 +1,118 @@
+//! PowerPC Vector Scalar eXtensions (VSX) intrinsics.
+//!
+//! The references are: [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA
+//! NVlink)] and [POWER ISA v3.0B (for POWER9)].
+//!
+//! [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA NVlink)]: https://ibm.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u
+//! [POWER ISA v3.0B (for POWER9)]: https://ibm.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv
+
+#![allow(non_camel_case_types)]
+
+use crate::core_arch::simd_llvm::*;
+
+#[cfg(test)]
+use stdarch_test::assert_instr;
+
+use crate::mem;
+
+types! {
+ // pub struct vector_Float16 = f16x8;
+ /// PowerPC-specific 128-bit wide vector of two packed `i64`
+ pub struct vector_signed_long(i64, i64);
+ /// PowerPC-specific 128-bit wide vector of two packed `u64`
+ pub struct vector_unsigned_long(u64, u64);
+ /// PowerPC-specific 128-bit wide vector mask of two `i64`
+ pub struct vector_bool_long(i64, i64);
+ /// PowerPC-specific 128-bit wide vector of two packed `f64`
+ pub struct vector_double(f64, f64);
+ // pub struct vector_signed_long_long = vector_signed_long;
+ // pub struct vector_unsigned_long_long = vector_unsigned_long;
+ // pub struct vector_bool_long_long = vector_bool_long;
+ // pub struct vector_signed___int128 = i128x1;
+ // pub struct vector_unsigned___int128 = i128x1;
+}
+
+mod sealed {
+ use super::*;
+ use crate::core_arch::simd::*;
+
+ pub trait VectorPermDI {
+ unsafe fn vec_xxpermdi(self, b: Self, dm: u8) -> Self;
+ }
+
+ // xxpermdi has an big-endian bias and extended mnemonics
+ #[inline]
+ #[target_feature(enable = "vsx")]
+ #[cfg_attr(all(test, target_endian = "little"), assert_instr(xxmrgld, dm = 0x0))]
+ #[cfg_attr(all(test, target_endian = "big"), assert_instr(xxspltd, dm = 0x0))]
+ unsafe fn xxpermdi(a: i64x2, b: i64x2, dm: u8) -> i64x2 {
+ match dm & 0b11 {
+ 0 => simd_shuffle2!(a, b, [0b00, 0b10]),
+ 1 => simd_shuffle2!(a, b, [0b01, 0b10]),
+ 2 => simd_shuffle2!(a, b, [0b00, 0b11]),
+ _ => simd_shuffle2!(a, b, [0b01, 0b11]),
+ }
+ }
+
+ macro_rules! vec_xxpermdi {
+ {$impl: ident} => {
+ impl VectorPermDI for $impl {
+ #[inline]
+ #[target_feature(enable = "vsx")]
+ unsafe fn vec_xxpermdi(self, b: Self, dm: u8) -> Self {
+ mem::transmute(xxpermdi(mem::transmute(self), mem::transmute(b), dm))
+ }
+ }
+ }
+ }
+
+ vec_xxpermdi! { vector_unsigned_long }
+ vec_xxpermdi! { vector_signed_long }
+ vec_xxpermdi! { vector_bool_long }
+ vec_xxpermdi! { vector_double }
+}
+
+/// Vector permute.
+#[inline]
+#[target_feature(enable = "vsx")]
+//#[rustc_legacy_const_generics(2)]
+pub unsafe fn vec_xxpermdi<T, const DM: i32>(a: T, b: T) -> T
+where
+ T: sealed::VectorPermDI,
+{
+ static_assert_imm2!(DM);
+ a.vec_xxpermdi(b, DM as u8)
+}
+
+#[cfg(test)]
+mod tests {
+ #[cfg(target_arch = "powerpc")]
+ use crate::core_arch::arch::powerpc::*;
+
+ #[cfg(target_arch = "powerpc64")]
+ use crate::core_arch::arch::powerpc64::*;
+
+ use super::mem;
+ use crate::core_arch::simd::*;
+ use stdarch_test::simd_test;
+
+ macro_rules! test_vec_xxpermdi {
+ {$name:ident, $shorttype:ident, $longtype:ident, [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
+ #[simd_test(enable = "vsx")]
+ unsafe fn $name() {
+ let a: $longtype = mem::transmute($shorttype::new($($a),+, $($b),+));
+ let b = mem::transmute($shorttype::new($($c),+, $($d),+));
+
+ assert_eq!($shorttype::new($($a),+, $($c),+), mem::transmute(vec_xxpermdi::<_, 0>(a, b)));
+ assert_eq!($shorttype::new($($b),+, $($c),+), mem::transmute(vec_xxpermdi::<_, 1>(a, b)));
+ assert_eq!($shorttype::new($($a),+, $($d),+), mem::transmute(vec_xxpermdi::<_, 2>(a, b)));
+ assert_eq!($shorttype::new($($b),+, $($d),+), mem::transmute(vec_xxpermdi::<_, 3>(a, b)));
+ }
+ }
+ }
+
+ test_vec_xxpermdi! {test_vec_xxpermdi_u64x2, u64x2, vector_unsigned_long, [0], [1], [2], [3]}
+ test_vec_xxpermdi! {test_vec_xxpermdi_i64x2, i64x2, vector_signed_long, [0], [-1], [2], [-3]}
+ test_vec_xxpermdi! {test_vec_xxpermdi_m64x2, m64x2, vector_bool_long, [false], [true], [false], [true]}
+ test_vec_xxpermdi! {test_vec_xxpermdi_f64x2, f64x2, vector_double, [0.0], [1.0], [2.0], [3.0]}
+}