From 3c31e6e2f9d40d90f6f8416f2cd2f85e72deebe0 Mon Sep 17 00:00:00 2001 From: "andrew@webrtc.org" Date: Thu, 11 Dec 2014 00:24:13 +0000 Subject: [PATCH] Add NEON intrinsics version for WebRtcSpl_MinValueW16Neon WebRtcSpl_MinValueW16Neon is added. SplTest in common_audio_unittests is passed on ARM32/ARM64 platforms. BUG=4002 R=andrew@webrtc.org, jridges@masque.com Change-Id: I33c3853766d7594ed121166288e5325a03b3d6fe Review URL: https://webrtc-codereview.appspot.com/32639004 Patch from Yang Zhang . git-svn-id: http://webrtc.googlecode.com/svn/trunk@7867 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../min_max_operations_neon.c | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/webrtc/common_audio/signal_processing/min_max_operations_neon.c b/webrtc/common_audio/signal_processing/min_max_operations_neon.c index aa6cf1fb3..704911e63 100644 --- a/webrtc/common_audio/signal_processing/min_max_operations_neon.c +++ b/webrtc/common_audio/signal_processing/min_max_operations_neon.c @@ -67,3 +67,43 @@ int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, int length) { return (int16_t)maximum; } +// Minimum value of word16 vector. NEON intrinsics version for +// ARM 32-bit/64-bit platforms. +int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, int length) { + int16_t minimum = WEBRTC_SPL_WORD16_MAX; + int i = 0; + int residual = length & 0x7; + + if (vector == NULL || length <= 0) { + return minimum; + } + + const int16_t* p_start = vector; + int16x8_t min16x8 = vdupq_n_s16(WEBRTC_SPL_WORD16_MAX); + + // First part, unroll the loop 8 times. + for (i = length - residual; i >0; i -= 8) { + int16x8_t in16x8 = vld1q_s16(p_start); + min16x8 = vminq_s16(min16x8, in16x8); + p_start += 8; + } + +#if defined(WEBRTC_ARCH_ARM64) + minimum = vminvq_s16(min16x8); +#else + int16x4_t min16x4 = vmin_s16(vget_low_s16(min16x8), vget_high_s16(min16x8)); + min16x4 = vpmin_s16(min16x4, min16x4); + min16x4 = vpmin_s16(min16x4, min16x4); + + minimum = vget_lane_s16(min16x4, 0); +#endif + + // Second part, do the remaining iterations (if any). + for (i = residual; i > 0; i--) { + if (*p_start < minimum) + minimum = *p_start; + p_start++; + } + return minimum; +} +