Skip to content

Commit ff28479

Browse files
lu-zerognzlbg
authored andcommitted
Add Altivec vec_avg
1 parent 7269815 commit ff28479

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,20 @@ extern "C" {
192192
fn vadduhs(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
193193
#[link_name = "llvm.ppc.altivec.vadduws"]
194194
fn vadduws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
195+
196+
#[link_name = "llvm.ppc.altivec.vavgsb"]
197+
fn vavgsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
198+
#[link_name = "llvm.ppc.altivec.vavgsh"]
199+
fn vavgsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
200+
#[link_name = "llvm.ppc.altivec.vavgsw"]
201+
fn vavgsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
202+
203+
#[link_name = "llvm.ppc.altivec.vavgub"]
204+
fn vavgub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
205+
#[link_name = "llvm.ppc.altivec.vavguh"]
206+
fn vavguh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
207+
#[link_name = "llvm.ppc.altivec.vavguw"]
208+
fn vavguw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
195209
}
196210

197211
macro_rules! s_t_l {
@@ -300,7 +314,7 @@ mod sealed {
300314
}
301315
}
302316
};
303-
([$Trait:ident $m:ident] ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident, $sf: ident)) => {
317+
([$Trait:ident $m:ident] 1 ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident, $sf: ident)) => {
304318
impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char) -> vector_unsigned_char }
305319
impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char) -> vector_signed_char }
306320
impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short) -> vector_unsigned_short }
@@ -334,9 +348,34 @@ mod sealed {
334348
};
335349
([$Trait:ident $m:ident] ~($fn:ident)) => {
336350
impl_vec_trait!{ [$Trait $m] ~($fn, $fn, $fn, $fn, $fn, $fn) }
351+
};
352+
([$Trait:ident $m:ident] 2 ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident)) => {
353+
impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
354+
impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char, vector_signed_char) -> vector_signed_char }
355+
impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
356+
impl_vec_trait!{ [$Trait $m] $sh (vector_signed_short, vector_signed_short) -> vector_signed_short }
357+
impl_vec_trait!{ [$Trait $m] $uw (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
358+
impl_vec_trait!{ [$Trait $m] $sw (vector_signed_int, vector_signed_int) -> vector_signed_int }
359+
};
360+
([$Trait:ident $m:ident] 2 ($fn:ident)) => {
361+
impl_vec_trait!{ [$Trait $m] ($fn, $fn, $fn, $fn, $fn, $fn) }
337362
}
338363
}
339364

365+
test_impl! { vec_vavgsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vavgsb, vavgsb ] }
366+
test_impl! { vec_vavgsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vavgsh, vavgsh ] }
367+
test_impl! { vec_vavgsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vavgsw, vavgsw ] }
368+
test_impl! { vec_vavgub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vavgub, vavgub ] }
369+
test_impl! { vec_vavguh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vavguh, vavguh ] }
370+
test_impl! { vec_vavguw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vavguw, vavguw ] }
371+
372+
pub trait VectorAvg<Other> {
373+
type Result;
374+
unsafe fn vec_avg(self, b: Other) -> Self::Result;
375+
}
376+
377+
impl_vec_trait! { [VectorAvg vec_avg] 2 (vec_vavgub, vec_vavgsb, vec_vavguh, vec_vavgsh, vec_vavguw, vec_vavgsw) }
378+
340379
#[inline]
341380
#[target_feature(enable = "altivec")]
342381
#[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vandc))]
@@ -1240,6 +1279,16 @@ mod sealed {
12401279
vector_mladd! { vector_signed_short, vector_signed_short, vector_signed_short }
12411280
}
12421281

1282+
/// Vector avg.
1283+
#[inline]
1284+
#[target_feature(enable = "altivec")]
1285+
pub unsafe fn vec_avg<T, U>(a: T, b: U) -> <T as sealed::VectorAvg<U>>::Result
1286+
where
1287+
T: sealed::VectorAvg<U>,
1288+
{
1289+
a.vec_avg(b)
1290+
}
1291+
12431292
/// Vector andc.
12441293
#[inline]
12451294
#[target_feature(enable = "altivec")]
@@ -1574,6 +1623,42 @@ mod tests {
15741623
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
15751624
[0b00000000, 0b11000000, 0b00001100, 0b00000000] }
15761625

1626+
macro_rules! test_vec_avg {
1627+
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
1628+
test_vec_2! {$name, vec_avg, $ty, [$($a),+], [$($b),+], [$($d),+] }
1629+
}
1630+
}
1631+
1632+
test_vec_avg! { test_vec_avg_i32x4, i32x4,
1633+
[i32::min_value(), i32::max_value(), 1, -1],
1634+
[-1, 1, 1, -1],
1635+
[-1073741824, 1073741824, 1, -1] }
1636+
1637+
test_vec_avg! { test_vec_avg_u32x4, u32x4,
1638+
[u32::max_value(), 0, 1, 2],
1639+
[2, 1, 0, 0],
1640+
[2147483649, 1, 1, 1] }
1641+
1642+
test_vec_avg! { test_vec_avg_i16x8, i16x8,
1643+
[i16::min_value(), i16::max_value(), 1, -1, 0, 0, 0, 0],
1644+
[-1, 1, 1, -1, 0, 0, 0, 0],
1645+
[-16384, 16384, 1, -1, 0, 0, 0, 0] }
1646+
1647+
test_vec_avg! { test_vec_avg_u16x8, u16x8,
1648+
[u16::max_value(), 0, 1, 2, 0, 0, 0, 0],
1649+
[2, 1, 0, 0, 0, 0, 0, 0],
1650+
[32769, 1, 1, 1, 0, 0, 0, 0] }
1651+
1652+
test_vec_avg! { test_vec_avg_i8x16, i8x16,
1653+
[i8::min_value(), i8::max_value(), 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1654+
[-1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1655+
[-64, 64, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
1656+
1657+
test_vec_avg! { test_vec_avg_u8x16, u8x16,
1658+
[u8::max_value(), 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1659+
[2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1660+
[129, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
1661+
15771662
macro_rules! test_vec_adds {
15781663
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
15791664
test_vec_2! {$name, vec_adds, $ty, [$($a),+], [$($b),+], [$($d),+] }

0 commit comments

Comments
 (0)