@@ -244,6 +244,16 @@ extern "C" {
244
244
245
245
#[ link_name = "llvm.floor.v4f32" ]
246
246
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 ;
247
257
}
248
258
249
259
macro_rules! s_t_l {
@@ -351,6 +361,20 @@ mod sealed {
351
361
}
352
362
}
353
363
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
+
354
378
#[ inline( always) ]
355
379
unsafe fn load ( off : i32 , p : * const i8 ) -> u32x4 {
356
380
let addr = p. offset ( off as isize ) ;
@@ -430,6 +454,93 @@ mod sealed {
430
454
431
455
test_impl ! { vec_vcmpbfp( a: vector_float, b: vector_float) -> vector_signed_int [ vcmpbfp, vcmpbfp] }
432
456
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
+
433
544
test_impl ! { vec_vceil( a: vector_float) -> vector_float [ vceil, vrfip / xvrspip ] }
434
545
435
546
test_impl ! { vec_vavgsb( a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vavgsb, vavgsb ] }
@@ -1715,6 +1826,26 @@ where
1715
1826
a. vec_sum4s ( b)
1716
1827
}
1717
1828
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
+
1718
1849
#[ cfg( target_endian = "big" ) ]
1719
1850
mod endian {
1720
1851
use super :: * ;
@@ -1784,8 +1915,18 @@ mod tests {
1784
1915
let r : $ty_out = transmute( $fn( a, b) ) ;
1785
1916
assert_eq!( d, r) ;
1786
1917
}
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
+ }
1787
1928
}
1788
- }
1929
+ }
1789
1930
1790
1931
macro_rules! test_vec_1 {
1791
1932
{ $name: ident, $fn: ident, f32x4, [ $( $a: expr) ,+] , ~[ $( $d: expr) ,+] } => {
@@ -1927,6 +2068,150 @@ mod tests {
1927
2068
[ false , true , true , false ]
1928
2069
}
1929
2070
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
+
1930
2215
#[ simd_test( enable = "altivec" ) ]
1931
2216
unsafe fn test_vec_cmpb ( ) {
1932
2217
let a: vector_float = transmute ( f32x4:: new ( 0.1 , 0.5 , 0.6 , 0.9 ) ) ;
0 commit comments