Skip to content

Commit 64bf5a5

Browse files
lu-zeroAmanieu
authored andcommitted
Add vec_all_eq and vec_any_eq
1 parent 2dfc447 commit 64bf5a5

File tree

1 file changed

+286
-1
lines changed

1 file changed

+286
-1
lines changed

crates/core_arch/src/powerpc/altivec.rs

Lines changed: 286 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,16 @@ extern "C" {
244244

245245
#[link_name = "llvm.floor.v4f32"]
246246
fn vfloor(a: vector_float) -> vector_float;
247+
248+
#[link_name = "llvm.ppc.altivec.vcmpequb.p"]
249+
fn vcmpequb_p(cr: i32, a: vector_unsigned_char, b: vector_unsigned_char) -> i32;
250+
#[link_name = "llvm.ppc.altivec.vcmpequh.p"]
251+
fn vcmpequh_p(cr: i32, a: vector_unsigned_short, b: vector_unsigned_short) -> i32;
252+
#[link_name = "llvm.ppc.altivec.vcmpequw.p"]
253+
fn vcmpequw_p(cr: i32, a: vector_unsigned_int, b: vector_unsigned_int) -> i32;
254+
255+
#[link_name = "llvm.ppc.altivec.vcmpeqfp.p"]
256+
fn vcmpeqfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
247257
}
248258

249259
macro_rules! s_t_l {
@@ -351,6 +361,20 @@ mod sealed {
351361
}
352362
}
353363

364+
macro_rules! impl_vec_any_all {
365+
([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident)) => {
366+
impl_vec_any_all! { [$Trait $m] ($b, $b, $h, $h, $w, $w) }
367+
};
368+
([$Trait:ident $m:ident] ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident)) => {
369+
impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char, vector_unsigned_char) -> bool }
370+
impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char, vector_signed_char) -> bool }
371+
impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short, vector_unsigned_short) -> bool }
372+
impl_vec_trait!{ [$Trait $m] $sh (vector_signed_short, vector_signed_short) -> bool }
373+
impl_vec_trait!{ [$Trait $m] $uw (vector_unsigned_int, vector_unsigned_int) -> bool }
374+
impl_vec_trait!{ [$Trait $m] $sw (vector_signed_int, vector_signed_int) -> bool }
375+
}
376+
}
377+
354378
#[inline(always)]
355379
unsafe fn load(off: i32, p: *const i8) -> u32x4 {
356380
let addr = p.offset(off as isize);
@@ -430,6 +454,93 @@ mod sealed {
430454

431455
test_impl! { vec_vcmpbfp(a: vector_float, b: vector_float) -> vector_signed_int [vcmpbfp, vcmpbfp] }
432456

457+
#[inline]
458+
#[target_feature(enable = "altivec")]
459+
#[cfg_attr(test, assert_instr(vcmpequb.))]
460+
unsafe fn vcmpequb_all(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
461+
vcmpequb_p(2, a, b) != 0
462+
}
463+
464+
#[inline]
465+
#[target_feature(enable = "altivec")]
466+
#[cfg_attr(test, assert_instr(vcmpequb.))]
467+
unsafe fn vcmpequb_any(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
468+
vcmpequb_p(1, a, b) != 0
469+
}
470+
471+
#[inline]
472+
#[target_feature(enable = "altivec")]
473+
#[cfg_attr(test, assert_instr(vcmpequh.))]
474+
unsafe fn vcmpequh_all(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
475+
vcmpequh_p(2, a, b) != 0
476+
}
477+
478+
#[inline]
479+
#[target_feature(enable = "altivec")]
480+
#[cfg_attr(test, assert_instr(vcmpequh.))]
481+
unsafe fn vcmpequh_any(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
482+
vcmpequh_p(1, a, b) != 0
483+
}
484+
485+
#[inline]
486+
#[target_feature(enable = "altivec")]
487+
#[cfg_attr(test, assert_instr(vcmpequw.))]
488+
unsafe fn vcmpequw_all(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
489+
vcmpequw_p(2, a, b) != 0
490+
}
491+
492+
#[inline]
493+
#[target_feature(enable = "altivec")]
494+
#[cfg_attr(test, assert_instr(vcmpequw.))]
495+
unsafe fn vcmpequw_any(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
496+
vcmpequw_p(1, a, b) != 0
497+
}
498+
499+
pub trait VectorAllEq<Other> {
500+
type Result;
501+
unsafe fn vec_all_eq(self, b: Other) -> Self::Result;
502+
}
503+
504+
impl_vec_any_all! { [VectorAllEq vec_all_eq] (vcmpequb_all, vcmpequh_all, vcmpequw_all) }
505+
506+
// TODO: vsx encoding
507+
#[inline]
508+
#[target_feature(enable = "altivec")]
509+
#[cfg_attr(test, assert_instr(vcmpeqfp.))]
510+
unsafe fn vcmpeqfp_all(a: vector_float, b: vector_float) -> bool {
511+
vcmpeqfp_p(2, a, b) != 0
512+
}
513+
514+
impl VectorAllEq<vector_float> for vector_float {
515+
type Result = bool;
516+
#[inline]
517+
unsafe fn vec_all_eq(self, b: vector_float) -> Self::Result {
518+
vcmpeqfp_all(self, b)
519+
}
520+
}
521+
522+
pub trait VectorAnyEq<Other> {
523+
type Result;
524+
unsafe fn vec_any_eq(self, b: Other) -> Self::Result;
525+
}
526+
527+
impl_vec_any_all! { [VectorAnyEq vec_any_eq] (vcmpequb_any, vcmpequh_any, vcmpequw_any) }
528+
529+
#[inline]
530+
#[target_feature(enable = "altivec")]
531+
#[cfg_attr(test, assert_instr(vcmpeqfp.))]
532+
unsafe fn vcmpeqfp_any(a: vector_float, b: vector_float) -> bool {
533+
vcmpeqfp_p(1, a, b) != 0
534+
}
535+
536+
impl VectorAnyEq<vector_float> for vector_float {
537+
type Result = bool;
538+
#[inline]
539+
unsafe fn vec_any_eq(self, b: vector_float) -> Self::Result {
540+
vcmpeqfp_any(self, b)
541+
}
542+
}
543+
433544
test_impl! { vec_vceil(a: vector_float) -> vector_float [vceil, vrfip / xvrspip ] }
434545

435546
test_impl! { vec_vavgsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vavgsb, vavgsb ] }
@@ -1715,6 +1826,26 @@ where
17151826
a.vec_sum4s(b)
17161827
}
17171828

