@@ -80,6 +80,9 @@ extern "C" {
8080
8181 #[ link_name = "llvm.arm.smusdx" ]
8282 fn arm_smusdx ( a : i32 , b : i32 ) -> i32 ;
83+
84+ #[ link_name = "llvm.arm.usad8" ]
85+ fn arm_usad8 ( a : i32 , b : i32 ) -> u32 ;
8386}
8487
8588/// Signed saturating addition
@@ -284,6 +287,7 @@ pub unsafe fn shsub16(a: int16x2_t, b: int16x2_t) -> int16x2_t {
284287/// res = a\[0\] * b\[0\] + a\[1\] * b\[1\]
285288///
286289/// and sets the Q flag if overflow occurs on the addition.
290+ #[ inline]
287291#[ cfg_attr( test, assert_instr( smuad) ) ]
288292pub unsafe fn smuad ( a : int16x2_t , b : int16x2_t ) -> i32 {
289293 arm_smuad ( :: mem:: transmute ( a) , :: mem:: transmute ( b) )
@@ -328,6 +332,30 @@ pub unsafe fn smusdx(a: int16x2_t, b: int16x2_t) -> i32 {
328332 arm_smusdx ( :: mem:: transmute ( a) , :: mem:: transmute ( b) )
329333}
330334
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+
331359#[ cfg( test) ]
332360mod tests {
333361 use coresimd:: arm:: * ;
@@ -548,4 +576,25 @@ mod tests {
548576 assert_eq ! ( r, -6 ) ;
549577 }
550578 }
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+ }
551600}
0 commit comments