about summary refs log tree commit diff
path: root/library/stdarch
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2023-04-23 15:19:12 +0000
committerAmanieu d'Antras <amanieu@gmail.com>2023-04-24 19:02:22 -0700
commit9bf9dd4e4d64b0fda394d0ffc6e14ae0999807e4 (patch)
tree3e4351c60cf34ea6d221e6abbb9fdeac7e622dc1 /library/stdarch
parent24e69958b62fd25b1bbd15c8cddf1eed0e40355c (diff)
downloadrust-9bf9dd4e4d64b0fda394d0ffc6e14ae0999807e4.tar.gz
rust-9bf9dd4e4d64b0fda394d0ffc6e14ae0999807e4.zip
Add vec_lde
Diffstat (limited to 'library/stdarch')
-rw-r--r--library/stdarch/crates/core_arch/src/powerpc/altivec.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
index 1429d7023ae..06811aaee98 100644
--- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
+++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs
@@ -53,6 +53,14 @@ types! {
 extern "C" {
     #[link_name = "llvm.ppc.altivec.lvx"]
     fn lvx(p: *const i8) -> vector_unsigned_int;
+
+    #[link_name = "llvm.ppc.altivec.lvebx"]
+    fn lvebx(p: *const i8) -> vector_signed_char;
+    #[link_name = "llvm.ppc.altivec.lvehx"]
+    fn lvehx(p: *const i8) -> vector_signed_short;
+    #[link_name = "llvm.ppc.altivec.lvewx"]
+    fn lvewx(p: *const i8) -> vector_signed_int;
+
     #[link_name = "llvm.ppc.altivec.vperm"]
     fn vperm(
         a: vector_signed_int,
@@ -440,6 +448,43 @@ mod sealed {
 
     impl_vec_ld! { vec_ld_f32 f32 }
 
+    pub trait VectorLde {
+        type Result;
+        unsafe fn vec_lde(self, a: isize) -> Self::Result;
+    }
+
+    macro_rules! impl_vec_lde {
+        ($fun:ident $instr:ident $ty:ident) => {
+            #[inline]
+            #[target_feature(enable = "altivec")]
+            #[cfg_attr(test, assert_instr($instr))]
+            pub unsafe fn $fun(a: isize, b: *const $ty) -> t_t_l!($ty) {
+                let addr = (b as *const i8).offset(a);
+                transmute($instr(addr))
+            }
+
+            impl VectorLde for *const $ty {
+                type Result = t_t_l!($ty);
+                #[inline]
+                #[target_feature(enable = "altivec")]
+                unsafe fn vec_lde(self, a: isize) -> Self::Result {
+                    $fun(a, self)
+                }
+            }
+        };
+    }
+
+    impl_vec_lde! { vec_lde_u8 lvebx u8 }
+    impl_vec_lde! { vec_lde_i8 lvebx i8 }
+
+    impl_vec_lde! { vec_lde_u16 lvehx u16 }
+    impl_vec_lde! { vec_lde_i16 lvehx i16 }
+
+    impl_vec_lde! { vec_lde_u32 lvewx u32 }
+    impl_vec_lde! { vec_lde_i32 lvewx i32 }
+
+    impl_vec_lde! { vec_lde_f32 lvewx f32 }
+
     test_impl! { vec_floor(a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
 
     test_impl! { vec_vexptefp(a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1918,6 +1963,16 @@ where
     p.vec_ld(off)
 }
 
+/// Vector Load Element Indexed.
+#[inline]
+#[target_feature(enable = "altivec")]
+pub unsafe fn vec_lde<T>(off: isize, p: T) -> <T as sealed::VectorLde>::Result
+where
+    T: sealed::VectorLde,
+{
+    p.vec_lde(off)
+}
+
 /// Vector floor.
 #[inline]
 #[target_feature(enable = "altivec")]
@@ -2650,6 +2705,27 @@ mod tests {
         }
     }
 
+    #[simd_test(enable = "altivec")]
+    unsafe fn test_vec_lde() {
+        let pat = [u8x16::new(
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+        )];
+        for off in 0..16 {
+            let v: u8x16 = transmute(vec_lde(off, pat.as_ptr() as *const u8));
+            assert_eq!(off as u8, v.extract(off as _));
+        }
+        let pat = [u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)];
+        for off in 0..8 {
+            let v: u16x8 = transmute(vec_lde(off * 2, pat.as_ptr() as *const u8));
+            assert_eq!(off as u16, v.extract(off as _));
+        }
+        let pat = [u32x4::new(0, 1, 2, 3)];
+        for off in 0..4 {
+            let v: u32x4 = transmute(vec_lde(off * 4, pat.as_ptr() as *const u8));
+            assert_eq!(off as u32, v.extract(off as _));
+        }
+    }
+
     test_vec_1! { test_vec_floor, vec_floor, f32x4,
         [1.1, 1.9, -0.5, -0.9],
         [1.0, 1.0, -1.0, -1.0]