Skip to content

Commit 2b239c1

Browse files
committed
Add Altivec vec_ld
1 parent 410f295 commit 2b239c1

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,32 @@ macro_rules! s_t_l {
270270
};
271271
}
272272

273+
macro_rules! t_t_l {
274+
(i32) => {
275+
vector_signed_int
276+
};
277+
(i16) => {
278+
vector_signed_short
279+
};
280+
(i8) => {
281+
vector_signed_char
282+
};
283+
284+
(u32) => {
285+
vector_unsigned_int
286+
};
287+
(u16) => {
288+
vector_unsigned_short
289+
};
290+
(u8) => {
291+
vector_unsigned_char
292+
};
293+
294+
(f32) => {
295+
vector_float
296+
};
297+
}
298+
273299
macro_rules! impl_from {
274300
($s: ident) => {
275301
impl From<$s> for s_t_l!($s) {
@@ -412,6 +438,52 @@ mod sealed {
412438
}
413439
}
414440

441+
#[inline(always)]
442+
unsafe fn load(off: i32, p: *const i8) -> u32x4 {
443+
let addr = p.offset(off as isize);
444+
445+
*(addr as *const u32x4)
446+
}
447+
448+
pub trait VectorLd {
449+
type Result;
450+
unsafe fn vec_ld(self, off: i32) -> Self::Result;
451+
}
452+
453+
macro_rules! impl_vec_ld {
454+
($fun:ident $ty:ident [$instr:ident]) => {
455+
#[inline]
456+
#[target_feature(enable = "altivec")]
457+
#[cfg_attr(test, assert_instr($instr))]
458+
pub unsafe fn $fun(off: i32, p: *const $ty) -> t_t_l!($ty) {
459+
transmute(load(off, p as *const i8))
460+
}
461+
462+
impl VectorLd for *const $ty {
463+
type Result = t_t_l!($ty);
464+
#[inline]
465+
#[target_feature(enable = "altivec")]
466+
unsafe fn vec_ld(self, off: i32) -> Self::Result {
467+
$fun(off, self)
468+
}
469+
}
470+
};
471+
($fun:ident $ty:ident) => {
472+
impl_vec_ld! { $fun $ty [lvx] }
473+
};
474+
}
475+
476+
impl_vec_ld! { vec_ld_u8 u8 }
477+
impl_vec_ld! { vec_ld_i8 i8 }
478+
479+
impl_vec_ld! { vec_ld_u16 u16 }
480+
impl_vec_ld! { vec_ld_i16 i16 }
481+
482+
impl_vec_ld! { vec_ld_u32 u32 }
483+
impl_vec_ld! { vec_ld_i32 i32 }
484+
485+
impl_vec_ld! { vec_ld_f32 f32 }
486+
415487
test_impl! { vec_floor(a: vector_float) -> vector_float [ vfloor, vrfim / xvrspim ] }
416488

417489
test_impl! { vec_vexptefp(a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
@@ -1376,6 +1448,16 @@ mod sealed {
13761448
vector_mladd! { vector_signed_short, vector_signed_short, vector_signed_short }
13771449
}
13781450

1451+
/// Vector ld.
1452+
#[inline]
1453+
#[target_feature(enable = "altivec")]
1454+
pub unsafe fn vec_ld<T>(off: i32, p: T) -> <T as sealed::VectorLd>::Result
1455+
where
1456+
T: sealed::VectorLd,
1457+
{
1458+
p.vec_ld(off)
1459+
}
1460+
13791461
/// Vector floor.
13801462
#[inline]
13811463
#[target_feature(enable = "altivec")]
@@ -1812,6 +1894,23 @@ mod tests {
18121894
}
18131895
}
18141896

1897+
#[simd_test(enable = "altivec")]
1898+
unsafe fn test_vec_ld() {
1899+
let pat = [
1900+
u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
1901+
u8x16::new(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31)
1902+
];
1903+
1904+
for off in 0..16 {
1905+
let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off)));
1906+
assert_eq!(v, u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
1907+
}
1908+
for off in 16..32 {
1909+
let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off)));
1910+
assert_eq!(v, u8x16::new(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31));
1911+
}
1912+
}
1913+
18151914
test_vec_1! { test_vec_floor, vec_floor, f32x4,
18161915
[1.1, 1.9, -0.5, -0.9],
18171916
[1.0, 1.0, -1.0, -1.0]

0 commit comments

Comments
 (0)