Skip to content

Commit fe6046b

Browse files
lu-zeroAmanieu
authored andcommitted
Add vec_lde
1 parent 313a8bd commit fe6046b

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ types! {
5353
extern "C" {
5454
#[link_name = "llvm.ppc.altivec.lvx"]
5555
fn lvx(p: *const i8) -> vector_unsigned_int;
56+
57+
#[link_name = "llvm.ppc.altivec.lvebx"]
58+
fn lvebx(p: *const i8) -> vector_signed_char;
59+
#[link_name = "llvm.ppc.altivec.lvehx"]
60+
fn lvehx(p: *const i8) -> vector_signed_short;
61+
#[link_name = "llvm.ppc.altivec.lvewx"]
62+
fn lvewx(p: *const i8) -> vector_signed_int;
63+
5664
#[link_name = "llvm.ppc.altivec.vperm"]
5765
fn vperm(
5866
a: vector_signed_int,
@@ -440,6 +448,43 @@ mod sealed {
440448

441449
impl_vec_ld! { vec_ld_f32 f32 }
442450

451+
pub trait VectorLde {
452+
type Result;
453+
unsafe fn vec_lde(self, a: isize) -> Self::Result;
454+
}
455+
456+
macro_rules! impl_vec_lde {
457+
($fun:ident $instr:ident $ty:ident) => {
458+
#[inline]
459+
#[target_feature(enable = "altivec")]
460+
#[cfg_attr(test, assert_instr($instr))]
461+
pub unsafe fn $fun(a: isize, b: *const $ty) -> t_t_l!($ty) {
462+
let addr = (b as *const i8).offset(a);
463+
transmute($instr(addr))
464+
}
465+
466+
impl VectorLde for *const $ty {
467+
type Result = t_t_l!($ty);
468+
#[inline]
469+
#[target_feature(enable = "altivec")]
470+
unsafe fn vec_lde(self, a: isize) -> Self::Result {
471+
$fun(a, self)
472+
}
473+
}
474+
};
475+
}
476+
477+
impl_vec_lde! { vec_lde_u8 lvebx u8 }
478+
impl_vec_lde! { vec_lde_i8 lvebx i8 }
479+
480+
impl_vec_lde! { vec_lde_u16 lvehx u16 }
481+
impl_vec_lde! { vec_lde_i16 lvehx i16 }
482+
483+
impl_vec_lde! { vec_lde_u32 lvewx u32 }
484+
impl_vec_lde! { vec_lde_i32 lvewx i32 }
485+
486+
impl_vec_lde! { vec_lde_f32 lvewx f32 }
487+
443488
test_impl! { vec_floor(a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
444489

445490
test_impl! { vec_vexptefp(a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1918,6 +1963,16 @@ where
19181963
p.vec_ld(off)
19191964
}
19201965

1966+
/// Vector Load Element Indexed.
1967+
#[inline]
1968+
#[target_feature(enable = "altivec")]
1969+
pub unsafe fn vec_lde<T>(off: isize, p: T) -> <T as sealed::VectorLde>::Result
1970+
where
1971+
T: sealed::VectorLde,
1972+
{
1973+
p.vec_lde(off)
1974+
}
1975+
19211976
/// Vector floor.
19221977
#[inline]
19231978
#[target_feature(enable = "altivec")]
@@ -2650,6 +2705,27 @@ mod tests {
26502705
}
26512706
}
26522707

2708+
#[simd_test(enable = "altivec")]
2709+
unsafe fn test_vec_lde() {
2710+
let pat = [u8x16::new(
2711+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2712+
)];
2713+
for off in 0..16 {
2714+
let v: u8x16 = transmute(vec_lde(off, pat.as_ptr() as *const u8));
2715+
assert_eq!(off as u8, v.extract(off as _));
2716+
}
2717+
let pat = [u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)];
2718+
for off in 0..8 {
2719+
let v: u16x8 = transmute(vec_lde(off * 2, pat.as_ptr() as *const u8));
2720+
assert_eq!(off as u16, v.extract(off as _));
2721+
}
2722+
let pat = [u32x4::new(0, 1, 2, 3)];
2723+
for off in 0..4 {
2724+
let v: u32x4 = transmute(vec_lde(off * 4, pat.as_ptr() as *const u8));
2725+
assert_eq!(off as u32, v.extract(off as _));
2726+
}
2727+
}
2728+
26532729
test_vec_1! { test_vec_floor, vec_floor, f32x4,
26542730
[1.1, 1.9, -0.5, -0.9],
26552731
[1.0, 1.0, -1.0, -1.0]

0 commit comments

Comments
 (0)