@@ -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
249259macro_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" ) ]
17191850mod 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