]> git.sesse.net Git - ffmpeg/blob - libavcodec/mips/sbrdsp_mips.c
Merge commit 'b704b648f9ecb830874627db958a37e004107d1b'
[ffmpeg] / libavcodec / mips / sbrdsp_mips.c
1 /*
2  * Copyright (c) 2012
3  *      MIPS Technologies, Inc., California.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
14  *    contributors may be used to endorse or promote products derived from
15  *    this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Authors:  Darko Laus      (darko@mips.com)
30  *           Djordje Pesut   (djordje@mips.com)
31  *           Mirjana Vulin   (mvulin@mips.com)
32  *
33  * AAC Spectral Band Replication decoding functions optimized for MIPS
34  *
35  * This file is part of FFmpeg.
36  *
37  * FFmpeg is free software; you can redistribute it and/or
38  * modify it under the terms of the GNU Lesser General Public
39  * License as published by the Free Software Foundation; either
40  * version 2.1 of the License, or (at your option) any later version.
41  *
42  * FFmpeg is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
45  * Lesser General Public License for more details.
46  *
47  * You should have received a copy of the GNU Lesser General Public
48  * License along with FFmpeg; if not, write to the Free Software
49  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
50  */
51
52 /**
53  * @file
54  * Reference: libavcodec/sbrdsp.c
55  */
56
57 #include "config.h"
58 #include "libavcodec/sbrdsp.h"
59
60 #if HAVE_INLINE_ASM
61 static void sbr_neg_odd_64_mips(float *x)
62 {
63     int Temp1, Temp2, Temp3, Temp4, Temp5;
64     float *x1    = &x[1];
65     float *x_end = x1 + 64;
66
67     /* loop unrolled 4 times */
68     __asm__ volatile (
69         "lui    %[Temp5],   0x8000                  \n\t"
70     "1:                                             \n\t"
71         "lw     %[Temp1],   0(%[x1])                \n\t"
72         "lw     %[Temp2],   8(%[x1])                \n\t"
73         "lw     %[Temp3],   16(%[x1])               \n\t"
74         "lw     %[Temp4],   24(%[x1])               \n\t"
75         "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
76         "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
77         "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
78         "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
79         "sw     %[Temp1],   0(%[x1])                \n\t"
80         "sw     %[Temp2],   8(%[x1])                \n\t"
81         "sw     %[Temp3],   16(%[x1])               \n\t"
82         "sw     %[Temp4],   24(%[x1])               \n\t"
83         "addiu  %[x1],      %[x1],      32          \n\t"
84         "bne    %[x1],      %[x_end],   1b          \n\t"
85
86         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
87           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
88           [Temp5]"=&r"(Temp5), [x1]"+r"(x1)
89         : [x_end]"r"(x_end)
90         : "memory"
91     );
92 }
93
94 static void sbr_qmf_pre_shuffle_mips(float *z)
95 {
96     int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6;
97     float *z1 = &z[66];
98     float *z2 = &z[59];
99     float *z3 = &z[2];
100     float *z4 = z1 + 60;
101
102     /* loop unrolled 5 times */
103     __asm__ volatile (
104         "lui    %[Temp6],   0x8000                  \n\t"
105     "1:                                             \n\t"
106         "lw     %[Temp1],   0(%[z2])                \n\t"
107         "lw     %[Temp2],   4(%[z2])                \n\t"
108         "lw     %[Temp3],   8(%[z2])                \n\t"
109         "lw     %[Temp4],   12(%[z2])               \n\t"
110         "lw     %[Temp5],   16(%[z2])               \n\t"
111         "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
112         "xor    %[Temp2],   %[Temp2],   %[Temp6]    \n\t"
113         "xor    %[Temp3],   %[Temp3],   %[Temp6]    \n\t"
114         "xor    %[Temp4],   %[Temp4],   %[Temp6]    \n\t"
115         "xor    %[Temp5],   %[Temp5],   %[Temp6]    \n\t"
116         "addiu  %[z2],      %[z2],      -20         \n\t"
117         "sw     %[Temp1],   32(%[z1])               \n\t"
118         "sw     %[Temp2],   24(%[z1])               \n\t"
119         "sw     %[Temp3],   16(%[z1])               \n\t"
120         "sw     %[Temp4],   8(%[z1])                \n\t"
121         "sw     %[Temp5],   0(%[z1])                \n\t"
122         "lw     %[Temp1],   0(%[z3])                \n\t"
123         "lw     %[Temp2],   4(%[z3])                \n\t"
124         "lw     %[Temp3],   8(%[z3])                \n\t"
125         "lw     %[Temp4],   12(%[z3])               \n\t"
126         "lw     %[Temp5],   16(%[z3])               \n\t"
127         "sw     %[Temp1],   4(%[z1])                \n\t"
128         "sw     %[Temp2],   12(%[z1])               \n\t"
129         "sw     %[Temp3],   20(%[z1])               \n\t"
130         "sw     %[Temp4],   28(%[z1])               \n\t"
131         "sw     %[Temp5],   36(%[z1])               \n\t"
132         "addiu  %[z3],      %[z3],      20          \n\t"
133         "addiu  %[z1],      %[z1],      40          \n\t"
134         "bne    %[z1],      %[z4],      1b          \n\t"
135         "lw     %[Temp1],   132(%[z])               \n\t"
136         "lw     %[Temp2],   128(%[z])               \n\t"
137         "lw     %[Temp3],   0(%[z])                 \n\t"
138         "lw     %[Temp4],   4(%[z])                 \n\t"
139         "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
140         "sw     %[Temp1],   504(%[z])               \n\t"
141         "sw     %[Temp2],   508(%[z])               \n\t"
142         "sw     %[Temp3],   256(%[z])               \n\t"
143         "sw     %[Temp4],   260(%[z])               \n\t"
144
145         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
146           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
147           [Temp5]"=&r"(Temp5), [Temp6]"=&r"(Temp6),
148           [z1]"+r"(z1), [z2]"+r"(z2), [z3]"+r"(z3)
149         : [z4]"r"(z4), [z]"r"(z)
150         : "memory"
151     );
152 }
153
154 static void sbr_qmf_post_shuffle_mips(float W[32][2], const float *z)
155 {
156     int Temp1, Temp2, Temp3, Temp4, Temp5;
157     float *W_ptr = (float *)W;
158     float *z1    = (float *)z;
159     float *z2    = (float *)&z[60];
160     float *z_end = z1 + 32;
161
162      /* loop unrolled 4 times */
163     __asm__ volatile (
164         "lui    %[Temp5],   0x8000                  \n\t"
165     "1:                                             \n\t"
166         "lw     %[Temp1],   0(%[z2])                \n\t"
167         "lw     %[Temp2],   4(%[z2])                \n\t"
168         "lw     %[Temp3],   8(%[z2])                \n\t"
169         "lw     %[Temp4],   12(%[z2])               \n\t"
170         "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
171         "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
172         "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
173         "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
174         "addiu  %[z2],      %[z2],      -16         \n\t"
175         "sw     %[Temp1],   24(%[W_ptr])            \n\t"
176         "sw     %[Temp2],   16(%[W_ptr])            \n\t"
177         "sw     %[Temp3],   8(%[W_ptr])             \n\t"
178         "sw     %[Temp4],   0(%[W_ptr])             \n\t"
179         "lw     %[Temp1],   0(%[z1])                \n\t"
180         "lw     %[Temp2],   4(%[z1])                \n\t"
181         "lw     %[Temp3],   8(%[z1])                \n\t"
182         "lw     %[Temp4],   12(%[z1])               \n\t"
183         "sw     %[Temp1],   4(%[W_ptr])             \n\t"
184         "sw     %[Temp2],   12(%[W_ptr])            \n\t"
185         "sw     %[Temp3],   20(%[W_ptr])            \n\t"
186         "sw     %[Temp4],   28(%[W_ptr])            \n\t"
187         "addiu  %[z1],      %[z1],      16          \n\t"
188         "addiu  %[W_ptr],   %[W_ptr],   32          \n\t"
189         "bne    %[z1],      %[z_end],   1b          \n\t"
190
191         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
192           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
193           [Temp5]"=&r"(Temp5), [z1]"+r"(z1),
194           [z2]"+r"(z2), [W_ptr]"+r"(W_ptr)
195         : [z_end]"r"(z_end)
196         : "memory"
197     );
198 }
199
200 #if HAVE_MIPSFPU
201 static void sbr_sum64x5_mips(float *z)
202 {
203     int k;
204     float *z1;
205     float f1, f2, f3, f4, f5, f6, f7, f8;
206     for (k = 0; k < 64; k += 8) {
207
208         z1 = &z[k];
209
210          /* loop unrolled 8 times */
211         __asm__ volatile (
212             "lwc1   $f0,    0(%[z1])        \n\t"
213             "lwc1   $f1,    256(%[z1])      \n\t"
214             "lwc1   $f2,    4(%[z1])        \n\t"
215             "lwc1   $f3,    260(%[z1])      \n\t"
216             "lwc1   $f4,    8(%[z1])        \n\t"
217             "add.s  %[f1],  $f0,    $f1     \n\t"
218             "lwc1   $f5,    264(%[z1])      \n\t"
219             "add.s  %[f2],  $f2,    $f3     \n\t"
220             "lwc1   $f6,    12(%[z1])       \n\t"
221             "lwc1   $f7,    268(%[z1])      \n\t"
222             "add.s  %[f3],  $f4,    $f5     \n\t"
223             "lwc1   $f8,    16(%[z1])       \n\t"
224             "lwc1   $f9,    272(%[z1])      \n\t"
225             "add.s  %[f4],  $f6,    $f7     \n\t"
226             "lwc1   $f10,   20(%[z1])       \n\t"
227             "lwc1   $f11,   276(%[z1])      \n\t"
228             "add.s  %[f5],  $f8,    $f9     \n\t"
229             "lwc1   $f12,   24(%[z1])       \n\t"
230             "lwc1   $f13,   280(%[z1])      \n\t"
231             "add.s  %[f6],  $f10,   $f11    \n\t"
232             "lwc1   $f14,   28(%[z1])       \n\t"
233             "lwc1   $f15,   284(%[z1])      \n\t"
234             "add.s  %[f7],  $f12,   $f13    \n\t"
235             "lwc1   $f0,    512(%[z1])      \n\t"
236             "lwc1   $f1,    516(%[z1])      \n\t"
237             "add.s  %[f8],  $f14,   $f15    \n\t"
238             "lwc1   $f2,    520(%[z1])      \n\t"
239             "add.s  %[f1],  %[f1],  $f0     \n\t"
240             "add.s  %[f2],  %[f2],  $f1     \n\t"
241             "lwc1   $f3,    524(%[z1])      \n\t"
242             "add.s  %[f3],  %[f3],  $f2     \n\t"
243             "lwc1   $f4,    528(%[z1])      \n\t"
244             "lwc1   $f5,    532(%[z1])      \n\t"
245             "add.s  %[f4],  %[f4],  $f3     \n\t"
246             "lwc1   $f6,    536(%[z1])      \n\t"
247             "add.s  %[f5],  %[f5],  $f4     \n\t"
248             "add.s  %[f6],  %[f6],  $f5     \n\t"
249             "lwc1   $f7,    540(%[z1])      \n\t"
250             "add.s  %[f7],  %[f7],  $f6     \n\t"
251             "lwc1   $f0,    768(%[z1])      \n\t"
252             "lwc1   $f1,    772(%[z1])      \n\t"
253             "add.s  %[f8],  %[f8],  $f7     \n\t"
254             "lwc1   $f2,    776(%[z1])      \n\t"
255             "add.s  %[f1],  %[f1],  $f0     \n\t"
256             "add.s  %[f2],  %[f2],  $f1     \n\t"
257             "lwc1   $f3,    780(%[z1])      \n\t"
258             "add.s  %[f3],  %[f3],  $f2     \n\t"
259             "lwc1   $f4,    784(%[z1])      \n\t"
260             "lwc1   $f5,    788(%[z1])      \n\t"
261             "add.s  %[f4],  %[f4],  $f3     \n\t"
262             "lwc1   $f6,    792(%[z1])      \n\t"
263             "add.s  %[f5],  %[f5],  $f4     \n\t"
264             "add.s  %[f6],  %[f6],  $f5     \n\t"
265             "lwc1   $f7,    796(%[z1])      \n\t"
266             "add.s  %[f7],  %[f7],  $f6     \n\t"
267             "lwc1   $f0,    1024(%[z1])     \n\t"
268             "lwc1   $f1,    1028(%[z1])     \n\t"
269             "add.s  %[f8],  %[f8],  $f7     \n\t"
270             "lwc1   $f2,    1032(%[z1])     \n\t"
271             "add.s  %[f1],  %[f1],  $f0     \n\t"
272             "add.s  %[f2],  %[f2],  $f1     \n\t"
273             "lwc1   $f3,    1036(%[z1])     \n\t"
274             "add.s  %[f3],  %[f3],  $f2     \n\t"
275             "lwc1   $f4,    1040(%[z1])     \n\t"
276             "lwc1   $f5,    1044(%[z1])     \n\t"
277             "add.s  %[f4],  %[f4],  $f3     \n\t"
278             "lwc1   $f6,    1048(%[z1])     \n\t"
279             "add.s  %[f5],  %[f5],  $f4     \n\t"
280             "add.s  %[f6],  %[f6],  $f5     \n\t"
281             "lwc1   $f7,    1052(%[z1])     \n\t"
282             "add.s  %[f7],  %[f7],  $f6     \n\t"
283             "swc1   %[f1],  0(%[z1])        \n\t"
284             "swc1   %[f2],  4(%[z1])        \n\t"
285             "add.s  %[f8],  %[f8],  $f7     \n\t"
286             "swc1   %[f3],  8(%[z1])        \n\t"
287             "swc1   %[f4],  12(%[z1])       \n\t"
288             "swc1   %[f5],  16(%[z1])       \n\t"
289             "swc1   %[f6],  20(%[z1])       \n\t"
290             "swc1   %[f7],  24(%[z1])       \n\t"
291             "swc1   %[f8],  28(%[z1])       \n\t"
292
293             : [f1]"=&f"(f1), [f2]"=&f"(f2), [f3]"=&f"(f3),
294               [f4]"=&f"(f4), [f5]"=&f"(f5), [f6]"=&f"(f6),
295               [f7]"=&f"(f7), [f8]"=&f"(f8)
296             : [z1]"r"(z1)
297             : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
298               "$f6", "$f7", "$f8", "$f9", "$f10", "$f11",
299               "$f12", "$f13", "$f14", "$f15",
300               "memory"
301         );
302     }
303 }
304
305 static float sbr_sum_square_mips(float (*x)[2], int n)
306 {
307     float sum0 = 0.0f, sum1 = 0.0f;
308     float *p_x;
309     float temp0, temp1, temp2, temp3;
310     float *loop_end;
311     p_x = &x[0][0];
312     loop_end = p_x + (n >> 1)*4 - 4;
313
314     __asm__ volatile (
315         ".set      push                                             \n\t"
316         ".set      noreorder                                        \n\t"
317         "lwc1      %[temp0],   0(%[p_x])                            \n\t"
318         "lwc1      %[temp1],   4(%[p_x])                            \n\t"
319         "lwc1      %[temp2],   8(%[p_x])                            \n\t"
320         "lwc1      %[temp3],   12(%[p_x])                           \n\t"
321     "1:                                                             \n\t"
322         "addiu     %[p_x],     %[p_x],       16                     \n\t"
323         "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
324         "lwc1      %[temp0],   0(%[p_x])                            \n\t"
325         "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
326         "lwc1      %[temp1],   4(%[p_x])                            \n\t"
327         "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
328         "lwc1      %[temp2],   8(%[p_x])                            \n\t"
329         "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
330         "bne       %[p_x],     %[loop_end],  1b                     \n\t"
331         " lwc1     %[temp3],   12(%[p_x])                           \n\t"
332         "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
333         "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
334         "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
335         "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
336         ".set      pop                                              \n\t"
337
338         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
339           [temp3]"=&f"(temp3), [sum0]"+f"(sum0), [sum1]"+f"(sum1),
340           [p_x]"+r"(p_x)
341         : [loop_end]"r"(loop_end)
342         : "memory"
343     );
344     return sum0 + sum1;
345 }
346
347 static void sbr_qmf_deint_bfly_mips(float *v, const float *src0, const float *src1)
348 {
349     int i;
350     float temp0, temp1, temp2, temp3, temp4, temp5;
351     float temp6, temp7, temp8, temp9, temp10, temp11;
352     float *v0 = v;
353     float *v1 = &v[127];
354     float *psrc0 = (float*)src0;
355     float *psrc1 = (float*)&src1[63];
356
357     for (i = 0; i < 4; i++) {
358
359          /* loop unrolled 16 times */
360         __asm__ volatile(
361             "lwc1       %[temp0],   0(%[src0])             \n\t"
362             "lwc1       %[temp1],   0(%[src1])             \n\t"
363             "lwc1       %[temp3],   4(%[src0])             \n\t"
364             "lwc1       %[temp4],   -4(%[src1])            \n\t"
365             "lwc1       %[temp6],   8(%[src0])             \n\t"
366             "lwc1       %[temp7],   -8(%[src1])            \n\t"
367             "lwc1       %[temp9],   12(%[src0])            \n\t"
368             "lwc1       %[temp10],  -12(%[src1])           \n\t"
369             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
370             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
371             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
372             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
373             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
374             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
375             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
376             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
377             "swc1       %[temp2],   0(%[v1])               \n\t"
378             "swc1       %[temp0],   0(%[v0])               \n\t"
379             "swc1       %[temp5],   -4(%[v1])              \n\t"
380             "swc1       %[temp3],   4(%[v0])               \n\t"
381             "swc1       %[temp8],   -8(%[v1])              \n\t"
382             "swc1       %[temp6],   8(%[v0])               \n\t"
383             "swc1       %[temp11],  -12(%[v1])             \n\t"
384             "swc1       %[temp9],   12(%[v0])              \n\t"
385             "lwc1       %[temp0],   16(%[src0])            \n\t"
386             "lwc1       %[temp1],   -16(%[src1])           \n\t"
387             "lwc1       %[temp3],   20(%[src0])            \n\t"
388             "lwc1       %[temp4],   -20(%[src1])           \n\t"
389             "lwc1       %[temp6],   24(%[src0])            \n\t"
390             "lwc1       %[temp7],   -24(%[src1])           \n\t"
391             "lwc1       %[temp9],   28(%[src0])            \n\t"
392             "lwc1       %[temp10],  -28(%[src1])           \n\t"
393             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
394             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
395             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
396             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
397             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
398             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
399             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
400             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
401             "swc1       %[temp2],   -16(%[v1])             \n\t"
402             "swc1       %[temp0],   16(%[v0])              \n\t"
403             "swc1       %[temp5],   -20(%[v1])             \n\t"
404             "swc1       %[temp3],   20(%[v0])              \n\t"
405             "swc1       %[temp8],   -24(%[v1])             \n\t"
406             "swc1       %[temp6],   24(%[v0])              \n\t"
407             "swc1       %[temp11],  -28(%[v1])             \n\t"
408             "swc1       %[temp9],   28(%[v0])              \n\t"
409             "lwc1       %[temp0],   32(%[src0])            \n\t"
410             "lwc1       %[temp1],   -32(%[src1])           \n\t"
411             "lwc1       %[temp3],   36(%[src0])            \n\t"
412             "lwc1       %[temp4],   -36(%[src1])           \n\t"
413             "lwc1       %[temp6],   40(%[src0])            \n\t"
414             "lwc1       %[temp7],   -40(%[src1])           \n\t"
415             "lwc1       %[temp9],   44(%[src0])            \n\t"
416             "lwc1       %[temp10],  -44(%[src1])           \n\t"
417             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
418             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
419             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
420             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
421             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
422             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
423             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
424             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
425             "swc1       %[temp2],   -32(%[v1])             \n\t"
426             "swc1       %[temp0],   32(%[v0])              \n\t"
427             "swc1       %[temp5],   -36(%[v1])             \n\t"
428             "swc1       %[temp3],   36(%[v0])              \n\t"
429             "swc1       %[temp8],   -40(%[v1])             \n\t"
430             "swc1       %[temp6],   40(%[v0])              \n\t"
431             "swc1       %[temp11],  -44(%[v1])             \n\t"
432             "swc1       %[temp9],   44(%[v0])              \n\t"
433             "lwc1       %[temp0],   48(%[src0])            \n\t"
434             "lwc1       %[temp1],   -48(%[src1])           \n\t"
435             "lwc1       %[temp3],   52(%[src0])            \n\t"
436             "lwc1       %[temp4],   -52(%[src1])           \n\t"
437             "lwc1       %[temp6],   56(%[src0])            \n\t"
438             "lwc1       %[temp7],   -56(%[src1])           \n\t"
439             "lwc1       %[temp9],   60(%[src0])            \n\t"
440             "lwc1       %[temp10],  -60(%[src1])           \n\t"
441             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
442             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
443             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
444             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
445             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
446             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
447             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
448             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
449             "swc1       %[temp2],   -48(%[v1])             \n\t"
450             "swc1       %[temp0],   48(%[v0])              \n\t"
451             "swc1       %[temp5],   -52(%[v1])             \n\t"
452             "swc1       %[temp3],   52(%[v0])              \n\t"
453             "swc1       %[temp8],   -56(%[v1])             \n\t"
454             "swc1       %[temp6],   56(%[v0])              \n\t"
455             "swc1       %[temp11],  -60(%[v1])             \n\t"
456             "swc1       %[temp9],   60(%[v0])              \n\t"
457             "addiu      %[src0],    %[src0],    64         \n\t"
458             "addiu      %[src1],    %[src1],    -64        \n\t"
459             "addiu      %[v0],      %[v0],      64         \n\t"
460             "addiu      %[v1],      %[v1],      -64        \n\t"
461
462             : [v0]"+r"(v0), [v1]"+r"(v1), [src0]"+r"(psrc0), [src1]"+r"(psrc1),
463               [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
464               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
465               [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
466               [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
467             :
468             :"memory"
469         );
470     }
471 }
472
473 static void sbr_autocorrelate_mips(const float x[40][2], float phi[3][2][2])
474 {
475     int i;
476     float real_sum_0 = 0.0f;
477     float real_sum_1 = 0.0f;
478     float real_sum_2 = 0.0f;
479     float imag_sum_1 = 0.0f;
480     float imag_sum_2 = 0.0f;
481     float *p_x, *p_phi;
482     float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
483     float temp7, temp_r, temp_r1, temp_r2, temp_r3, temp_r4;
484     p_x = (float*)&x[0][0];
485     p_phi = &phi[0][0][0];
486
487     __asm__ volatile (
488         "lwc1    %[temp0],      8(%[p_x])                           \n\t"
489         "lwc1    %[temp1],      12(%[p_x])                          \n\t"
490         "lwc1    %[temp2],      16(%[p_x])                          \n\t"
491         "lwc1    %[temp3],      20(%[p_x])                          \n\t"
492         "lwc1    %[temp4],      24(%[p_x])                          \n\t"
493         "lwc1    %[temp5],      28(%[p_x])                          \n\t"
494         "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
495         "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
496         "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
497         "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
498         "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
499         "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
500         "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
501         "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
502         "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
503         "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
504         "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
505         "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
506         "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
507         "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
508         "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
509         "addiu   %[p_x],        %[p_x],        8                    \n\t"
510
511         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
512           [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
513           [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
514           [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
515           [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1), [temp_r2]"=&f"(temp_r2),
516           [temp_r3]"=&f"(temp_r3), [temp_r4]"=&f"(temp_r4),
517           [p_x]"+r"(p_x), [imag_sum_2]"+f"(imag_sum_2)
518         :
519         : "memory"
520     );
521
522     for (i = 0; i < 12; i++) {
523         __asm__ volatile (
524             "lwc1    %[temp0],      8(%[p_x])                           \n\t"
525             "lwc1    %[temp1],      12(%[p_x])                          \n\t"
526             "lwc1    %[temp2],      16(%[p_x])                          \n\t"
527             "lwc1    %[temp3],      20(%[p_x])                          \n\t"
528             "lwc1    %[temp4],      24(%[p_x])                          \n\t"
529             "lwc1    %[temp5],      28(%[p_x])                          \n\t"
530             "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
531             "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
532             "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
533             "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
534             "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
535             "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
536             "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
537             "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
538             "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
539             "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
540             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
541             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
542             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
543             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
544             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
545             "lwc1    %[temp0],      32(%[p_x])                          \n\t"
546             "lwc1    %[temp1],      36(%[p_x])                          \n\t"
547             "mul.s   %[temp_r],     %[temp3],      %[temp3]             \n\t"
548             "mul.s   %[temp_r1],    %[temp3],      %[temp5]             \n\t"
549             "mul.s   %[temp_r2],    %[temp3],      %[temp4]             \n\t"
550             "mul.s   %[temp_r3],    %[temp3],      %[temp1]             \n\t"
551             "mul.s   %[temp_r4],    %[temp3],      %[temp0]             \n\t"
552             "madd.s  %[temp_r],     %[temp_r],     %[temp2],  %[temp2]  \n\t"
553             "madd.s  %[temp_r1],    %[temp_r1],    %[temp2],  %[temp4]  \n\t"
554             "msub.s  %[temp_r2],    %[temp_r2],    %[temp2],  %[temp5]  \n\t"
555             "madd.s  %[temp_r3],    %[temp_r3],    %[temp2],  %[temp0]  \n\t"
556             "msub.s  %[temp_r4],    %[temp_r4],    %[temp2],  %[temp1]  \n\t"
557             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
558             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
559             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
560             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
561             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
562             "lwc1    %[temp2],      40(%[p_x])                          \n\t"
563             "lwc1    %[temp3],      44(%[p_x])                          \n\t"
564             "mul.s   %[temp_r],     %[temp5],      %[temp5]             \n\t"
565             "mul.s   %[temp_r1],    %[temp5],      %[temp1]             \n\t"
566             "mul.s   %[temp_r2],    %[temp5],      %[temp0]             \n\t"
567             "mul.s   %[temp_r3],    %[temp5],      %[temp3]             \n\t"
568             "mul.s   %[temp_r4],    %[temp5],      %[temp2]             \n\t"
569             "madd.s  %[temp_r],     %[temp_r],     %[temp4],  %[temp4]  \n\t"
570             "madd.s  %[temp_r1],    %[temp_r1],    %[temp4],  %[temp0]  \n\t"
571             "msub.s  %[temp_r2],    %[temp_r2],    %[temp4],  %[temp1]  \n\t"
572             "madd.s  %[temp_r3],    %[temp_r3],    %[temp4],  %[temp2]  \n\t"
573             "msub.s  %[temp_r4],    %[temp_r4],    %[temp4],  %[temp3]  \n\t"
574             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
575             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
576             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
577             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
578             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
579             "addiu   %[p_x],        %[p_x],        24                   \n\t"
580
581             : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
582               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
583               [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
584               [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
585               [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1),
586               [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
587               [temp_r4]"=&f"(temp_r4), [p_x]"+r"(p_x),
588               [imag_sum_2]"+f"(imag_sum_2)
589             :
590             : "memory"
591         );
592     }
593     __asm__ volatile (
594         "lwc1    %[temp0],    -296(%[p_x])                        \n\t"
595         "lwc1    %[temp1],    -292(%[p_x])                        \n\t"
596         "lwc1    %[temp2],    8(%[p_x])                           \n\t"
597         "lwc1    %[temp3],    12(%[p_x])                          \n\t"
598         "lwc1    %[temp4],    -288(%[p_x])                        \n\t"
599         "lwc1    %[temp5],    -284(%[p_x])                        \n\t"
600         "lwc1    %[temp6],    -280(%[p_x])                        \n\t"
601         "lwc1    %[temp7],    -276(%[p_x])                        \n\t"
602         "madd.s  %[temp_r],   %[real_sum_0], %[temp0],  %[temp0]  \n\t"
603         "madd.s  %[temp_r1],  %[real_sum_0], %[temp2],  %[temp2]  \n\t"
604         "madd.s  %[temp_r2],  %[real_sum_1], %[temp0],  %[temp4]  \n\t"
605         "madd.s  %[temp_r3],  %[imag_sum_1], %[temp0],  %[temp5]  \n\t"
606         "madd.s  %[temp_r],   %[temp_r],     %[temp1],  %[temp1]  \n\t"
607         "madd.s  %[temp_r1],  %[temp_r1],    %[temp3],  %[temp3]  \n\t"
608         "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp5]  \n\t"
609         "nmsub.s  %[temp_r3], %[temp_r3],    %[temp1],  %[temp4]  \n\t"
610         "lwc1    %[temp4],    16(%[p_x])                          \n\t"
611         "lwc1    %[temp5],    20(%[p_x])                          \n\t"
612         "swc1    %[temp_r],   40(%[p_phi])                        \n\t"
613         "swc1    %[temp_r1],  16(%[p_phi])                        \n\t"
614         "swc1    %[temp_r2],  24(%[p_phi])                        \n\t"
615         "swc1    %[temp_r3],  28(%[p_phi])                        \n\t"
616         "madd.s  %[temp_r],   %[real_sum_1], %[temp2],  %[temp4]  \n\t"
617         "madd.s  %[temp_r1],  %[imag_sum_1], %[temp2],  %[temp5]  \n\t"
618         "madd.s  %[temp_r2],  %[real_sum_2], %[temp0],  %[temp6]  \n\t"
619         "madd.s  %[temp_r3],  %[imag_sum_2], %[temp0],  %[temp7]  \n\t"
620         "madd.s  %[temp_r],   %[temp_r],     %[temp3],  %[temp5]  \n\t"
621         "nmsub.s %[temp_r1],  %[temp_r1],    %[temp3],  %[temp4]  \n\t"
622         "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp7]  \n\t"
623         "nmsub.s %[temp_r3],  %[temp_r3],    %[temp1],  %[temp6]  \n\t"
624         "swc1    %[temp_r],   0(%[p_phi])                         \n\t"
625         "swc1    %[temp_r1],  4(%[p_phi])                         \n\t"
626         "swc1    %[temp_r2],  8(%[p_phi])                         \n\t"
627         "swc1    %[temp_r3],  12(%[p_phi])                        \n\t"
628
629         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
630           [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
631           [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp_r]"=&f"(temp_r),
632           [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
633           [real_sum_2]"+f"(real_sum_2), [imag_sum_1]"+f"(imag_sum_1),
634           [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
635           [temp_r1]"=&f"(temp_r1), [p_phi]"+r"(p_phi),
636           [imag_sum_2]"+f"(imag_sum_2)
637         : [p_x]"r"(p_x)
638         : "memory"
639     );
640 }
641
642 static void sbr_hf_gen_mips(float (*X_high)[2], const float (*X_low)[2],
643                          const float alpha0[2], const float alpha1[2],
644                          float bw, int start, int end)
645 {
646     float alpha[4];
647     int i;
648     float *p_x_low = (float*)&X_low[0][0] + 2*start;
649     float *p_x_high = &X_high[0][0] + 2*start;
650     float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
651     float temp7, temp8, temp9, temp10, temp11, temp12;
652
653     alpha[0] = alpha1[0] * bw * bw;
654     alpha[1] = alpha1[1] * bw * bw;
655     alpha[2] = alpha0[0] * bw;
656     alpha[3] = alpha0[1] * bw;
657
658     for (i = start; i < end; i++) {
659         __asm__ volatile (
660             "lwc1    %[temp0],    -16(%[p_x_low])                        \n\t"
661             "lwc1    %[temp1],    -12(%[p_x_low])                        \n\t"
662             "lwc1    %[temp2],    -8(%[p_x_low])                         \n\t"
663             "lwc1    %[temp3],    -4(%[p_x_low])                         \n\t"
664             "lwc1    %[temp5],    0(%[p_x_low])                          \n\t"
665             "lwc1    %[temp6],    4(%[p_x_low])                          \n\t"
666             "lwc1    %[temp7],    0(%[alpha])                            \n\t"
667             "lwc1    %[temp8],    4(%[alpha])                            \n\t"
668             "lwc1    %[temp9],    8(%[alpha])                            \n\t"
669             "lwc1    %[temp10],   12(%[alpha])                           \n\t"
670             "addiu   %[p_x_high], %[p_x_high],     8                     \n\t"
671             "addiu   %[p_x_low],  %[p_x_low],      8                     \n\t"
672             "mul.s   %[temp11],   %[temp1],        %[temp8]              \n\t"
673             "msub.s  %[temp11],   %[temp11],       %[temp0],  %[temp7]   \n\t"
674             "madd.s  %[temp11],   %[temp11],       %[temp2],  %[temp9]   \n\t"
675             "nmsub.s %[temp11],   %[temp11],       %[temp3],  %[temp10]  \n\t"
676             "add.s   %[temp11],   %[temp11],       %[temp5]              \n\t"
677             "swc1    %[temp11],   -8(%[p_x_high])                        \n\t"
678             "mul.s   %[temp12],   %[temp1],        %[temp7]              \n\t"
679             "madd.s  %[temp12],   %[temp12],       %[temp0],  %[temp8]   \n\t"
680             "madd.s  %[temp12],   %[temp12],       %[temp3],  %[temp9]   \n\t"
681             "madd.s  %[temp12],   %[temp12],       %[temp2],  %[temp10]  \n\t"
682             "add.s   %[temp12],   %[temp12],       %[temp6]              \n\t"
683             "swc1    %[temp12],   -4(%[p_x_high])                        \n\t"
684
685             : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
686               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
687               [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
688               [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
689               [temp12]"=&f"(temp12), [p_x_high]"+r"(p_x_high),
690               [p_x_low]"+r"(p_x_low)
691             : [alpha]"r"(alpha)
692             : "memory"
693         );
694     }
695 }
696
697 static void sbr_hf_g_filt_mips(float (*Y)[2], const float (*X_high)[40][2],
698                             const float *g_filt, int m_max, intptr_t ixh)
699 {
700     float *p_y, *p_x, *p_g;
701     float temp0, temp1, temp2;
702     int loop_end;
703
704     p_g = (float*)&g_filt[0];
705     p_y = &Y[0][0];
706     p_x = (float*)&X_high[0][ixh][0];
707     loop_end = (int)((int*)p_g + m_max);
708
709     __asm__ volatile(
710         ".set    push                                \n\t"
711         ".set    noreorder                           \n\t"
712     "1:                                              \n\t"
713         "lwc1    %[temp0],   0(%[p_g])               \n\t"
714         "lwc1    %[temp1],   0(%[p_x])               \n\t"
715         "lwc1    %[temp2],   4(%[p_x])               \n\t"
716         "mul.s   %[temp1],   %[temp1],     %[temp0]  \n\t"
717         "mul.s   %[temp2],   %[temp2],     %[temp0]  \n\t"
718         "addiu   %[p_g],     %[p_g],       4         \n\t"
719         "addiu   %[p_x],     %[p_x],       320       \n\t"
720         "swc1    %[temp1],   0(%[p_y])               \n\t"
721         "swc1    %[temp2],   4(%[p_y])               \n\t"
722         "bne     %[p_g],     %[loop_end],  1b        \n\t"
723         " addiu  %[p_y],     %[p_y],       8         \n\t"
724         ".set    pop                                 \n\t"
725
726         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
727           [temp2]"=&f"(temp2), [p_x]"+r"(p_x),
728           [p_y]"+r"(p_y), [p_g]"+r"(p_g)
729         : [loop_end]"r"(loop_end)
730         : "memory"
731     );
732 }
733
734 static void sbr_hf_apply_noise_0_mips(float (*Y)[2], const float *s_m,
735                                  const float *q_filt, int noise,
736                                  int kx, int m_max)
737 {
738     int m;
739
740     for (m = 0; m < m_max; m++){
741
742         float *Y1=&Y[m][0];
743         float *ff_table;
744         float y0,y1, temp1, temp2, temp4, temp5;
745         int temp0, temp3;
746         const float *s_m1=&s_m[m];
747         const float *q_filt1= &q_filt[m];
748
749         __asm__ volatile(
750             "lwc1    %[y0],       0(%[Y1])                                    \n\t"
751             "lwc1    %[temp1],    0(%[s_m1])                                  \n\t"
752             "addiu   %[noise],    %[noise],              1                    \n\t"
753             "andi    %[noise],    %[noise],              0x1ff                \n\t"
754             "sll     %[temp0],    %[noise], 3                                 \n\t"
755             "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]             \n\t"
756             "add.s   %[y0],       %[y0],                 %[temp1]             \n\t"
757             "mfc1    %[temp3],    %[temp1]                                    \n\t"
758             "bne     %[temp3],    $0,                    1f                   \n\t"
759             "lwc1    %[y1],       4(%[Y1])                                    \n\t"
760             "lwc1    %[temp2],    0(%[q_filt1])                               \n\t"
761             "lwc1    %[temp4],    0(%[ff_table])                              \n\t"
762             "lwc1    %[temp5],    4(%[ff_table])                              \n\t"
763             "madd.s  %[y0],       %[y0],                 %[temp2],  %[temp4]  \n\t"
764             "madd.s  %[y1],       %[y1],                 %[temp2],  %[temp5]  \n\t"
765             "swc1    %[y1],       4(%[Y1])                                    \n\t"
766         "1:                                                                   \n\t"
767             "swc1    %[y0],       0(%[Y1])                                    \n\t"
768
769             : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
770               [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
771               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
772             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
773               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
774             : "memory"
775         );
776     }
777 }
778
779 static void sbr_hf_apply_noise_1_mips(float (*Y)[2], const float *s_m,
780                                  const float *q_filt, int noise,
781                                  int kx, int m_max)
782 {
783     float y0,y1,temp1, temp2, temp4, temp5;
784     int temp0, temp3, m;
785     float phi_sign = 1 - 2 * (kx & 1);
786
787     for (m = 0; m < m_max; m++) {
788
789         float *ff_table;
790         float *Y1=&Y[m][0];
791         const float *s_m1=&s_m[m];
792         const float *q_filt1= &q_filt[m];
793
794         __asm__ volatile(
795             "lwc1   %[y1],       4(%[Y1])                                     \n\t"
796             "lwc1   %[temp1],    0(%[s_m1])                                   \n\t"
797             "lw     %[temp3],    0(%[s_m1])                                   \n\t"
798             "addiu  %[noise],    %[noise],               1                    \n\t"
799             "andi   %[noise],    %[noise],               0x1ff                \n\t"
800             "sll    %[temp0],    %[noise],               3                    \n\t"
801             "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
802             "madd.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
803             "bne    %[temp3],    $0,                    1f                    \n\t"
804             "lwc1   %[y0],       0(%[Y1])                                     \n\t"
805             "lwc1   %[temp2],    0(%[q_filt1])                                \n\t"
806             "lwc1   %[temp4],    0(%[ff_table])                               \n\t"
807             "lwc1   %[temp5],    4(%[ff_table])                               \n\t"
808             "madd.s %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
809             "madd.s %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
810             "swc1   %[y0],       0(%[Y1])                                     \n\t"
811         "1:                                                                   \n\t"
812             "swc1   %[y1],       4(%[Y1])                                     \n\t"
813
814             : [ff_table] "=&r" (ff_table), [y0] "=&f" (y0), [y1] "=&f" (y1),
815               [temp0] "=&r" (temp0), [temp1] "=&f" (temp1), [temp2] "=&f" (temp2),
816               [temp3] "=&r" (temp3), [temp4] "=&f" (temp4), [temp5] "=&f" (temp5)
817             : [ff_sbr_noise_table] "r" (ff_sbr_noise_table), [noise] "r" (noise),
818               [Y1] "r" (Y1), [s_m1] "r" (s_m1), [q_filt1] "r" (q_filt1),
819               [phi_sign] "f" (phi_sign)
820             : "memory"
821         );
822         phi_sign = -phi_sign;
823     }
824 }
825
826 static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m,
827                                  const float *q_filt, int noise,
828                                  int kx, int m_max)
829 {
830     int m;
831     float *ff_table;
832     float y0,y1, temp0, temp1, temp2, temp3, temp4, temp5;
833
834     for (m = 0; m < m_max; m++) {
835
836         float *Y1=&Y[m][0];
837         const float *s_m1=&s_m[m];
838         const float *q_filt1= &q_filt[m];
839
840         __asm__ volatile(
841             "lwc1   %[y0],       0(%[Y1])                                  \n\t"
842             "lwc1   %[temp1],    0(%[s_m1])                                \n\t"
843             "addiu  %[noise],    %[noise],              1                  \n\t"
844             "andi   %[noise],    %[noise],              0x1ff              \n\t"
845             "sll    %[temp0],    %[noise],              3                  \n\t"
846             "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]           \n\t"
847             "sub.s  %[y0],       %[y0],                 %[temp1]           \n\t"
848             "mfc1   %[temp3],    %[temp1]                                  \n\t"
849             "bne    %[temp3],    $0,                    1f                 \n\t"
850             "lwc1   %[y1],       4(%[Y1])                                  \n\t"
851             "lwc1   %[temp2],    0(%[q_filt1])                             \n\t"
852             "lwc1   %[temp4],    0(%[ff_table])                            \n\t"
853             "lwc1   %[temp5],    4(%[ff_table])                            \n\t"
854             "madd.s %[y0],       %[y0],                 %[temp2], %[temp4] \n\t"
855             "madd.s %[y1],       %[y1],                 %[temp2], %[temp5] \n\t"
856             "swc1   %[y1],       4(%[Y1])                                  \n\t"
857         "1:                                                                \n\t"
858             "swc1   %[y0],       0(%[Y1])                                  \n\t"
859
860             : [temp0]"=&r"(temp0), [ff_table]"=&r"(ff_table), [y0]"=&f"(y0),
861               [y1]"=&f"(y1), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
862               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
863             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
864               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
865             : "memory"
866         );
867     }
868 }
869
870 static void sbr_hf_apply_noise_3_mips(float (*Y)[2], const float *s_m,
871                                  const float *q_filt, int noise,
872                                  int kx, int m_max)
873 {
874     float phi_sign = 1 - 2 * (kx & 1);
875     int m;
876
877     for (m = 0; m < m_max; m++) {
878
879         float *Y1=&Y[m][0];
880         float *ff_table;
881         float y0,y1, temp1, temp2, temp4, temp5;
882         int temp0, temp3;
883         const float *s_m1=&s_m[m];
884         const float *q_filt1= &q_filt[m];
885
886         __asm__ volatile(
887             "lwc1    %[y1],       4(%[Y1])                                     \n\t"
888             "lwc1    %[temp1],    0(%[s_m1])                                   \n\t"
889             "addiu   %[noise],    %[noise],              1                     \n\t"
890             "andi    %[noise],    %[noise],              0x1ff                 \n\t"
891             "sll     %[temp0],    %[noise],              3                     \n\t"
892             "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
893             "nmsub.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
894             "mfc1    %[temp3],    %[temp1]                                     \n\t"
895             "bne     %[temp3],    $0,                    1f                    \n\t"
896             "lwc1    %[y0],       0(%[Y1])                                     \n\t"
897             "lwc1    %[temp2],    0(%[q_filt1])                                \n\t"
898             "lwc1    %[temp4],    0(%[ff_table])                               \n\t"
899             "lwc1    %[temp5],    4(%[ff_table])                               \n\t"
900             "madd.s  %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
901             "madd.s  %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
902             "swc1    %[y0],       0(%[Y1])                                     \n\t"
903             "1:                                                                \n\t"
904             "swc1    %[y1],       4(%[Y1])                                     \n\t"
905
906             : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
907               [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
908               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
909             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
910               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1),
911               [phi_sign]"f"(phi_sign)
912             : "memory"
913         );
914        phi_sign = -phi_sign;
915     }
916 }
917 #endif /* HAVE_MIPSFPU */
918 #endif /* HAVE_INLINE_ASM */
919
920 void ff_sbrdsp_init_mips(SBRDSPContext *s)
921 {
922 #if HAVE_INLINE_ASM
923     s->neg_odd_64 = sbr_neg_odd_64_mips;
924     s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_mips;
925     s->qmf_post_shuffle = sbr_qmf_post_shuffle_mips;
926 #if HAVE_MIPSFPU
927     s->sum64x5 = sbr_sum64x5_mips;
928     s->sum_square = sbr_sum_square_mips;
929     s->qmf_deint_bfly = sbr_qmf_deint_bfly_mips;
930     s->autocorrelate = sbr_autocorrelate_mips;
931     s->hf_gen = sbr_hf_gen_mips;
932     s->hf_g_filt = sbr_hf_g_filt_mips;
933
934     s->hf_apply_noise[0] = sbr_hf_apply_noise_0_mips;
935     s->hf_apply_noise[1] = sbr_hf_apply_noise_1_mips;
936     s->hf_apply_noise[2] = sbr_hf_apply_noise_2_mips;
937     s->hf_apply_noise[3] = sbr_hf_apply_noise_3_mips;
938 #endif /* HAVE_MIPSFPU */
939 #endif /* HAVE_INLINE_ASM */
940 }