Skip to content

Commit e430d84

Browse files
committed
Add vec_xl
1 parent a2c08cc commit e430d84

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

crates/core_arch/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
proc_macro_hygiene,
1313
stmt_expr_attributes,
1414
core_intrinsics,
15+
intrinsics,
1516
no_core,
1617
rustc_attrs,
1718
stdsimd,

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
use crate::{
1717
core_arch::{simd::*, simd_llvm::*},
18+
mem,
1819
mem::transmute,
20+
ptr,
1921
};
2022

2123
#[cfg(test)]
@@ -534,6 +536,60 @@ mod sealed {
534536

535537
impl_vec_lde! { vec_lde_f32 lvewx f32 }
536538

539+
pub trait VectorXl {
540+
type Result;
541+
unsafe fn vec_xl(self, a: isize) -> Self::Result;
542+
}
543+
544+
macro_rules! impl_vec_xl {
545+
($fun:ident $notpwr9:ident / $pwr9:ident $ty:ident) => {
546+
#[inline]
547+
#[target_feature(enable = "altivec")]
548+
#[cfg_attr(
549+
all(test, not(target_feature = "power9-altivec")),
550+
assert_instr($notpwr9)
551+
)]
552+
#[cfg_attr(all(test, target_feature = "power9-altivec"), assert_instr($pwr9))]
553+
pub unsafe fn $fun(a: isize, b: *const $ty) -> t_t_l!($ty) {
554+
let addr = (b as *const u8).offset(a);
555+
556+
// Workaround ptr::copy_nonoverlapping not being inlined
557+
extern "rust-intrinsic" {
558+
#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
559+
#[rustc_nounwind]
560+
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
561+
}
562+
563+
let mut r = mem::MaybeUninit::uninit();
564+
565+
copy_nonoverlapping(
566+
addr,
567+
r.as_mut_ptr() as *mut u8,
568+
mem::size_of::<t_t_l!($ty)>(),
569+
);
570+
571+
r.assume_init()
572+
}
573+
574+
impl VectorXl for *const $ty {
575+
type Result = t_t_l!($ty);
576+
#[inline]
577+
#[target_feature(enable = "altivec")]
578+
unsafe fn vec_xl(self, a: isize) -> Self::Result {
579+
$fun(a, self)
580+
}
581+
}
582+
};
583+
}
584+
585+
impl_vec_xl! { vec_xl_i8 lxvd2x / lxv i8 }
586+
impl_vec_xl! { vec_xl_u8 lxvd2x / lxv u8 }
587+
impl_vec_xl! { vec_xl_i16 lxvd2x / lxv i16 }
588+
impl_vec_xl! { vec_xl_u16 lxvd2x / lxv u16 }
589+
impl_vec_xl! { vec_xl_i32 lxvd2x / lxv i32 }
590+
impl_vec_xl! { vec_xl_u32 lxvd2x / lxv u32 }
591+
impl_vec_xl! { vec_xl_f32 lxvd2x / lxv f32 }
592+
537593
test_impl! { vec_floor(a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
538594

539595
test_impl! { vec_vexptefp(a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -2507,6 +2563,16 @@ where
25072563
p.vec_lde(off)
25082564
}
25092565

2566+
/// VSX Unaligned Load
2567+
#[inline]
2568+
#[target_feature(enable = "altivec")]
2569+
pub unsafe fn vec_xl<T>(off: isize, p: T) -> <T as sealed::VectorXl>::Result
2570+
where
2571+
T: sealed::VectorXl,
2572+
{
2573+
p.vec_xl(off)
2574+
}
2575+
25102576
/// Vector Base-2 Logarithm Estimate
25112577
#[inline]
25122578
#[target_feature(enable = "altivec")]
@@ -3302,6 +3368,24 @@ mod tests {
33023368
}
33033369
}
33043370

3371+
#[simd_test(enable = "altivec")]
3372+
unsafe fn test_vec_xl() {
3373+
let pat = [
3374+
u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
3375+
u8x16::new(
3376+
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3377+
),
3378+
];
3379+
3380+
for off in 0..16 {
3381+
let val: u8x16 = transmute(vec_xl(0, (pat.as_ptr() as *const u8).offset(off)));
3382+
for i in 0..16 {
3383+
let v = val.extract(i);
3384+
assert_eq!(off as usize + i, v as usize);
3385+
}
3386+
}
3387+
}
3388+
33053389
#[simd_test(enable = "altivec")]
33063390
unsafe fn test_vec_ldl() {
33073391
let pat = [

0 commit comments

Comments
 (0)