1829+
/// Vector All Elements Equal
1830+
#[inline]
1831+
#[target_feature(enable = "altivec")]
1832+
pub unsafe fn vec_all_eq<T, U>(a: T, b: U) -> <T as sealed::VectorAllEq<U>>::Result
1833+
where
1834+
T: sealed::VectorAllEq<U>,
1835+
{
1836+
a.vec_all_eq(b)
1837+
}
1838+
1839+
/// Vector All Elements Equal
1840+
#[inline]
1841+
#[target_feature(enable = "altivec")]
1842+
pub unsafe fn vec_any_eq<T, U>(a: T, b: U) -> <T as sealed::VectorAnyEq<U>>::Result
1843+
where
1844+
T: sealed::VectorAnyEq<U>,
1845+
{
1846+
a.vec_any_eq(b)
1847+
}
1848+
17181849
#[cfg(target_endian = "big")]
17191850
mod endian {
17201851
use super::*;
@@ -1784,8 +1915,18 @@ mod tests {
17841915
let r : $ty_out = transmute($fn(a, b));
17851916
assert_eq!(d, r);
17861917
}
1918+
};
1919+
{ $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => {
1920+
#[simd_test(enable = "altivec")]
1921+
unsafe fn $name() {
1922+
let a: s_t_l!($ty) = transmute($ty::new($($a),+));
1923+
let b: s_t_l!($ty) = transmute($ty::new($($b),+));
1924+
1925+
let r : $ty_out = transmute($fn(a, b));
1926+
assert_eq!($d, r);
1927+
}
17871928
}
1788-
}
1929+
}
17891930

