1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/checks.h"
12 #include "common_audio/signal_processing/include/signal_processing_library.h"
13
WebRtcSpl_FilterARFastQ12(const int16_t * data_in,int16_t * data_out,const int16_t * __restrict coefficients,size_t coefficients_length,size_t data_length)14 void WebRtcSpl_FilterARFastQ12(const int16_t* data_in,
15 int16_t* data_out,
16 const int16_t* __restrict coefficients,
17 size_t coefficients_length,
18 size_t data_length) {
19 int r0, r1, r2, r3;
20 int coef0, offset;
21 int i, j, k;
22 int coefptr, outptr, tmpout, inptr;
23 #if !defined(MIPS_DSP_R1_LE)
24 int max16 = 0x7FFF;
25 int min16 = 0xFFFF8000;
26 #endif // #if !defined(MIPS_DSP_R1_LE)
27
28 RTC_DCHECK_GT(data_length, 0);
29 RTC_DCHECK_GT(coefficients_length, 1);
30
31 __asm __volatile (
32 ".set push \n\t"
33 ".set noreorder \n\t"
34 "addiu %[i], %[data_length], 0 \n\t"
35 "lh %[coef0], 0(%[coefficients]) \n\t"
36 "addiu %[j], %[coefficients_length], -1 \n\t"
37 "andi %[k], %[j], 1 \n\t"
38 "sll %[offset], %[j], 1 \n\t"
39 "subu %[outptr], %[data_out], %[offset] \n\t"
40 "addiu %[inptr], %[data_in], 0 \n\t"
41 "bgtz %[k], 3f \n\t"
42 " addu %[coefptr], %[coefficients], %[offset] \n\t"
43 "1: \n\t"
44 "lh %[r0], 0(%[inptr]) \n\t"
45 "addiu %[i], %[i], -1 \n\t"
46 "addiu %[tmpout], %[outptr], 0 \n\t"
47 "mult %[r0], %[coef0] \n\t"
48 "2: \n\t"
49 "lh %[r0], 0(%[tmpout]) \n\t"
50 "lh %[r1], 0(%[coefptr]) \n\t"
51 "lh %[r2], 2(%[tmpout]) \n\t"
52 "lh %[r3], -2(%[coefptr]) \n\t"
53 "addiu %[tmpout], %[tmpout], 4 \n\t"
54 "msub %[r0], %[r1] \n\t"
55 "msub %[r2], %[r3] \n\t"
56 "addiu %[j], %[j], -2 \n\t"
57 "bgtz %[j], 2b \n\t"
58 " addiu %[coefptr], %[coefptr], -4 \n\t"
59 #if defined(MIPS_DSP_R1_LE)
60 "extr_r.w %[r0], $ac0, 12 \n\t"
61 #else // #if defined(MIPS_DSP_R1_LE)
62 "mflo %[r0] \n\t"
63 #endif // #if defined(MIPS_DSP_R1_LE)
64 "addu %[coefptr], %[coefficients], %[offset] \n\t"
65 "addiu %[inptr], %[inptr], 2 \n\t"
66 "addiu %[j], %[coefficients_length], -1 \n\t"
67 #if defined(MIPS_DSP_R1_LE)
68 "shll_s.w %[r0], %[r0], 16 \n\t"
69 "sra %[r0], %[r0], 16 \n\t"
70 #else // #if defined(MIPS_DSP_R1_LE)
71 "addiu %[r0], %[r0], 2048 \n\t"
72 "sra %[r0], %[r0], 12 \n\t"
73 "slt %[r1], %[max16], %[r0] \n\t"
74 "movn %[r0], %[max16], %[r1] \n\t"
75 "slt %[r1], %[r0], %[min16] \n\t"
76 "movn %[r0], %[min16], %[r1] \n\t"
77 #endif // #if defined(MIPS_DSP_R1_LE)
78 "sh %[r0], 0(%[tmpout]) \n\t"
79 "bgtz %[i], 1b \n\t"
80 " addiu %[outptr], %[outptr], 2 \n\t"
81 "b 5f \n\t"
82 " nop \n\t"
83 "3: \n\t"
84 "lh %[r0], 0(%[inptr]) \n\t"
85 "addiu %[i], %[i], -1 \n\t"
86 "addiu %[tmpout], %[outptr], 0 \n\t"
87 "mult %[r0], %[coef0] \n\t"
88 "4: \n\t"
89 "lh %[r0], 0(%[tmpout]) \n\t"
90 "lh %[r1], 0(%[coefptr]) \n\t"
91 "lh %[r2], 2(%[tmpout]) \n\t"
92 "lh %[r3], -2(%[coefptr]) \n\t"
93 "addiu %[tmpout], %[tmpout], 4 \n\t"
94 "msub %[r0], %[r1] \n\t"
95 "msub %[r2], %[r3] \n\t"
96 "addiu %[j], %[j], -2 \n\t"
97 "bgtz %[j], 4b \n\t"
98 " addiu %[coefptr], %[coefptr], -4 \n\t"
99 "lh %[r0], 0(%[tmpout]) \n\t"
100 "lh %[r1], 0(%[coefptr]) \n\t"
101 "msub %[r0], %[r1] \n\t"
102 #if defined(MIPS_DSP_R1_LE)
103 "extr_r.w %[r0], $ac0, 12 \n\t"
104 #else // #if defined(MIPS_DSP_R1_LE)
105 "mflo %[r0] \n\t"
106 #endif // #if defined(MIPS_DSP_R1_LE)
107 "addu %[coefptr], %[coefficients], %[offset] \n\t"
108 "addiu %[inptr], %[inptr], 2 \n\t"
109 "addiu %[j], %[coefficients_length], -1 \n\t"
110 #if defined(MIPS_DSP_R1_LE)
111 "shll_s.w %[r0], %[r0], 16 \n\t"
112 "sra %[r0], %[r0], 16 \n\t"
113 #else // #if defined(MIPS_DSP_R1_LE)
114 "addiu %[r0], %[r0], 2048 \n\t"
115 "sra %[r0], %[r0], 12 \n\t"
116 "slt %[r1], %[max16], %[r0] \n\t"
117 "movn %[r0], %[max16], %[r1] \n\t"
118 "slt %[r1], %[r0], %[min16] \n\t"
119 "movn %[r0], %[min16], %[r1] \n\t"
120 #endif // #if defined(MIPS_DSP_R1_LE)
121 "sh %[r0], 2(%[tmpout]) \n\t"
122 "bgtz %[i], 3b \n\t"
123 " addiu %[outptr], %[outptr], 2 \n\t"
124 "5: \n\t"
125 ".set pop \n\t"
126 : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0),
127 [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
128 [coef0] "=&r" (coef0), [offset] "=&r" (offset),
129 [outptr] "=&r" (outptr), [inptr] "=&r" (inptr),
130 [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout)
131 : [coefficients] "r" (coefficients), [data_length] "r" (data_length),
132 [coefficients_length] "r" (coefficients_length),
133 #if !defined(MIPS_DSP_R1_LE)
134 [max16] "r" (max16), [min16] "r" (min16),
135 #endif
136 [data_out] "r" (data_out), [data_in] "r" (data_in)
137 : "hi", "lo", "memory"
138 );
139 }
140
141