xref: /aosp_15_r20/external/webrtc/common_audio/signal_processing/filter_ar_fast_q12_mips.c (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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