17901931
macro_rules! test_vec_1 {
17911932
{ $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => {
@@ -1927,6 +2068,150 @@ mod tests {
19272068
[false, true, true, false]
19282069
}
19292070

2071+
test_vec_2! { test_vec_all_eq_i8_false, vec_all_eq, i8x16 -> bool,
2072+
[1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2073+
[0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2074+
false
2075+
}
2076+
2077+
test_vec_2! { test_vec_all_eq_u8_false, vec_all_eq, u8x16 -> bool,
2078+
[1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2079+
[0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2080+
false
2081+
}
2082+
2083+
test_vec_2! { test_vec_all_eq_i16_false, vec_all_eq, i16x8 -> bool,
2084+
[1, -1, 0, 0, 0, 0, 0, 0],
2085+
[0, 0, -1, 1, 0, 0, 0, 0],
2086+
false
2087+
}
2088+
2089+
test_vec_2! { test_vec_all_eq_u16_false, vec_all_eq, u16x8 -> bool,
2090+
[1, 255, 0, 0, 0, 0, 0, 0],
2091+
[0, 0, 255, 1, 0, 0, 0, 0],
2092+
false
2093+
}
2094+
2095+
test_vec_2! { test_vec_all_eq_i32_false, vec_all_eq, i32x4 -> bool,
2096+
[1, -1, 0, 0],
2097+
[0, -1, 0, 1],
2098+
false
2099+
}
2100+
2101+
test_vec_2! { test_vec_all_eq_u32_false, vec_all_eq, u32x4 -> bool,
2102+
[1, 255, 0, 0],
2103+
[0, 255, 0, 1],
2104+
false
2105+
}
2106+
2107+
test_vec_2! { test_vec_all_eq_i8_true, vec_all_eq, i8x16 -> bool,
2108+
[0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2109+
[0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2110+
true
2111+
}
2112+
2113+
test_vec_2! { test_vec_all_eq_u8_true, vec_all_eq, u8x16 -> bool,
2114+
[1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2115+
[1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2116+
true
2117+
}
2118+
2119+
test_vec_2! { test_vec_all_eq_i16_true, vec_all_eq, i16x8 -> bool,
2120+
[1, -1, 1, 0, 0, 0, 0, 0],
2121+
[1, -1, 1, 0, 0, 0, 0, 0],
2122+
true
2123+
}
2124+
2125+
test_vec_2! { test_vec_all_eq_u16_true, vec_all_eq, u16x8 -> bool,
2126+
[1, 255, 1, 0, 0, 0, 0, 0],
2127+
[1, 255, 1, 0, 0, 0, 0, 0],
2128+
true
2129+
}
2130+
2131+
test_vec_2! { test_vec_all_eq_i32_true, vec_all_eq, i32x4 -> bool,
2132+
[1, -1, 0, 1],
2133+
[1, -1, 0, 1],
2134+
true
2135+
}
2136+
2137+
test_vec_2! { test_vec_all_eq_u32_true, vec_all_eq, u32x4 -> bool,
2138+
[1, 255, 0, 1],
2139+
[1, 255, 0, 1],
2140+
true
2141+
}
2142+
2143+
test_vec_2! { test_vec_any_eq_i8_false, vec_any_eq, i8x16 -> bool,
2144+
[1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2145+
[0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
2146+
false
2147+
}
2148+
2149+
test_vec_2! { test_vec_any_eq_u8_false, vec_any_eq, u8x16 -> bool,
2150+
[1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2151+
[0, 0, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
2152+
false
2153+
}
2154+
2155+
test_vec_2! { test_vec_any_eq_i16_false, vec_any_eq, i16x8 -> bool,
2156+
[1, -1, 0, 0, 0, 0, 0, 0],
2157+
[0, 0, -1, 1, 1, 1, 1, 1],
2158+
false
2159+
}
2160+
2161+
test_vec_2! { test_vec_any_eq_u16_false, vec_any_eq, u16x8 -> bool,
2162+
[1, 255, 0, 0, 0, 0, 0, 0],
2163+
[0, 0, 255, 1, 1, 1, 1, 1],
2164+
false
2165+
}
2166+
2167+
test_vec_2! { test_vec_any_eq_i32_false, vec_any_eq, i32x4 -> bool,
2168+
[1, -1, 0, 0],
2169+
[0, -2, 1, 1],
2170+
false
2171+
}
2172+
2173+
test_vec_2! { test_vec_any_eq_u32_false, vec_any_eq, u32x4 -> bool,
2174+
[1, 2, 1, 0],
2175+
[0, 255, 0, 1],
2176+
false
2177+
}
2178+
2179+
test_vec_2! { test_vec_any_eq_i8_true, vec_any_eq, i8x16 -> bool,
2180+
[1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2181+
[0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2182+
true
2183+
}
2184+
2185+
test_vec_2! { test_vec_any_eq_u8_true, vec_any_eq, u8x16 -> bool,
2186+
[0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2187+
[1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2188+
true
2189+
}
2190+
2191+
test_vec_2! { test_vec_any_eq_i16_true, vec_any_eq, i16x8 -> bool,
2192+
[0, -1, 1, 0, 0, 0, 0, 0],
2193+
[1, -1, 1, 0, 0, 0, 0, 0],
2194+
true
2195+
}
2196+
2197+
test_vec_2! { test_vec_any_eq_u16_true, vec_any_eq, u16x8 -> bool,
2198+
[0, 255, 1, 0, 0, 0, 0, 0],
2199+
[1, 255, 1, 0, 0, 0, 0, 0],
2200+
true
2201+
}
2202+
2203+
test_vec_2! { test_vec_any_eq_i32_true, vec_any_eq, i32x4 -> bool,
2204+
[0, -1, 0, 1],
2205+
[1, -1, 0, 1],
2206+
true
2207+
}
2208+
2209+
test_vec_2! { test_vec_any_eq_u32_true, vec_any_eq, u32x4 -> bool,
2210+
[0, 255, 0, 1],
2211+
[1, 255, 0, 1],
2212+
true
2213+
}
2214+
19302215
#[simd_test(enable = "altivec")]
19312216
unsafe fn test_vec_cmpb() {
19322217
let a: vector_float = transmute(f32x4::new(0.1, 0.5, 0.6, 0.9));

0 commit comments

Comments
 (0)