@@ -192,6 +192,20 @@ extern "C" {
192
192
fn vadduhs ( a : vector_unsigned_short , b : vector_unsigned_short ) -> vector_unsigned_short ;
193
193
#[ link_name = "llvm.ppc.altivec.vadduws" ]
194
194
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 ;
195
209
}
196
210
197
211
macro_rules! s_t_l {
@@ -300,7 +314,7 @@ mod sealed {
300
314
}
301
315
}
302
316
} ;
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) ) => {
304
318
impl_vec_trait!{ [ $Trait $m] $ub ( vector_unsigned_char) -> vector_unsigned_char }
305
319
impl_vec_trait!{ [ $Trait $m] $sb ( vector_signed_char) -> vector_signed_char }
306
320
impl_vec_trait!{ [ $Trait $m] $uh ( vector_unsigned_short) -> vector_unsigned_short }
@@ -334,9 +348,34 @@ mod sealed {
334
348
} ;
335
349
( [ $Trait: ident $m: ident] ~( $fn: ident) ) => {
336
350
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) }
337
362
}
338
363
}
339
364
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
+
340
379
#[ inline]
341
380
#[ target_feature( enable = "altivec" ) ]
342
381
#[ cfg_attr( all( test, not( target_feature = "vsx" ) ) , assert_instr( vandc) ) ]
@@ -1240,6 +1279,16 @@ mod sealed {
1240
1279
vector_mladd ! { vector_signed_short, vector_signed_short, vector_signed_short }
1241
1280
}
1242
1281
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
+
1243
1292
/// Vector andc.
1244
1293
#[ inline]
1245
1294
#[ target_feature( enable = "altivec" ) ]
@@ -1574,6 +1623,42 @@ mod tests {
1574
1623
[ 0b00110011 , 0b11110011 , 0b00001100 , 0b00000000 ] ,
1575
1624
[ 0b00000000 , 0b11000000 , 0b00001100 , 0b00000000 ] }
1576
1625
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
+
1577
1662
macro_rules! test_vec_adds {
1578
1663
{ $name: ident, $ty: ident, [ $( $a: expr) ,+] , [ $( $b: expr) ,+] , [ $( $d: expr) ,+] } => {
1579
1664
test_vec_2! { $name, vec_adds, $ty, [ $( $a) ,+] , [ $( $b) ,+] , [ $( $d) ,+] }
0 commit comments