@@ -80,6 +80,9 @@ extern "C" {
80
80
81
81
#[ link_name = "llvm.arm.smusdx" ]
82
82
fn arm_smusdx ( a : i32 , b : i32 ) -> i32 ;
83
+
84
+ #[ link_name = "llvm.arm.usad8" ]
85
+ fn arm_usad8 ( a : i32 , b : i32 ) -> u32 ;
83
86
}
84
87
85
88
/// Signed saturating addition
@@ -284,6 +287,7 @@ pub unsafe fn shsub16(a: int16x2_t, b: int16x2_t) -> int16x2_t {
284
287
/// res = a\[0\] * b\[0\] + a\[1\] * b\[1\]
285
288
///
286
289
/// and sets the Q flag if overflow occurs on the addition.
290
+ #[ inline]
287
291
#[ cfg_attr( test, assert_instr( smuad) ) ]
288
292
pub unsafe fn smuad ( a : int16x2_t , b : int16x2_t ) -> i32 {
289
293
arm_smuad ( :: mem:: transmute ( a) , :: mem:: transmute ( b) )
@@ -328,6 +332,30 @@ pub unsafe fn smusdx(a: int16x2_t, b: int16x2_t) -> i32 {
328
332
arm_smusdx ( :: mem:: transmute ( a) , :: mem:: transmute ( b) )
329
333
}
330
334
335
+ /// Sum of 8-bit absolute differences.
336
+ ///
337
+ /// Returns the 8-bit unsigned equivalent of
338
+ ///
339
+ /// res = abs(a\[0\] - b\[0\]) + abs(a\[1\] - b\[1\]) +\
340
+ /// (a\[2\] - b\[2\]) + (a\[3\] - b\[3\])
341
+ #[ inline]
342
+ #[ cfg_attr( test, assert_instr( usad8) ) ]
343
+ pub unsafe fn usad8 ( a : int8x4_t , b : int8x4_t ) -> u32 {
344
+ arm_usad8 ( :: mem:: transmute ( a) , :: mem:: transmute ( b) )
345
+ }
346
+
347
+ /// Sum of 8-bit absolute differences and constant.
348
+ ///
349
+ /// Returns the 8-bit unsigned equivalent of
350
+ ///
351
+ /// res = abs(a\[0\] - b\[0\]) + abs(a\[1\] - b\[1\]) +\
352
+ /// (a\[2\] - b\[2\]) + (a\[3\] - b\[3\]) + c
353
+ #[ inline]
354
+ #[ cfg_attr( test, assert_instr( usad8) ) ]
355
+ pub unsafe fn usad8a ( a : int8x4_t , b : int8x4_t , c : u32 ) -> u32 {
356
+ usad8 ( a, b) + c
357
+ }
358
+
331
359
#[ cfg( test) ]
332
360
mod tests {
333
361
use coresimd:: arm:: * ;
@@ -548,4 +576,25 @@ mod tests {
548
576
assert_eq ! ( r, -6 ) ;
549
577
}
550
578
}
579
+
580
+ #[ test]
581
+ fn usad8 ( ) {
582
+ unsafe {
583
+ let a = i8x4:: new ( 1 , 2 , 3 , 4 ) ;
584
+ let b = i8x4:: new ( 4 , 3 , 2 , 1 ) ;
585
+ let r = dsp:: usad8 ( :: mem:: transmute ( a) , :: mem:: transmute ( b) ) ;
586
+ assert_eq ! ( r, 8 ) ;
587
+ }
588
+ }
589
+
590
+ #[ test]
591
+ fn usad8a ( ) {
592
+ unsafe {
593
+ let a = i8x4:: new ( 1 , 2 , 3 , 4 ) ;
594
+ let b = i8x4:: new ( 4 , 3 , 2 , 1 ) ;
595
+ let c = 10 ;
596
+ let r = dsp:: usad8a ( :: mem:: transmute ( a) , :: mem:: transmute ( b) , c) ;
597
+ assert_eq ! ( r, 8 + c) ;
598
+ }
599
+ }
551
600
}
0 commit comments