summaryrefslogtreecommitdiff
path: root/third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c')
-rw-r--r--third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c b/third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c
new file mode 100644
index 00000000..03847018
--- /dev/null
+++ b/third_party/webrtc/src/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <assert.h>
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+void WebRtcSpl_FilterARFastQ12(const int16_t* data_in,
+ int16_t* data_out,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ size_t data_length) {
+ int r0, r1, r2, r3;
+ int coef0, offset;
+ int i, j, k;
+ int coefptr, outptr, tmpout, inptr;
+#if !defined(MIPS_DSP_R1_LE)
+ int max16 = 0x7FFF;
+ int min16 = 0xFFFF8000;
+#endif // #if !defined(MIPS_DSP_R1_LE)
+
+ assert(data_length > 0);
+ assert(coefficients_length > 1);
+
+ __asm __volatile (
+ ".set push \n\t"
+ ".set noreorder \n\t"
+ "addiu %[i], %[data_length], 0 \n\t"
+ "lh %[coef0], 0(%[coefficients]) \n\t"
+ "addiu %[j], %[coefficients_length], -1 \n\t"
+ "andi %[k], %[j], 1 \n\t"
+ "sll %[offset], %[j], 1 \n\t"
+ "subu %[outptr], %[data_out], %[offset] \n\t"
+ "addiu %[inptr], %[data_in], 0 \n\t"
+ "bgtz %[k], 3f \n\t"
+ " addu %[coefptr], %[coefficients], %[offset] \n\t"
+ "1: \n\t"
+ "lh %[r0], 0(%[inptr]) \n\t"
+ "addiu %[i], %[i], -1 \n\t"
+ "addiu %[tmpout], %[outptr], 0 \n\t"
+ "mult %[r0], %[coef0] \n\t"
+ "2: \n\t"
+ "lh %[r0], 0(%[tmpout]) \n\t"
+ "lh %[r1], 0(%[coefptr]) \n\t"
+ "lh %[r2], 2(%[tmpout]) \n\t"
+ "lh %[r3], -2(%[coefptr]) \n\t"
+ "addiu %[tmpout], %[tmpout], 4 \n\t"
+ "msub %[r0], %[r1] \n\t"
+ "msub %[r2], %[r3] \n\t"
+ "addiu %[j], %[j], -2 \n\t"
+ "bgtz %[j], 2b \n\t"
+ " addiu %[coefptr], %[coefptr], -4 \n\t"
+#if defined(MIPS_DSP_R1_LE)
+ "extr_r.w %[r0], $ac0, 12 \n\t"
+#else // #if defined(MIPS_DSP_R1_LE)
+ "mflo %[r0] \n\t"
+#endif // #if defined(MIPS_DSP_R1_LE)
+ "addu %[coefptr], %[coefficients], %[offset] \n\t"
+ "addiu %[inptr], %[inptr], 2 \n\t"
+ "addiu %[j], %[coefficients_length], -1 \n\t"
+#if defined(MIPS_DSP_R1_LE)
+ "shll_s.w %[r0], %[r0], 16 \n\t"
+ "sra %[r0], %[r0], 16 \n\t"
+#else // #if defined(MIPS_DSP_R1_LE)
+ "addiu %[r0], %[r0], 2048 \n\t"
+ "sra %[r0], %[r0], 12 \n\t"
+ "slt %[r1], %[max16], %[r0] \n\t"
+ "movn %[r0], %[max16], %[r1] \n\t"
+ "slt %[r1], %[r0], %[min16] \n\t"
+ "movn %[r0], %[min16], %[r1] \n\t"
+#endif // #if defined(MIPS_DSP_R1_LE)
+ "sh %[r0], 0(%[tmpout]) \n\t"
+ "bgtz %[i], 1b \n\t"
+ " addiu %[outptr], %[outptr], 2 \n\t"
+ "b 5f \n\t"
+ " nop \n\t"
+ "3: \n\t"
+ "lh %[r0], 0(%[inptr]) \n\t"
+ "addiu %[i], %[i], -1 \n\t"
+ "addiu %[tmpout], %[outptr], 0 \n\t"
+ "mult %[r0], %[coef0] \n\t"
+ "4: \n\t"
+ "lh %[r0], 0(%[tmpout]) \n\t"
+ "lh %[r1], 0(%[coefptr]) \n\t"
+ "lh %[r2], 2(%[tmpout]) \n\t"
+ "lh %[r3], -2(%[coefptr]) \n\t"
+ "addiu %[tmpout], %[tmpout], 4 \n\t"
+ "msub %[r0], %[r1] \n\t"
+ "msub %[r2], %[r3] \n\t"
+ "addiu %[j], %[j], -2 \n\t"
+ "bgtz %[j], 4b \n\t"
+ " addiu %[coefptr], %[coefptr], -4 \n\t"
+ "lh %[r0], 0(%[tmpout]) \n\t"
+ "lh %[r1], 0(%[coefptr]) \n\t"
+ "msub %[r0], %[r1] \n\t"
+#if defined(MIPS_DSP_R1_LE)
+ "extr_r.w %[r0], $ac0, 12 \n\t"
+#else // #if defined(MIPS_DSP_R1_LE)
+ "mflo %[r0] \n\t"
+#endif // #if defined(MIPS_DSP_R1_LE)
+ "addu %[coefptr], %[coefficients], %[offset] \n\t"
+ "addiu %[inptr], %[inptr], 2 \n\t"
+ "addiu %[j], %[coefficients_length], -1 \n\t"
+#if defined(MIPS_DSP_R1_LE)
+ "shll_s.w %[r0], %[r0], 16 \n\t"
+ "sra %[r0], %[r0], 16 \n\t"
+#else // #if defined(MIPS_DSP_R1_LE)
+ "addiu %[r0], %[r0], 2048 \n\t"
+ "sra %[r0], %[r0], 12 \n\t"
+ "slt %[r1], %[max16], %[r0] \n\t"
+ "movn %[r0], %[max16], %[r1] \n\t"
+ "slt %[r1], %[r0], %[min16] \n\t"
+ "movn %[r0], %[min16], %[r1] \n\t"
+#endif // #if defined(MIPS_DSP_R1_LE)
+ "sh %[r0], 2(%[tmpout]) \n\t"
+ "bgtz %[i], 3b \n\t"
+ " addiu %[outptr], %[outptr], 2 \n\t"
+ "5: \n\t"
+ ".set pop \n\t"
+ : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0),
+ [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
+ [coef0] "=&r" (coef0), [offset] "=&r" (offset),
+ [outptr] "=&r" (outptr), [inptr] "=&r" (inptr),
+ [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout)
+ : [coefficients] "r" (coefficients), [data_length] "r" (data_length),
+ [coefficients_length] "r" (coefficients_length),
+#if !defined(MIPS_DSP_R1_LE)
+ [max16] "r" (max16), [min16] "r" (min16),
+#endif
+ [data_out] "r" (data_out), [data_in] "r" (data_in)
+ : "hi", "lo", "memory"
+ );
+}
+