1/*
2 *  Copyright (c) 2014 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 "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
12#include "webrtc/modules/audio_coding/codecs/isac/fix/source/fft.h"
13#include "webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h"
14
15// The tables are defined in transform_tables.c file.
16extern const int16_t WebRtcIsacfix_kCosTab1[FRAMESAMPLES/2];
17extern const int16_t WebRtcIsacfix_kSinTab1[FRAMESAMPLES/2];
18extern const int16_t WebRtcIsacfix_kCosTab2[FRAMESAMPLES/4];
19extern const int16_t WebRtcIsacfix_kSinTab2[FRAMESAMPLES/4];
20
21// MIPS DSPr2 version of the WebRtcIsacfix_Time2Spec function
22// is not bit-exact with the C version.
23// The accuracy of the MIPS DSPr2 version is same or better.
24void WebRtcIsacfix_Time2SpecMIPS(int16_t* inre1Q9,
25                                 int16_t* inre2Q9,
26                                 int16_t* outreQ7,
27                                 int16_t* outimQ7) {
28  int k = FRAMESAMPLES / 2;
29  int32_t tmpreQ16[FRAMESAMPLES / 2], tmpimQ16[FRAMESAMPLES / 2];
30  int32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9;
31  int32_t inre1, inre2, tmpre, tmpim, factor, max, max1;
32  int16_t* cosptr;
33  int16_t* sinptr;
34
35  cosptr = (int16_t*)WebRtcIsacfix_kCosTab1;
36  sinptr = (int16_t*)WebRtcIsacfix_kSinTab1;
37
38  __asm __volatile (
39    ".set           push                                      \n\t"
40    ".set           noreorder                                 \n\t"
41    "addiu          %[inre1],     %[inre1Q9],   0             \n\t"
42    "addiu          %[inre2],     %[inre2Q9],   0             \n\t"
43    "addiu          %[tmpre],     %[tmpreQ16],  0             \n\t"
44    "addiu          %[tmpim],     %[tmpimQ16],  0             \n\t"
45    "addiu          %[factor],    $zero,        16921         \n\t"
46    "mul            %[max],       $zero,        $zero         \n\t"
47    // Multiply with complex exponentials and combine into one complex vector.
48    // Also, calculate the maximal absolute value in the same loop.
49   "1:                                                        \n\t"
50#if defined(MIPS_DSP_R2_LE)
51    "lwl            %[r0],        0(%[inre1])                 \n\t"
52    "lwl            %[r2],        0(%[cosptr])                \n\t"
53    "lwl            %[r3],        0(%[sinptr])                \n\t"
54    "lwl            %[r1],        0(%[inre2])                 \n\t"
55    "lwr            %[r0],        0(%[inre1])                 \n\t"
56    "lwr            %[r2],        0(%[cosptr])                \n\t"
57    "lwr            %[r3],        0(%[sinptr])                \n\t"
58    "lwr            %[r1],        0(%[inre2])                 \n\t"
59    "muleq_s.w.phr  %[r4],        %[r2],        %[r0]         \n\t"
60    "muleq_s.w.phr  %[r5],        %[r3],        %[r0]         \n\t"
61    "muleq_s.w.phr  %[r6],        %[r3],        %[r1]         \n\t"
62    "muleq_s.w.phr  %[r7],        %[r2],        %[r1]         \n\t"
63    "muleq_s.w.phl  %[r8],        %[r2],        %[r0]         \n\t"
64    "muleq_s.w.phl  %[r0],        %[r3],        %[r0]         \n\t"
65    "muleq_s.w.phl  %[r3],        %[r3],        %[r1]         \n\t"
66    "muleq_s.w.phl  %[r1],        %[r2],        %[r1]         \n\t"
67    "addiu          %[k],         %[k],         -2            \n\t"
68    "addu           %[r4],        %[r4],        %[r6]         \n\t"
69    "subu           %[r5],        %[r7],        %[r5]         \n\t"
70    "sra            %[r4],        %[r4],        8             \n\t"
71    "sra            %[r5],        %[r5],        8             \n\t"
72    "mult           $ac0,         %[factor],    %[r4]         \n\t"
73    "mult           $ac1,         %[factor],    %[r5]         \n\t"
74    "addu           %[r3],        %[r8],        %[r3]         \n\t"
75    "subu           %[r0],        %[r1],        %[r0]         \n\t"
76    "sra            %[r3],        %[r3],        8             \n\t"
77    "sra            %[r0],        %[r0],        8             \n\t"
78    "mult           $ac2,         %[factor],    %[r3]         \n\t"
79    "mult           $ac3,         %[factor],    %[r0]         \n\t"
80    "extr_r.w       %[r4],        $ac0,         16            \n\t"
81    "extr_r.w       %[r5],        $ac1,         16            \n\t"
82    "addiu          %[inre1],     %[inre1],     4             \n\t"
83    "addiu          %[inre2],     %[inre2],     4             \n\t"
84    "extr_r.w       %[r6],        $ac2,         16            \n\t"
85    "extr_r.w       %[r7],        $ac3,         16            \n\t"
86    "addiu          %[cosptr],    %[cosptr],    4             \n\t"
87    "addiu          %[sinptr],    %[sinptr],    4             \n\t"
88    "shra_r.w       %[r4],        %[r4],        3             \n\t"
89    "shra_r.w       %[r5],        %[r5],        3             \n\t"
90    "sw             %[r4],        0(%[tmpre])                 \n\t"
91    "absq_s.w       %[r4],        %[r4]                       \n\t"
92    "sw             %[r5],        0(%[tmpim])                 \n\t"
93    "absq_s.w       %[r5],        %[r5]                       \n\t"
94    "shra_r.w       %[r6],        %[r6],        3             \n\t"
95    "shra_r.w       %[r7],        %[r7],        3             \n\t"
96    "sw             %[r6],        4(%[tmpre])                 \n\t"
97    "absq_s.w       %[r6],        %[r6]                       \n\t"
98    "sw             %[r7],        4(%[tmpim])                 \n\t"
99    "absq_s.w       %[r7],        %[r7]                       \n\t"
100    "slt            %[r0],        %[r4],        %[r5]         \n\t"
101    "movn           %[r4],        %[r5],        %[r0]         \n\t"
102    "slt            %[r1],        %[r6],        %[r7]         \n\t"
103    "movn           %[r6],        %[r7],        %[r1]         \n\t"
104    "slt            %[r0],        %[max],       %[r4]         \n\t"
105    "movn           %[max],       %[r4],        %[r0]         \n\t"
106    "slt            %[r1],        %[max],       %[r6]         \n\t"
107    "movn           %[max],       %[r6],        %[r1]         \n\t"
108    "addiu          %[tmpre],     %[tmpre],     8             \n\t"
109    "bgtz           %[k],         1b                          \n\t"
110    " addiu         %[tmpim],     %[tmpim],     8             \n\t"
111#else  // #if defined(MIPS_DSP_R2_LE)
112    "lh             %[r0],        0(%[inre1])                 \n\t"
113    "lh             %[r1],        0(%[inre2])                 \n\t"
114    "lh             %[r2],        0(%[cosptr])                \n\t"
115    "lh             %[r3],        0(%[sinptr])                \n\t"
116    "addiu          %[k],         %[k],         -1            \n\t"
117    "mul            %[r4],        %[r0],        %[r2]         \n\t"
118    "mul            %[r5],        %[r1],        %[r3]         \n\t"
119    "mul            %[r0],        %[r0],        %[r3]         \n\t"
120    "mul            %[r2],        %[r1],        %[r2]         \n\t"
121    "addiu          %[inre1],     %[inre1],     2             \n\t"
122    "addiu          %[inre2],     %[inre2],     2             \n\t"
123    "addiu          %[cosptr],    %[cosptr],    2             \n\t"
124    "addiu          %[sinptr],    %[sinptr],    2             \n\t"
125    "addu           %[r1],        %[r4],        %[r5]         \n\t"
126    "sra            %[r1],        %[r1],        7             \n\t"
127    "sra            %[r3],        %[r1],        16            \n\t"
128    "andi           %[r1],        %[r1],        0xFFFF        \n\t"
129    "sra            %[r1],        %[r1],        1             \n\t"
130    "mul            %[r1],        %[factor],    %[r1]         \n\t"
131    "mul            %[r3],        %[factor],    %[r3]         \n\t"
132    "subu           %[r0],        %[r2],        %[r0]         \n\t"
133    "sra            %[r0],        %[r0],        7             \n\t"
134    "sra            %[r2],        %[r0],        16            \n\t"
135    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
136    "sra            %[r0],        %[r0],        1             \n\t"
137    "mul            %[r0],        %[factor],    %[r0]         \n\t"
138    "mul            %[r2],        %[factor],    %[r2]         \n\t"
139#if defined(MIPS_DSP_R1_LE)
140    "shra_r.w       %[r1],        %[r1],        15            \n\t"
141#else  // #if defined(MIPS_DSP_R1_LE)
142    "addiu          %[r1],        %[r1],        0x4000        \n\t"
143    "sra            %[r1],        %[r1],        15            \n\t"
144#endif  // #if defined(MIPS_DSP_R1_LE)
145    "addu           %[r1],        %[r3],        %[r1]         \n\t"
146#if defined(MIPS_DSP_R1_LE)
147    "shra_r.w       %[r1],        %[r1],        3             \n\t"
148#else  // #if defined(MIPS_DSP_R1_LE)
149    "addiu          %[r1],        %[r1],        4             \n\t"
150    "sra            %[r1],        %[r1],        3             \n\t"
151#endif  // #if defined(MIPS_DSP_R1_LE)
152    "sw             %[r1],        0(%[tmpre])                 \n\t"
153    "addiu          %[tmpre],     %[tmpre],     4             \n\t"
154#if defined(MIPS_DSP_R1_LE)
155    "absq_s.w       %[r1],        %[r1]                       \n\t"
156    "shra_r.w       %[r0],        %[r0],        15            \n\t"
157#else  // #if defined(MIPS_DSP_R1_LE)
158    "negu           %[r4],        %[r1]                       \n\t"
159    "slt            %[r3],        %[r1],        $zero         \n\t"
160    "movn           %[r1],        %[r4],        %[r3]         \n\t"
161    "addiu          %[r0],        %[r0],        0x4000        \n\t"
162    "sra            %[r0],        %[r0],        15            \n\t"
163#endif  // #if defined(MIPS_DSP_R1_LE)
164    "addu           %[r0],        %[r0],        %[r2]         \n\t"
165#if defined(MIPS_DSP_R1_LE)
166    "shra_r.w       %[r0],        %[r0],        3             \n\t"
167    "sw             %[r0],        0(%[tmpim])                 \n\t"
168    "absq_s.w       %[r0],        %[r0]                       \n\t"
169#else  // #if defined(MIPS_DSP_R1_LE)
170    "addiu          %[r0],        %[r0],        4             \n\t"
171    "sra            %[r0],        %[r0],        3             \n\t"
172    "sw             %[r0],        0(%[tmpim])                 \n\t"
173    "negu           %[r2],        %[r0]                       \n\t"
174    "slt            %[r3],        %[r0],        $zero         \n\t"
175    "movn           %[r0],        %[r2],        %[r3]         \n\t"
176#endif  // #if defined(MIPS_DSP_R1_LE)
177    "slt            %[r2],        %[max],       %[r1]         \n\t"
178    "movn           %[max],       %[r1],        %[r2]         \n\t"
179    "slt            %[r2],        %[max],       %[r0]         \n\t"
180    "movn           %[max],       %[r0],        %[r2]         \n\t"
181    "bgtz           %[k],         1b                          \n\t"
182    " addiu         %[tmpim],     %[tmpim],     4             \n\t"
183#endif  // #if defined(MIPS_DSP_R2_LE)
184    // Calculate WebRtcSpl_NormW32(max).
185    // If max gets value >=0, we should shift max steps to the left, and the
186    // domain will be Q(16+shift). If max gets value <0, we should shift -max
187    // steps to the right, and the domain will be Q(16+max)
188    "clz            %[max],       %[max]                      \n\t"
189    "addiu          %[max],       %[max],       -25           \n\t"
190    ".set           pop                                       \n\t"
191    : [k] "+r" (k), [inre1] "=&r" (inre1), [inre2] "=&r" (inre2),
192      [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2),
193      [r3] "=&r" (r3), [r4] "=&r" (r4), [tmpre] "=&r" (tmpre),
194      [tmpim] "=&r" (tmpim), [max] "=&r" (max), [factor] "=&r" (factor),
195#if defined(MIPS_DSP_R2_LE)
196      [r6] "=&r" (r6), [r7] "=&r" (r7), [r8] "=&r" (r8),
197#endif  // #if defined(MIPS_DSP_R2_LE)
198      [r5] "=&r" (r5)
199    : [inre1Q9] "r" (inre1Q9), [inre2Q9] "r" (inre2Q9),
200      [tmpreQ16] "r" (tmpreQ16), [tmpimQ16] "r" (tmpimQ16),
201      [cosptr] "r" (cosptr), [sinptr] "r" (sinptr)
202    : "hi", "lo", "memory"
203#if defined(MIPS_DSP_R2_LE)
204    , "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi", "$ac3lo"
205#endif  // #if defined(MIPS_DSP_R2_LE)
206  );
207
208  // "Fastest" vectors
209  k = FRAMESAMPLES / 4;
210  __asm __volatile (
211    ".set           push                                      \n\t"
212    ".set           noreorder                                 \n\t"
213    "addiu          %[tmpre],     %[tmpreQ16],  0             \n\t"
214    "addiu          %[tmpim],     %[tmpimQ16],  0             \n\t"
215    "addiu          %[inre1],     %[inre1Q9],   0             \n\t"
216    "addiu          %[inre2],     %[inre2Q9],   0             \n\t"
217    "blez           %[max],       2f                          \n\t"
218    " subu          %[max1],      $zero,        %[max]        \n\t"
219   "1:                                                        \n\t"
220    "lw             %[r0],        0(%[tmpre])                 \n\t"
221    "lw             %[r1],        0(%[tmpim])                 \n\t"
222    "lw             %[r2],        4(%[tmpre])                 \n\t"
223    "lw             %[r3],        4(%[tmpim])                 \n\t"
224    "addiu          %[k],         %[k],         -1            \n\t"
225    "sllv           %[r0],        %[r0],        %[max]        \n\t"
226    "sllv           %[r1],        %[r1],        %[max]        \n\t"
227    "sllv           %[r2],        %[r2],        %[max]        \n\t"
228    "sllv           %[r3],        %[r3],        %[max]        \n\t"
229    "addiu          %[tmpre],     %[tmpre],     8             \n\t"
230    "addiu          %[tmpim],     %[tmpim],     8             \n\t"
231    "sh             %[r0],        0(%[inre1])                 \n\t"
232    "sh             %[r1],        0(%[inre2])                 \n\t"
233    "sh             %[r2],        2(%[inre1])                 \n\t"
234    "sh             %[r3],        2(%[inre2])                 \n\t"
235    "addiu          %[inre1],     %[inre1],     4             \n\t"
236    "bgtz           %[k],         1b                          \n\t"
237    " addiu         %[inre2],     %[inre2],     4             \n\t"
238    "b              4f                                        \n\t"
239    " nop                                                     \n\t"
240   "2:                                                        \n\t"
241#if !defined(MIPS_DSP_R1_LE)
242    "addiu          %[r4],        %[max1],      -1            \n\t"
243    "addiu          %[r5],        $zero,        1             \n\t"
244    "sllv           %[r4],        %[r5],        %[r4]         \n\t"
245#endif // #if !defined(MIPS_DSP_R1_LE)
246   "3:                                                        \n\t"
247    "lw             %[r0],        0(%[tmpre])                 \n\t"
248    "lw             %[r1],        0(%[tmpim])                 \n\t"
249    "lw             %[r2],        4(%[tmpre])                 \n\t"
250    "lw             %[r3],        4(%[tmpim])                 \n\t"
251    "addiu          %[k],         %[k],         -1            \n\t"
252#if defined(MIPS_DSP_R1_LE)
253    "shrav_r.w      %[r0],        %[r0],        %[max1]       \n\t"
254    "shrav_r.w      %[r1],        %[r1],        %[max1]       \n\t"
255    "shrav_r.w      %[r2],        %[r2],        %[max1]       \n\t"
256    "shrav_r.w      %[r3],        %[r3],        %[max1]       \n\t"
257#else // #if !defined(MIPS_DSP_R1_LE)
258    "addu           %[r0],        %[r0],        %[r4]         \n\t"
259    "addu           %[r1],        %[r1],        %[r4]         \n\t"
260    "addu           %[r2],        %[r2],        %[r4]         \n\t"
261    "addu           %[r3],        %[r3],        %[r4]         \n\t"
262    "srav           %[r0],        %[r0],        %[max1]       \n\t"
263    "srav           %[r1],        %[r1],        %[max1]       \n\t"
264    "srav           %[r2],        %[r2],        %[max1]       \n\t"
265    "srav           %[r3],        %[r3],        %[max1]       \n\t"
266#endif // #if !defined(MIPS_DSP_R1_LE)
267    "addiu          %[tmpre],     %[tmpre],     8             \n\t"
268    "addiu          %[tmpim],     %[tmpim],     8             \n\t"
269    "sh             %[r0],        0(%[inre1])                 \n\t"
270    "sh             %[r1],        0(%[inre2])                 \n\t"
271    "sh             %[r2],        2(%[inre1])                 \n\t"
272    "sh             %[r3],        2(%[inre2])                 \n\t"
273    "addiu          %[inre1],     %[inre1],     4             \n\t"
274    "bgtz           %[k],         3b                          \n\t"
275    " addiu         %[inre2],     %[inre2],     4             \n\t"
276   "4:                                                        \n\t"
277    ".set           pop                                       \n\t"
278    : [tmpre] "=&r" (tmpre), [tmpim] "=&r" (tmpim), [inre1] "=&r" (inre1),
279      [inre2] "=&r" (inre2), [k] "+r" (k), [max1] "=&r" (max1),
280#if !defined(MIPS_DSP_R1_LE)
281      [r4] "=&r" (r4), [r5] "=&r" (r5),
282#endif // #if !defined(MIPS_DSP_R1_LE)
283      [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3)
284    : [tmpreQ16] "r" (tmpreQ16), [tmpimQ16] "r" (tmpimQ16),
285      [inre1Q9] "r" (inre1Q9), [inre2Q9] "r" (inre2Q9), [max] "r" (max)
286    : "memory"
287  );
288
289  // Get DFT
290  WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call
291
292  // "Fastest" vectors and
293  // Use symmetry to separate into two complex vectors
294  // and center frames in time around zero
295  // merged into one loop
296  cosptr = (int16_t*)WebRtcIsacfix_kCosTab2;
297  sinptr = (int16_t*)WebRtcIsacfix_kSinTab2;
298  k = FRAMESAMPLES / 4;
299  factor = FRAMESAMPLES - 2;  // offset for FRAMESAMPLES / 2 - 1 array member
300
301  __asm __volatile (
302    ".set           push                                      \n\t"
303    ".set           noreorder                                 \n\t"
304    "addiu          %[inre1],     %[inre1Q9],   0             \n\t"
305    "addiu          %[inre2],     %[inre2Q9],   0             \n\t"
306    "addiu          %[tmpre],     %[outreQ7],   0             \n\t"
307    "addiu          %[tmpim],     %[outimQ7],   0             \n\t"
308    "bltz           %[max],       2f                          \n\t"
309    " subu          %[max1],      $zero,        %[max]        \n\t"
310   "1:                                                        \n\t"
311#if !defined(MIPS_DSP_R1_LE)
312    "addu           %[r4],        %[inre1],     %[offset]     \n\t"
313    "addu           %[r5],        %[inre2],     %[offset]     \n\t"
314#endif  // #if !defined(MIPS_DSP_R1_LE)
315    "lh             %[r0],        0(%[inre1])                 \n\t"
316    "lh             %[r1],        0(%[inre2])                 \n\t"
317#if defined(MIPS_DSP_R1_LE)
318    "lhx            %[r2],        %[offset](%[inre1])         \n\t"
319    "lhx            %[r3],        %[offset](%[inre2])         \n\t"
320#else  // #if defined(MIPS_DSP_R1_LE)
321    "lh             %[r2],        0(%[r4])                    \n\t"
322    "lh             %[r3],        0(%[r5])                    \n\t"
323#endif  // #if defined(MIPS_DSP_R1_LE)
324    "srav           %[r0],        %[r0],        %[max]        \n\t"
325    "srav           %[r1],        %[r1],        %[max]        \n\t"
326    "srav           %[r2],        %[r2],        %[max]        \n\t"
327    "srav           %[r3],        %[r3],        %[max]        \n\t"
328    "addu           %[r4],        %[r0],        %[r2]         \n\t"
329    "subu           %[r0],        %[r2],        %[r0]         \n\t"
330    "subu           %[r2],        %[r1],        %[r3]         \n\t"
331    "addu           %[r1],        %[r1],        %[r3]         \n\t"
332    "lh             %[r3],        0(%[cosptr])                \n\t"
333    "lh             %[r5],        0(%[sinptr])                \n\t"
334    "andi           %[r6],        %[r4],        0xFFFF        \n\t"
335    "sra            %[r4],        %[r4],        16            \n\t"
336    "mul            %[r7],        %[r3],        %[r6]         \n\t"
337    "mul            %[r8],        %[r3],        %[r4]         \n\t"
338    "mul            %[r6],        %[r5],        %[r6]         \n\t"
339    "mul            %[r4],        %[r5],        %[r4]         \n\t"
340    "addiu          %[k],         %[k],         -1            \n\t"
341    "addiu          %[inre1],     %[inre1],     2             \n\t"
342    "addiu          %[inre2],     %[inre2],     2             \n\t"
343#if defined(MIPS_DSP_R1_LE)
344    "shra_r.w       %[r7],        %[r7],        14            \n\t"
345#else  // #if defined(MIPS_DSP_R1_LE)
346    "addiu          %[r7],        %[r7],        0x2000        \n\t"
347    "sra            %[r7],        %[r7],        14            \n\t"
348#endif  // #if defined(MIPS_DSP_R1_LE)
349    "sll            %[r8],        %[r8],        2             \n\t"
350    "addu           %[r8],        %[r8],        %[r7]         \n\t"
351#if defined(MIPS_DSP_R1_LE)
352    "shra_r.w       %[r6],        %[r6],        14            \n\t"
353#else  // #if defined(MIPS_DSP_R1_LE)
354    "addiu          %[r6],        %[r6],        0x2000        \n\t"
355    "sra            %[r6],        %[r6],        14            \n\t"
356#endif  // #if defined(MIPS_DSP_R1_LE)
357    "sll            %[r4],        %[r4],        2             \n\t"
358    "addu           %[r4],        %[r4],        %[r6]         \n\t"
359    "andi           %[r6],        %[r2],        0xFFFF        \n\t"
360    "sra            %[r2],        %[r2],        16            \n\t"
361    "mul            %[r7],        %[r5],        %[r6]         \n\t"
362    "mul            %[r9],        %[r5],        %[r2]         \n\t"
363    "mul            %[r6],        %[r3],        %[r6]         \n\t"
364    "mul            %[r2],        %[r3],        %[r2]         \n\t"
365    "addiu          %[cosptr],    %[cosptr],    2             \n\t"
366    "addiu          %[sinptr],    %[sinptr],    2             \n\t"
367#if defined(MIPS_DSP_R1_LE)
368    "shra_r.w       %[r7],        %[r7],        14            \n\t"
369#else  // #if defined(MIPS_DSP_R1_LE)
370    "addiu          %[r7],        %[r7],        0x2000        \n\t"
371    "sra            %[r7],        %[r7],        14            \n\t"
372#endif  // #if defined(MIPS_DSP_R1_LE)
373    "sll            %[r9],        %[r9],        2             \n\t"
374    "addu           %[r9],        %[r7],        %[r9]         \n\t"
375#if defined(MIPS_DSP_R1_LE)
376    "shra_r.w       %[r6],        %[r6],        14            \n\t"
377#else  // #if defined(MIPS_DSP_R1_LE)
378    "addiu          %[r6],        %[r6],        0x2000        \n\t"
379    "sra            %[r6],        %[r6],        14            \n\t"
380#endif  // #if defined(MIPS_DSP_R1_LE)
381    "sll            %[r2],        %[r2],        2             \n\t"
382    "addu           %[r2],        %[r6],        %[r2]         \n\t"
383    "subu           %[r8],        %[r8],        %[r9]         \n\t"
384    "sra            %[r8],        %[r8],        9             \n\t"
385    "addu           %[r2],        %[r4],        %[r2]         \n\t"
386    "sra            %[r2],        %[r2],        9             \n\t"
387    "sh             %[r8],        0(%[tmpre])                 \n\t"
388    "sh             %[r2],        0(%[tmpim])                 \n\t"
389
390    "andi           %[r4],        %[r1],        0xFFFF        \n\t"
391    "sra            %[r1],        %[r1],        16            \n\t"
392    "andi           %[r6],        %[r0],        0xFFFF        \n\t"
393    "sra            %[r0],        %[r0],        16            \n\t"
394    "mul            %[r7],        %[r5],        %[r4]         \n\t"
395    "mul            %[r9],        %[r5],        %[r1]         \n\t"
396    "mul            %[r4],        %[r3],        %[r4]         \n\t"
397    "mul            %[r1],        %[r3],        %[r1]         \n\t"
398    "mul            %[r8],        %[r3],        %[r0]         \n\t"
399    "mul            %[r3],        %[r3],        %[r6]         \n\t"
400    "mul            %[r6],        %[r5],        %[r6]         \n\t"
401    "mul            %[r0],        %[r5],        %[r0]         \n\t"
402#if defined(MIPS_DSP_R1_LE)
403    "shra_r.w       %[r7],        %[r7],        14            \n\t"
404#else  // #if defined(MIPS_DSP_R1_LE)
405    "addiu          %[r7],        %[r7],        0x2000        \n\t"
406    "sra            %[r7],        %[r7],        14            \n\t"
407#endif  // #if defined(MIPS_DSP_R1_LE)
408    "sll            %[r9],        %[r9],        2             \n\t"
409    "addu           %[r9],        %[r9],        %[r7]         \n\t"
410#if defined(MIPS_DSP_R1_LE)
411    "shra_r.w       %[r4],        %[r4],        14            \n\t"
412#else  // #if defined(MIPS_DSP_R1_LE)
413    "addiu          %[r4],        %[r4],        0x2000        \n\t"
414    "sra            %[r4],        %[r4],        14            \n\t"
415#endif  // #if defined(MIPS_DSP_R1_LE)
416    "sll            %[r1],        %[r1],        2             \n\t"
417    "addu           %[r1],        %[r1],        %[r4]         \n\t"
418#if defined(MIPS_DSP_R1_LE)
419    "shra_r.w       %[r3],        %[r3],        14            \n\t"
420#else  // #if defined(MIPS_DSP_R1_LE)
421    "addiu          %[r3],        %[r3],        0x2000        \n\t"
422    "sra            %[r3],        %[r3],        14            \n\t"
423#endif  // #if defined(MIPS_DSP_R1_LE)
424    "sll            %[r8],        %[r8],        2             \n\t"
425    "addu           %[r8],        %[r8],        %[r3]         \n\t"
426#if defined(MIPS_DSP_R1_LE)
427    "shra_r.w       %[r6],        %[r6],        14            \n\t"
428#else  // #if defined(MIPS_DSP_R1_LE)
429    "addiu          %[r6],        %[r6],        0x2000        \n\t"
430    "sra            %[r6],        %[r6],        14            \n\t"
431#endif  // #if defined(MIPS_DSP_R1_LE)
432    "sll            %[r0],        %[r0],        2             \n\t"
433    "addu           %[r0],        %[r0],        %[r6]         \n\t"
434    "addu           %[r3],        %[tmpre],     %[offset]     \n\t"
435    "addu           %[r2],        %[tmpim],     %[offset]     \n\t"
436    "addu           %[r9],        %[r9],        %[r8]         \n\t"
437    "negu           %[r9],        %[r9]                       \n\t"
438    "sra            %[r9],        %[r9],        9             \n\t"
439    "subu           %[r0],        %[r0],        %[r1]         \n\t"
440    "addiu          %[offset],    %[offset],    -4            \n\t"
441    "sh             %[r9],        0(%[r3])                    \n\t"
442    "sh             %[r0],        0(%[r2])                    \n\t"
443    "addiu          %[tmpre],     %[tmpre],     2             \n\t"
444    "bgtz           %[k],         1b                          \n\t"
445    " addiu         %[tmpim],     %[tmpim],     2             \n\t"
446    "b              3f                                        \n\t"
447    " nop                                                     \n\t"
448   "2:                                                        \n\t"
449#if !defined(MIPS_DSP_R1_LE)
450    "addu           %[r4],        %[inre1],     %[offset]     \n\t"
451    "addu           %[r5],        %[inre2],     %[offset]     \n\t"
452#endif  // #if !defined(MIPS_DSP_R1_LE)
453    "lh             %[r0],        0(%[inre1])                 \n\t"
454    "lh             %[r1],        0(%[inre2])                 \n\t"
455#if defined(MIPS_DSP_R1_LE)
456    "lhx            %[r2],        %[offset](%[inre1])         \n\t"
457    "lhx            %[r3],        %[offset](%[inre2])         \n\t"
458#else  // #if defined(MIPS_DSP_R1_LE)
459    "lh             %[r2],        0(%[r4])                    \n\t"
460    "lh             %[r3],        0(%[r5])                    \n\t"
461#endif  // #if defined(MIPS_DSP_R1_LE)
462    "sllv           %[r0],        %[r0],        %[max1]       \n\t"
463    "sllv           %[r1],        %[r1],        %[max1]       \n\t"
464    "sllv           %[r2],        %[r2],        %[max1]       \n\t"
465    "sllv           %[r3],        %[r3],        %[max1]       \n\t"
466    "addu           %[r4],        %[r0],        %[r2]         \n\t"
467    "subu           %[r0],        %[r2],        %[r0]         \n\t"
468    "subu           %[r2],        %[r1],        %[r3]         \n\t"
469    "addu           %[r1],        %[r1],        %[r3]         \n\t"
470    "lh             %[r3],        0(%[cosptr])                \n\t"
471    "lh             %[r5],        0(%[sinptr])                \n\t"
472    "andi           %[r6],        %[r4],        0xFFFF        \n\t"
473    "sra            %[r4],        %[r4],        16            \n\t"
474    "mul            %[r7],        %[r3],        %[r6]         \n\t"
475    "mul            %[r8],        %[r3],        %[r4]         \n\t"
476    "mul            %[r6],        %[r5],        %[r6]         \n\t"
477    "mul            %[r4],        %[r5],        %[r4]         \n\t"
478    "addiu          %[k],         %[k],         -1            \n\t"
479    "addiu          %[inre1],     %[inre1],     2             \n\t"
480    "addiu          %[inre2],     %[inre2],     2             \n\t"
481#if defined(MIPS_DSP_R1_LE)
482    "shra_r.w       %[r7],        %[r7],        14            \n\t"
483#else  // #if defined(MIPS_DSP_R1_LE)
484    "addiu          %[r7],        %[r7],        0x2000        \n\t"
485    "sra            %[r7],        %[r7],        14            \n\t"
486#endif  // #if defined(MIPS_DSP_R1_LE)
487    "sll            %[r8],        %[r8],        2             \n\t"
488    "addu           %[r8],        %[r8],        %[r7]         \n\t"
489#if defined(MIPS_DSP_R1_LE)
490    "shra_r.w       %[r6],        %[r6],        14            \n\t"
491#else  // #if defined(MIPS_DSP_R1_LE)
492    "addiu          %[r6],        %[r6],        0x2000        \n\t"
493    "sra            %[r6],        %[r6],        14            \n\t"
494#endif  // #if defined(MIPS_DSP_R1_LE)
495    "sll            %[r4],        %[r4],        2             \n\t"
496    "addu           %[r4],        %[r4],        %[r6]         \n\t"
497    "andi           %[r6],        %[r2],        0xFFFF        \n\t"
498    "sra            %[r2],        %[r2],        16            \n\t"
499    "mul            %[r7],        %[r5],        %[r6]         \n\t"
500    "mul            %[r9],        %[r5],        %[r2]         \n\t"
501    "mul            %[r6],        %[r3],        %[r6]         \n\t"
502    "mul            %[r2],        %[r3],        %[r2]         \n\t"
503    "addiu          %[cosptr],    %[cosptr],    2             \n\t"
504    "addiu          %[sinptr],    %[sinptr],    2             \n\t"
505#if defined(MIPS_DSP_R1_LE)
506    "shra_r.w       %[r7],        %[r7],        14            \n\t"
507#else  // #if defined(MIPS_DSP_R1_LE)
508    "addiu          %[r7],        %[r7],        0x2000        \n\t"
509    "sra            %[r7],        %[r7],        14            \n\t"
510#endif  // #if defined(MIPS_DSP_R1_LE)
511    "sll            %[r9],        %[r9],        2             \n\t"
512    "addu           %[r9],        %[r7],        %[r9]         \n\t"
513#if defined(MIPS_DSP_R1_LE)
514    "shra_r.w       %[r6],        %[r6],        14            \n\t"
515#else  // #if defined(MIPS_DSP_R1_LE)
516    "addiu          %[r6],        %[r6],        0x2000        \n\t"
517    "sra            %[r6],        %[r6],        14            \n\t"
518#endif  // #if defined(MIPS_DSP_R1_LE)
519    "sll            %[r2],        %[r2],        2             \n\t"
520    "addu           %[r2],        %[r6],        %[r2]         \n\t"
521    "subu           %[r8],        %[r8],        %[r9]         \n\t"
522    "sra            %[r8],        %[r8],        9             \n\t"
523    "addu           %[r2],        %[r4],        %[r2]         \n\t"
524    "sra            %[r2],        %[r2],        9             \n\t"
525    "sh             %[r8],        0(%[tmpre])                 \n\t"
526    "sh             %[r2],        0(%[tmpim])                 \n\t"
527    "andi           %[r4],        %[r1],        0xFFFF        \n\t"
528    "sra            %[r1],        %[r1],        16            \n\t"
529    "andi           %[r6],        %[r0],        0xFFFF        \n\t"
530    "sra            %[r0],        %[r0],        16            \n\t"
531    "mul            %[r7],        %[r5],        %[r4]         \n\t"
532    "mul            %[r9],        %[r5],        %[r1]         \n\t"
533    "mul            %[r4],        %[r3],        %[r4]         \n\t"
534    "mul            %[r1],        %[r3],        %[r1]         \n\t"
535    "mul            %[r8],        %[r3],        %[r0]         \n\t"
536    "mul            %[r3],        %[r3],        %[r6]         \n\t"
537    "mul            %[r6],        %[r5],        %[r6]         \n\t"
538    "mul            %[r0],        %[r5],        %[r0]         \n\t"
539#if defined(MIPS_DSP_R1_LE)
540    "shra_r.w       %[r7],        %[r7],        14            \n\t"
541#else  // #if defined(MIPS_DSP_R1_LE)
542    "addiu          %[r7],        %[r7],        0x2000        \n\t"
543    "sra            %[r7],        %[r7],        14            \n\t"
544#endif  // #if defined(MIPS_DSP_R1_LE)
545    "sll            %[r9],        %[r9],        2             \n\t"
546    "addu           %[r9],        %[r9],        %[r7]         \n\t"
547#if defined(MIPS_DSP_R1_LE)
548    "shra_r.w       %[r4],        %[r4],        14            \n\t"
549#else  // #if defined(MIPS_DSP_R1_LE)
550    "addiu          %[r4],        %[r4],        0x2000        \n\t"
551    "sra            %[r4],        %[r4],        14            \n\t"
552#endif
553    "sll            %[r1],        %[r1],        2             \n\t"
554    "addu           %[r1],        %[r1],        %[r4]         \n\t"
555#if defined(MIPS_DSP_R1_LE)
556    "shra_r.w       %[r3],        %[r3],        14            \n\t"
557#else  // #if defined(MIPS_DSP_R1_LE)
558    "addiu          %[r3],        %[r3],        0x2000        \n\t"
559    "sra            %[r3],        %[r3],        14            \n\t"
560#endif  // #if defined(MIPS_DSP_R1_LE)
561    "sll            %[r8],        %[r8],        2             \n\t"
562    "addu           %[r8],        %[r8],        %[r3]         \n\t"
563#if defined(MIPS_DSP_R1_LE)
564    "shra_r.w       %[r6],        %[r6],        14            \n\t"
565#else  // #if defined(MIPS_DSP_R1_LE)
566    "addiu          %[r6],        %[r6],        0x2000        \n\t"
567    "sra            %[r6],        %[r6],        14            \n\t"
568#endif  // #if defined(MIPS_DSP_R1_LE)
569    "sll            %[r0],        %[r0],        2             \n\t"
570    "addu           %[r0],        %[r0],        %[r6]         \n\t"
571    "addu           %[r3],        %[tmpre],     %[offset]     \n\t"
572    "addu           %[r2],        %[tmpim],     %[offset]     \n\t"
573    "addu           %[r9],        %[r9],        %[r8]         \n\t"
574    "negu           %[r9],        %[r9]                       \n\t"
575    "sra            %[r9],        %[r9],        9             \n\t"
576    "subu           %[r0],        %[r0],        %[r1]         \n\t"
577    "sra            %[r0],        %[r0],        9             \n\t"
578    "addiu          %[offset],    %[offset],    -4            \n\t"
579    "sh             %[r9],        0(%[r3])                    \n\t"
580    "sh             %[r0],        0(%[r2])                    \n\t"
581    "addiu          %[tmpre],     %[tmpre],     2             \n\t"
582    "bgtz           %[k],         2b                          \n\t"
583    " addiu         %[tmpim],     %[tmpim],     2             \n\t"
584   "3:                                                        \n\t"
585    ".set           pop                                       \n\t"
586    : [inre1] "=&r" (inre1), [inre2] "=&r" (inre2), [tmpre] "=&r" (tmpre),
587      [tmpim] "=&r" (tmpim), [offset] "+r" (factor), [k] "+r" (k),
588      [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
589      [r4] "=&r" (r4), [r5] "=&r" (r5), [r6] "=&r" (r6), [r7] "=&r" (r7),
590      [r8] "=&r" (r8), [r9] "=&r" (r9), [max1] "=&r" (max1)
591    : [inre1Q9] "r" (inre1Q9), [inre2Q9] "r" (inre2Q9),
592      [outreQ7] "r" (outreQ7), [outimQ7] "r" (outimQ7),
593      [max] "r" (max), [cosptr] "r" (cosptr), [sinptr] "r" (sinptr)
594    : "hi", "lo", "memory"
595  );
596}
597
598void WebRtcIsacfix_Spec2TimeMIPS(int16_t *inreQ7,
599                                 int16_t *inimQ7,
600                                 int32_t *outre1Q16,
601                                 int32_t *outre2Q16) {
602  int k = FRAMESAMPLES / 4;
603  int16_t* inre;
604  int16_t* inim;
605  int32_t* outre1;
606  int32_t* outre2;
607  int16_t* cosptr = (int16_t*)WebRtcIsacfix_kCosTab2;
608  int16_t* sinptr = (int16_t*)WebRtcIsacfix_kSinTab2;
609  int32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, max, max1;
610#if defined(MIPS_DSP_R1_LE)
611  int32_t offset = FRAMESAMPLES - 4;
612#else  // #if defined(MIPS_DSP_R1_LE)
613  int32_t offset = FRAMESAMPLES - 2;
614#endif  // #if defined(MIPS_DSP_R1_LE)
615
616  __asm __volatile (
617    ".set           push                                      \n\t"
618    ".set           noreorder                                 \n\t"
619    "addiu          %[inre],      %[inreQ7],    0             \n\t"
620    "addiu          %[inim] ,     %[inimQ7],    0             \n\t"
621    "addiu          %[outre1],    %[outre1Q16], 0             \n\t"
622    "addiu          %[outre2],    %[outre2Q16], 0             \n\t"
623    "mul            %[max],       $zero,        $zero         \n\t"
624   "1:                                                        \n\t"
625#if defined(MIPS_DSP_R1_LE)
626    // Process two samples in one iteration avoiding left shift before
627    // multiplication. MaxAbsValueW32 function inlined into the loop.
628    "addu           %[r8],        %[inre],      %[offset]     \n\t"
629    "addu           %[r9],        %[inim],      %[offset]     \n\t"
630    "lwl            %[r4],        0(%[r8])                    \n\t"
631    "lwl            %[r5],        0(%[r9])                    \n\t"
632    "lwl            %[r0],        0(%[inre])                  \n\t"
633    "lwl            %[r1],        0(%[inim])                  \n\t"
634    "lwl            %[r2],        0(%[cosptr])                \n\t"
635    "lwl            %[r3],        0(%[sinptr])                \n\t"
636    "lwr            %[r4],        0(%[r8])                    \n\t"
637    "lwr            %[r5],        0(%[r9])                    \n\t"
638    "lwr            %[r0],        0(%[inre])                  \n\t"
639    "lwr            %[r1],        0(%[inim])                  \n\t"
640    "lwr            %[r2],        0(%[cosptr])                \n\t"
641    "lwr            %[r3],        0(%[sinptr])                \n\t"
642    "packrl.ph      %[r4],        %[r4],        %[r4]         \n\t"
643    "packrl.ph      %[r5],        %[r5],        %[r5]         \n\t"
644    "muleq_s.w.phr  %[r6],        %[r0],        %[r2]         \n\t"
645    "muleq_s.w.phr  %[r7],        %[r1],        %[r3]         \n\t"
646    "muleq_s.w.phr  %[r8],        %[r4],        %[r2]         \n\t"
647    "muleq_s.w.phr  %[r9],        %[r5],        %[r3]         \n\t"
648    "addiu          %[k],         %[k],         -2            \n\t"
649    "addiu          %[cosptr],    %[cosptr],    4             \n\t"
650    "addiu          %[sinptr],    %[sinptr],    4             \n\t"
651    "addiu          %[inre],      %[inre],      4             \n\t"
652    "addiu          %[inim],      %[inim],      4             \n\t"
653    "shra_r.w       %[r6],        %[r6],        6             \n\t"
654    "shra_r.w       %[r7],        %[r7],        6             \n\t"
655    "shra_r.w       %[r8],        %[r8],        6             \n\t"
656    "shra_r.w       %[r9],        %[r9],        6             \n\t"
657    "addu           %[r6],        %[r6],        %[r7]         \n\t"
658    "subu           %[r9],        %[r9],        %[r8]         \n\t"
659    "subu           %[r7],        %[r6],        %[r9]         \n\t"
660    "addu           %[r6],        %[r6],        %[r9]         \n\t"
661    "sw             %[r7],        0(%[outre1])                \n\t"
662    "absq_s.w       %[r7],        %[r7]                       \n\t"
663    "slt            %[r8],        %[max],       %[r7]         \n\t"
664    "movn           %[max],       %[r7],        %[r8]         \n\t"
665    "sll            %[r7],        %[offset],    1             \n\t"
666    "addu           %[r7],        %[outre1],    %[r7]         \n\t"
667    "sw             %[r6],        4(%[r7])                    \n\t"
668    "absq_s.w       %[r6],        %[r6]                       \n\t"
669    "slt            %[r8],        %[max],       %[r6]         \n\t"
670    "movn           %[max],       %[r6],        %[r8]         \n\t"
671    "muleq_s.w.phl  %[r6],        %[r0],        %[r2]         \n\t"
672    "muleq_s.w.phl  %[r7],        %[r1],        %[r3]         \n\t"
673    "muleq_s.w.phl  %[r8],        %[r4],        %[r2]         \n\t"
674    "muleq_s.w.phl  %[r9],        %[r5],        %[r3]         \n\t"
675    "shra_r.w       %[r6],        %[r6],        6             \n\t"
676    "shra_r.w       %[r7],        %[r7],        6             \n\t"
677    "shra_r.w       %[r8],        %[r8],        6             \n\t"
678    "shra_r.w       %[r9],        %[r9],        6             \n\t"
679    "addu           %[r6],        %[r6],        %[r7]         \n\t"
680    "subu           %[r9],        %[r9],        %[r8]         \n\t"
681    "subu           %[r7],        %[r6],        %[r9]         \n\t"
682    "addu           %[r6],        %[r6],        %[r9]         \n\t"
683    "sw             %[r7],        4(%[outre1])                \n\t"
684    "absq_s.w       %[r7],        %[r7]                       \n\t"
685    "slt            %[r8],        %[max],       %[r7]         \n\t"
686    "movn           %[max],       %[r7],        %[r8]         \n\t"
687    "sll            %[r7],        %[offset],    1             \n\t"
688    "addu           %[r7],        %[outre1],    %[r7]         \n\t"
689    "sw             %[r6],        0(%[r7])                    \n\t"
690    "absq_s.w       %[r6],        %[r6]                       \n\t"
691    "slt            %[r8],        %[max],       %[r6]         \n\t"
692    "movn           %[max],       %[r6],        %[r8]         \n\t"
693    "muleq_s.w.phr  %[r6],        %[r1],        %[r2]         \n\t"
694    "muleq_s.w.phr  %[r7],        %[r0],        %[r3]         \n\t"
695    "muleq_s.w.phr  %[r8],        %[r5],        %[r2]         \n\t"
696    "muleq_s.w.phr  %[r9],        %[r4],        %[r3]         \n\t"
697    "addiu          %[outre1],    %[outre1],    8             \n\t"
698    "shra_r.w       %[r6],        %[r6],        6             \n\t"
699    "shra_r.w       %[r7],        %[r7],        6             \n\t"
700    "shra_r.w       %[r8],        %[r8],        6             \n\t"
701    "shra_r.w       %[r9],        %[r9],        6             \n\t"
702    "subu           %[r6],        %[r6],        %[r7]         \n\t"
703    "addu           %[r9],        %[r9],        %[r8]         \n\t"
704    "subu           %[r7],        %[r6],        %[r9]         \n\t"
705    "addu           %[r6],        %[r9],        %[r6]         \n\t"
706    "negu           %[r6],        %[r6]                       \n\t"
707    "sw             %[r7],        0(%[outre2])                \n\t"
708    "absq_s.w       %[r7],        %[r7]                       \n\t"
709    "slt            %[r8],        %[max],       %[r7]         \n\t"
710    "movn           %[max],       %[r7],        %[r8]         \n\t"
711    "sll            %[r7],        %[offset],    1             \n\t"
712    "addu           %[r7],        %[outre2],    %[r7]         \n\t"
713    "sw             %[r6],        4(%[r7])                    \n\t"
714    "absq_s.w       %[r6],        %[r6]                       \n\t"
715    "slt            %[r8],        %[max],       %[r6]         \n\t"
716    "movn           %[max],       %[r6],        %[r8]         \n\t"
717    "muleq_s.w.phl  %[r6],       %[r1],         %[r2]         \n\t"
718    "muleq_s.w.phl  %[r7],       %[r0],         %[r3]         \n\t"
719    "muleq_s.w.phl  %[r8],       %[r5],         %[r2]         \n\t"
720    "muleq_s.w.phl  %[r9],       %[r4],         %[r3]         \n\t"
721    "addiu          %[offset],   %[offset],     -8            \n\t"
722    "shra_r.w       %[r6],       %[r6],         6             \n\t"
723    "shra_r.w       %[r7],       %[r7],         6             \n\t"
724    "shra_r.w       %[r8],       %[r8],         6             \n\t"
725    "shra_r.w       %[r9],       %[r9],         6             \n\t"
726    "subu           %[r6],       %[r6],         %[r7]         \n\t"
727    "addu           %[r9],       %[r9],         %[r8]         \n\t"
728    "subu           %[r7],       %[r6],         %[r9]         \n\t"
729    "addu           %[r6],       %[r9],         %[r6]         \n\t"
730    "negu           %[r6],       %[r6]                        \n\t"
731    "sw             %[r7],       4(%[outre2])                 \n\t"
732    "absq_s.w       %[r7],       %[r7]                        \n\t"
733    "slt            %[r8],       %[max],        %[r7]         \n\t"
734    "movn           %[max],      %[r7],         %[r8]         \n\t"
735    "sll            %[r7],       %[offset],     1             \n\t"
736    "addu           %[r7],       %[outre2],     %[r7]         \n\t"
737    "sw             %[r6],       0(%[r7])                     \n\t"
738    "absq_s.w       %[r6],       %[r6]                        \n\t"
739    "slt            %[r8],       %[max],        %[r6]         \n\t"
740    "movn           %[max],      %[r6],         %[r8]         \n\t"
741    "bgtz           %[k],        1b                           \n\t"
742    " addiu         %[outre2],   %[outre2],     8             \n\t"
743#else  // #if defined(MIPS_DSP_R1_LE)
744    "lh             %[r0],       0(%[inre])                   \n\t"
745    "lh             %[r1],       0(%[inim])                   \n\t"
746    "lh             %[r4],       0(%[cosptr])                 \n\t"
747    "lh             %[r5],       0(%[sinptr])                 \n\t"
748    "addiu          %[k],        %[k],          -1            \n\t"
749    "mul            %[r2],       %[r0],         %[r4]         \n\t"
750    "mul            %[r0],       %[r0],         %[r5]         \n\t"
751    "mul            %[r3],       %[r1],         %[r5]         \n\t"
752    "mul            %[r1],       %[r1],         %[r4]         \n\t"
753    "addiu          %[cosptr],   %[cosptr],     2             \n\t"
754    "addiu          %[sinptr],   %[sinptr],     2             \n\t"
755    "addu           %[r8],       %[inre],       %[offset]     \n\t"
756    "addu           %[r9],       %[inim],       %[offset]     \n\t"
757    "addiu          %[r2],       %[r2],         16            \n\t"
758    "sra            %[r2],       %[r2],         5             \n\t"
759    "addiu          %[r0],       %[r0],         16            \n\t"
760    "sra            %[r0],       %[r0],         5             \n\t"
761    "addiu          %[r3],       %[r3],         16            \n\t"
762    "sra            %[r3],       %[r3],         5             \n\t"
763    "lh             %[r6],       0(%[r8])                     \n\t"
764    "lh             %[r7],       0(%[r9])                     \n\t"
765    "addiu          %[r1],       %[r1],         16            \n\t"
766    "sra            %[r1],       %[r1],         5             \n\t"
767    "mul            %[r8],       %[r7],         %[r4]         \n\t"
768    "mul            %[r7],       %[r7],         %[r5]         \n\t"
769    "mul            %[r9],       %[r6],         %[r4]         \n\t"
770    "mul            %[r6],       %[r6],         %[r5]         \n\t"
771    "addu           %[r2],       %[r2],         %[r3]         \n\t"
772    "subu           %[r1],       %[r1],         %[r0]         \n\t"
773    "sll            %[r0],       %[offset],     1             \n\t"
774    "addu           %[r4],       %[outre1],     %[r0]         \n\t"
775    "addu           %[r5],       %[outre2],     %[r0]         \n\t"
776    "addiu          %[r8],       %[r8],         16            \n\t"
777    "sra            %[r8],       %[r8],         5             \n\t"
778    "addiu          %[r7],       %[r7],         16            \n\t"
779    "sra            %[r7],       %[r7],         5             \n\t"
780    "addiu          %[r6],       %[r6],         16            \n\t"
781    "sra            %[r6],       %[r6],         5             \n\t"
782    "addiu          %[r9],       %[r9],         16            \n\t"
783    "sra            %[r9],       %[r9],         5             \n\t"
784    "addu           %[r8],       %[r8],         %[r6]         \n\t"
785    "negu           %[r8],       %[r8]                        \n\t"
786    "subu           %[r7],       %[r7],         %[r9]         \n\t"
787    "subu           %[r6],       %[r2],         %[r7]         \n\t"
788    "addu           %[r0],       %[r2],         %[r7]         \n\t"
789    "addu           %[r3],       %[r1],         %[r8]         \n\t"
790    "subu           %[r1],       %[r8],         %[r1]         \n\t"
791    "sw             %[r6],       0(%[outre1])                 \n\t"
792    "sw             %[r0],       0(%[r4])                     \n\t"
793    "sw             %[r3],       0(%[outre2])                 \n\t"
794    "sw             %[r1],       0(%[r5])                     \n\t"
795    "addiu          %[outre1],   %[outre1],     4             \n\t"
796    "addiu          %[offset],   %[offset],     -4            \n\t"
797    "addiu          %[inre],     %[inre],       2             \n\t"
798    "addiu          %[inim],     %[inim],       2             \n\t"
799    // Inlined WebRtcSpl_MaxAbsValueW32
800    "negu           %[r5],       %[r6]                        \n\t"
801    "slt            %[r2],       %[r6],         $zero         \n\t"
802    "movn           %[r6],       %[r5],         %[r2]         \n\t"
803    "negu           %[r5],       %[r0]                        \n\t"
804    "slt            %[r2],       %[r0],         $zero         \n\t"
805    "movn           %[r0],       %[r5],         %[r2]         \n\t"
806    "negu           %[r5],       %[r3]                        \n\t"
807    "slt            %[r2],       %[r3],         $zero         \n\t"
808    "movn           %[r3],       %[r5],         %[r2]         \n\t"
809    "negu           %[r5],       %[r1]                        \n\t"
810    "slt            %[r2],       %[r1],         $zero         \n\t"
811    "movn           %[r1],       %[r5],         %[r2]         \n\t"
812    "slt            %[r2],       %[r6],         %[r0]         \n\t"
813    "slt            %[r5],       %[r3],         %[r1]         \n\t"
814    "movn           %[r6],       %[r0],         %[r2]         \n\t"
815    "movn           %[r3],       %[r1],         %[r5]         \n\t"
816    "slt            %[r2],       %[r6],         %[r3]         \n\t"
817    "movn           %[r6],       %[r3],         %[r2]         \n\t"
818    "slt            %[r2],       %[max],        %[r6]         \n\t"
819    "movn           %[max],      %[r6],         %[r2]         \n\t"
820    "bgtz           %[k],        1b                           \n\t"
821    " addiu         %[outre2],   %[outre2],     4             \n\t"
822#endif  // #if defined(MIPS_DSP_R1_LE)
823    "clz            %[max],      %[max]                       \n\t"
824    "addiu          %[max],      %[max],        -25           \n\t"
825    ".set           pop                                       \n\t"
826    : [inre] "=&r" (inre), [inim] "=&r" (inim),
827      [outre1] "=&r" (outre1), [outre2] "=&r" (outre2),
828      [offset] "+r" (offset), [k] "+r" (k), [r0] "=&r" (r0),
829      [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
830      [r4] "=&r" (r4), [r5] "=&r" (r5), [r6] "=&r" (r6),
831      [r7] "=&r" (r7), [r8] "=&r" (r8), [r9] "=&r" (r9),
832      [max] "=&r" (max)
833    : [inreQ7] "r" (inreQ7), [inimQ7] "r" (inimQ7),
834      [cosptr] "r" (cosptr), [sinptr] "r" (sinptr),
835      [outre1Q16] "r" (outre1Q16), [outre2Q16] "r" (outre2Q16)
836    : "hi", "lo", "memory"
837  );
838
839  // "Fastest" vectors
840  k = FRAMESAMPLES / 4;
841  __asm __volatile (
842    ".set           push                                      \n\t"
843    ".set           noreorder                                 \n\t"
844    "addiu          %[inre],      %[inreQ7],    0             \n\t"
845    "addiu          %[inim],      %[inimQ7],    0             \n\t"
846    "addiu          %[outre1],    %[outre1Q16], 0             \n\t"
847    "addiu          %[outre2],    %[outre2Q16], 0             \n\t"
848    "bltz           %[max],       2f                          \n\t"
849    " subu          %[max1],      $zero,        %[max]        \n\t"
850   "1:                                                        \n\t"
851    "lw             %[r0],        0(%[outre1])                \n\t"
852    "lw             %[r1],        0(%[outre2])                \n\t"
853    "lw             %[r2],        4(%[outre1])                \n\t"
854    "lw             %[r3],        4(%[outre2])                \n\t"
855    "sllv           %[r0],        %[r0],        %[max]        \n\t"
856    "sllv           %[r1],        %[r1],        %[max]        \n\t"
857    "sllv           %[r2],        %[r2],        %[max]        \n\t"
858    "sllv           %[r3],        %[r3],        %[max]        \n\t"
859    "addiu          %[k],         %[k],         -1            \n\t"
860    "addiu          %[outre1],    %[outre1],    8             \n\t"
861    "addiu          %[outre2],    %[outre2],    8             \n\t"
862    "sh             %[r0],        0(%[inre])                  \n\t"
863    "sh             %[r1],        0(%[inim])                  \n\t"
864    "sh             %[r2],        2(%[inre])                  \n\t"
865    "sh             %[r3],        2(%[inim])                  \n\t"
866    "addiu          %[inre],      %[inre],      4             \n\t"
867    "bgtz           %[k],         1b                          \n\t"
868    " addiu         %[inim],      %[inim],      4             \n\t"
869    "b              4f                                        \n\t"
870    " nop                                                     \n\t"
871   "2:                                                        \n\t"
872#if !defined(MIPS_DSP_R1_LE)
873    "addiu          %[r4],        $zero,        1             \n\t"
874    "addiu          %[r5],        %[max1],      -1            \n\t"
875    "sllv           %[r4],        %[r4],        %[r5]         \n\t"
876#endif  // #if !defined(MIPS_DSP_R1_LE)
877   "3:                                                        \n\t"
878    "lw             %[r0],        0(%[outre1])                \n\t"
879    "lw             %[r1],        0(%[outre2])                \n\t"
880    "lw             %[r2],        4(%[outre1])                \n\t"
881    "lw             %[r3],        4(%[outre2])                \n\t"
882#if defined(MIPS_DSP_R1_LE)
883    "shrav_r.w      %[r0],        %[r0],        %[max1]       \n\t"
884    "shrav_r.w      %[r1],        %[r1],        %[max1]       \n\t"
885    "shrav_r.w      %[r2],        %[r2],        %[max1]       \n\t"
886    "shrav_r.w      %[r3],        %[r3],        %[max1]       \n\t"
887#else  // #if defined(MIPS_DSP_R1_LE)
888    "addu           %[r0],        %[r0],        %[r4]         \n\t"
889    "addu           %[r1],        %[r1],        %[r4]         \n\t"
890    "addu           %[r2],        %[r2],        %[r4]         \n\t"
891    "addu           %[r3],        %[r3],        %[r4]         \n\t"
892    "srav           %[r0],        %[r0],        %[max1]       \n\t"
893    "srav           %[r1],        %[r1],        %[max1]       \n\t"
894    "srav           %[r2],        %[r2],        %[max1]       \n\t"
895    "srav           %[r3],        %[r3],        %[max1]       \n\t"
896#endif  // #if defined(MIPS_DSP_R1_LE)
897    "addiu          %[outre1],    %[outre1],    8             \n\t"
898    "addiu          %[outre2],    %[outre2],    8             \n\t"
899    "sh             %[r0],        0(%[inre])                  \n\t"
900    "sh             %[r1],        0(%[inim])                  \n\t"
901    "sh             %[r2],        2(%[inre])                  \n\t"
902    "sh             %[r3],        2(%[inim])                  \n\t"
903    "addiu          %[k],         %[k],         -1            \n\t"
904    "addiu          %[inre],      %[inre],      4             \n\t"
905    "bgtz           %[k],         3b                          \n\t"
906    " addiu         %[inim],      %[inim],      4             \n\t"
907   "4:                                                        \n\t"
908    ".set           pop                                       \n\t"
909    : [k] "+r" (k), [max1] "=&r" (max1), [r0] "=&r" (r0),
910      [inre] "=&r" (inre), [inim] "=&r" (inim),
911      [outre1] "=&r" (outre1), [outre2] "=&r" (outre2),
912#if !defined(MIPS_DSP_R1_LE)
913      [r4] "=&r" (r4), [r5] "=&r" (r5),
914#endif  // #if !defined(MIPS_DSP_R1_LE)
915      [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3)
916    : [max] "r" (max), [inreQ7] "r" (inreQ7),
917      [inimQ7] "r" (inimQ7), [outre1Q16] "r" (outre1Q16),
918      [outre2Q16] "r" (outre2Q16)
919    : "memory"
920  );
921
922  WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call
923
924  // All the remaining processing is done inside a single loop to avoid
925  // unnecessary memory accesses. MIPS DSPr2 version processes two samples
926  // at a time.
927  cosptr = (int16_t*)WebRtcIsacfix_kCosTab1;
928  sinptr = (int16_t*)WebRtcIsacfix_kSinTab1;
929  k = FRAMESAMPLES / 2;
930  __asm __volatile (
931    ".set           push                                      \n\t"
932    ".set           noreorder                                 \n\t"
933    "addiu          %[inre],      %[inreQ7],    0             \n\t"
934    "addiu          %[inim],      %[inimQ7],    0             \n\t"
935    "addiu          %[outre1],    %[outre1Q16], 0             \n\t"
936    "addiu          %[outre2],    %[outre2Q16], 0             \n\t"
937    "addiu          %[r4],        $zero,        273           \n\t"
938    "addiu          %[r5],        $zero,        31727         \n\t"
939#if defined(MIPS_DSP_R2_LE)
940    "addiu          %[max],       %[max],       16            \n\t"
941    "replv.ph       %[r4],        %[r4]                       \n\t"
942#endif  // #if defined(MIPS_DSP_R2_LE)
943    "bltz           %[max],       2f                          \n\t"
944    " subu          %[max1],      $zero,        %[max]        \n\t"
945#if defined(MIPS_DSP_R2_LE)
946    "addiu          %[max],       %[max],       1             \n\t"
947#endif  // #if defined(MIPS_DSP_R2_LE)
948   "1:                                                        \n\t"
949#if defined(MIPS_DSP_R2_LE)
950    "lwl            %[r0],        0(%[inre])                  \n\t"
951    "lwl            %[r1],        0(%[inim])                  \n\t"
952    "lh             %[r2],        0(%[cosptr])                \n\t"
953    "lwr            %[r0],        0(%[inre])                  \n\t"
954    "lwr            %[r1],        0(%[inim])                  \n\t"
955    "lh             %[r3],        0(%[sinptr])                \n\t"
956    "muleq_s.w.phr  %[r6],        %[r0],        %[r4]         \n\t"
957    "muleq_s.w.phr  %[r7],        %[r1],        %[r4]         \n\t"
958    "muleq_s.w.phl  %[r0],        %[r0],        %[r4]         \n\t"
959    "muleq_s.w.phl  %[r1],        %[r1],        %[r4]         \n\t"
960    "addiu          %[k],         %[k],         -2            \n\t"
961    "addiu          %[inre],      %[inre],      4             \n\t"
962    "addiu          %[inim],      %[inim],      4             \n\t"
963    "shrav_r.w      %[r6],        %[r6],        %[max]        \n\t"
964    "shrav_r.w      %[r7],        %[r7],        %[max]        \n\t"
965    "mult           $ac0,         %[r2],        %[r6]         \n\t"
966    "mult           $ac1,         %[r3],        %[r7]         \n\t"
967    "mult           $ac2,         %[r2],        %[r7]         \n\t"
968    "mult           $ac3,         %[r3],        %[r6]         \n\t"
969    "lh             %[r2],        2(%[cosptr])                \n\t"
970    "lh             %[r3],        2(%[sinptr])                \n\t"
971    "extr_r.w       %[r6],        $ac0,         14            \n\t"
972    "extr_r.w       %[r7],        $ac1,         14            \n\t"
973    "extr_r.w       %[r8],        $ac2,         14            \n\t"
974    "extr_r.w       %[r9],        $ac3,         14            \n\t"
975    "shrav_r.w      %[r0],        %[r0],        %[max]        \n\t"
976    "shrav_r.w      %[r1],        %[r1],        %[max]        \n\t"
977    "mult           $ac0,         %[r2],        %[r0]         \n\t"
978    "mult           $ac1,         %[r3],        %[r1]         \n\t"
979    "mult           $ac2,         %[r2],        %[r1]         \n\t"
980    "mult           $ac3,         %[r3],        %[r0]         \n\t"
981    "addiu          %[cosptr],    %[cosptr],    4             \n\t"
982    "extr_r.w       %[r0],        $ac0,         14            \n\t"
983    "extr_r.w       %[r1],        $ac1,         14            \n\t"
984    "extr_r.w       %[r2],        $ac2,         14            \n\t"
985    "extr_r.w       %[r3],        $ac3,         14            \n\t"
986    "subu           %[r6],        %[r6],        %[r7]         \n\t"
987    "addu           %[r8],        %[r8],        %[r9]         \n\t"
988    "mult           $ac0,         %[r5],        %[r6]         \n\t"
989    "mult           $ac1,         %[r5],        %[r8]         \n\t"
990    "addiu          %[sinptr],    %[sinptr],    4             \n\t"
991    "subu           %[r0],        %[r0],        %[r1]         \n\t"
992    "addu           %[r2],        %[r2],        %[r3]         \n\t"
993    "extr_r.w       %[r1],        $ac0,         11            \n\t"
994    "extr_r.w       %[r3],        $ac1,         11            \n\t"
995    "mult           $ac2,         %[r5],        %[r0]         \n\t"
996    "mult           $ac3,         %[r5],        %[r2]         \n\t"
997    "sw             %[r1],        0(%[outre1])                \n\t"
998    "sw             %[r3],        0(%[outre2])                \n\t"
999    "addiu          %[outre1],    %[outre1],    8             \n\t"
1000    "extr_r.w       %[r0],        $ac2,         11            \n\t"
1001    "extr_r.w       %[r2],        $ac3,         11            \n\t"
1002    "sw             %[r0],        -4(%[outre1])               \n\t"
1003    "sw             %[r2],        4(%[outre2])                \n\t"
1004    "bgtz           %[k],         1b                          \n\t"
1005    " addiu         %[outre2],    %[outre2],    8             \n\t"
1006    "b              3f                                        \n\t"
1007#else  // #if defined(MIPS_DSP_R2_LE)
1008    "lh             %[r0],        0(%[inre])                  \n\t"
1009    "lh             %[r1],        0(%[inim])                  \n\t"
1010    "addiu          %[k],         %[k],         -1            \n\t"
1011    "srav           %[r0],        %[r0],        %[max]        \n\t"
1012    "srav           %[r1],        %[r1],        %[max]        \n\t"
1013    "sra            %[r2],        %[r0],        16            \n\t"
1014    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1015    "sra            %[r0],        %[r0],        1             \n\t"
1016    "sra            %[r3],        %[r1],        16            \n\t"
1017    "andi           %[r1],        %[r1],        0xFFFF        \n\t"
1018    "sra            %[r1],        %[r1],        1             \n\t"
1019    "mul            %[r2],        %[r2],        %[r4]         \n\t"
1020    "mul            %[r0],        %[r0],        %[r4]         \n\t"
1021    "mul            %[r3],        %[r3],        %[r4]         \n\t"
1022    "mul            %[r1],        %[r1],        %[r4]         \n\t"
1023    "addiu          %[inre],      %[inre],      2             \n\t"
1024    "addiu          %[inim],      %[inim],      2             \n\t"
1025    "lh             %[r6],        0(%[cosptr])                \n\t"
1026    "lh             %[r7],        0(%[sinptr])                \n\t"
1027#if defined(MIPS_DSP_R1_LE)
1028    "shra_r.w       %[r0],        %[r0],        15            \n\t"
1029    "shra_r.w       %[r1],        %[r1],        15            \n\t"
1030#else  // #if defined(MIPS_DSP_R1_LE)
1031    "addiu          %[r0],        %[r0],        0x4000        \n\t"
1032    "addiu          %[r1],        %[r1],        0x4000        \n\t"
1033    "sra            %[r0],        %[r0],        15            \n\t"
1034    "sra            %[r1],        %[r1],        15            \n\t"
1035#endif  // #if defined(MIPS_DSP_R1_LE)
1036    "addu           %[r0],        %[r2],        %[r0]         \n\t"
1037    "addu           %[r1],        %[r3],        %[r1]         \n\t"
1038    "sra            %[r2],        %[r0],        16            \n\t"
1039    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1040    "mul            %[r9],        %[r2],        %[r6]         \n\t"
1041    "mul            %[r2],        %[r2],        %[r7]         \n\t"
1042    "mul            %[r8],        %[r0],        %[r6]         \n\t"
1043    "mul            %[r0],        %[r0],        %[r7]         \n\t"
1044    "sra            %[r3],        %[r3],        16            \n\t"
1045    "andi           %[r1],        %[r1],        0xFFFF        \n\t"
1046    "sll            %[r9],        %[r9],        2             \n\t"
1047    "sll            %[r2],        %[r2],        2             \n\t"
1048#if defined(MIPS_DSP_R1_LE)
1049    "shra_r.w       %[r8],        %[r8],        14            \n\t"
1050    "shra_r.w       %[r0],        %[r0],        14            \n\t"
1051#else  // #if defined(MIPS_DSP_R1_LE)
1052    "addiu          %[r8],        %[r8],        0x2000        \n\t"
1053    "addiu          %[r0],        %[r0],        0x2000        \n\t"
1054    "sra            %[r8],        %[r8],        14            \n\t"
1055    "sra            %[r0],        %[r0],        14            \n\t"
1056#endif  // #if defined(MIPS_DSP_R1_LE)
1057    "addu           %[r9],        %[r9],        %[r8]         \n\t"
1058    "addu           %[r2],        %[r2],        %[r0]         \n\t"
1059    "mul            %[r0],        %[r3],        %[r6]         \n\t"
1060    "mul            %[r3],        %[r3],        %[r7]         \n\t"
1061    "mul            %[r8],        %[r1],        %[r6]         \n\t"
1062    "mul            %[r1],        %[r1],        %[r8]         \n\t"
1063    "addiu          %[cosptr],    %[cosptr],    2             \n\t"
1064    "addiu          %[sinptr],    %[sinptr],    2             \n\t"
1065    "sll            %[r0],        %[r0],        2             \n\t"
1066    "sll            %[r3],        %[r3],        2             \n\t"
1067#if defined(MIPS_DSP_R1_LE)
1068    "shra_r.w       %[r8],        %[r8],        14            \n\t"
1069    "shra_r.w       %[r1],        %[r1],        14            \n\t"
1070#else  // #if defined(MIPS_DSP_R1_LE)
1071    "addiu          %[r8],        %[r8],        0x2000        \n\t"
1072    "addiu          %[r1],        %[r1],        0x2000        \n\t"
1073    "sra            %[r8],        %[r8],        14            \n\t"
1074    "sra            %[r1],        %[r1],        14            \n\t"
1075#endif  // #if defined(MIPS_DSP_R1_LE)
1076    "addu           %[r0],        %[r0],        %[r8]         \n\t"
1077    "addu           %[r3],        %[r3],        %[r1]         \n\t"
1078    "subu           %[r9],        %[r9],        %[r3]         \n\t"
1079    "addu           %[r0],        %[r0],        %[r2]         \n\t"
1080    "sra            %[r1],        %[r9],        16            \n\t"
1081    "andi           %[r9],        %[r9],        0xFFFF        \n\t"
1082    "mul            %[r1],        %[r1],        %[r5]         \n\t"
1083    "mul            %[r9],        %[r9],        %[r5]         \n\t"
1084    "sra            %[r2],        %[r0],        16            \n\t"
1085    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1086    "mul            %[r2],        %[r2],        %[r5]         \n\t"
1087    "mul            %[r0],        %[r0],        %[r5]         \n\t"
1088    "sll            %[r1],        %[r1],        5             \n\t"
1089#if defined(MIPS_DSP_R1_LE)
1090    "shra_r.w       %[r9],        %[r9],        11            \n\t"
1091#else  // #if defined(MIPS_DSP_R1_LE)
1092    "addiu          %[r9],        %[r9],        0x400         \n\t"
1093    "sra            %[r9],        %[r9],        11            \n\t"
1094#endif  // #if defined(MIPS_DSP_R1_LE)
1095    "addu           %[r1],        %[r1],        %[r9]         \n\t"
1096    "sll            %[r2],        %[r2],        5             \n\t"
1097#if defined(MIPS_DSP_R1_LE)
1098    "shra_r.w       %[r0],        %[r0],        11            \n\t"
1099#else  // #if defined(MIPS_DSP_R1_LE)
1100    "addiu          %[r0],        %[r0],        0x400         \n\t"
1101    "sra            %[r0],        %[r0],        11            \n\t"
1102#endif  // #if defined(MIPS_DSP_R1_LE)
1103    "addu           %[r0],        %[r0],        %[r2]         \n\t"
1104    "sw             %[r1],        0(%[outre1])                \n\t"
1105    "addiu          %[outre1],    %[outre1],    4             \n\t"
1106    "sw             %[r0],        0(%[outre2])                \n\t"
1107    "bgtz           %[k],         1b                          \n\t"
1108    " addiu         %[outre2],    %[outre2],    4             \n\t"
1109    "b              3f                                        \n\t"
1110    " nop                                                     \n\t"
1111#endif  // #if defined(MIPS_DSP_R2_LE)
1112   "2:                                                        \n\t"
1113#if defined(MIPS_DSP_R2_LE)
1114    "addiu          %[max1],      %[max1],      -1            \n\t"
1115   "21:                                                       \n\t"
1116    "lwl            %[r0],        0(%[inre])                  \n\t"
1117    "lwl            %[r1],        0(%[inim])                  \n\t"
1118    "lh             %[r2],        0(%[cosptr])                \n\t"
1119    "lwr            %[r0],        0(%[inre])                  \n\t"
1120    "lwr            %[r1],        0(%[inim])                  \n\t"
1121    "lh             %[r3],        0(%[sinptr])                \n\t"
1122    "muleq_s.w.phr  %[r6],        %[r0],        %[r4]         \n\t"
1123    "muleq_s.w.phr  %[r7],        %[r1],        %[r4]         \n\t"
1124    "muleq_s.w.phl  %[r0],        %[r0],        %[r4]         \n\t"
1125    "muleq_s.w.phl  %[r1],        %[r1],        %[r4]         \n\t"
1126    "addiu          %[k],         %[k],         -2            \n\t"
1127    "addiu          %[inre],      %[inre],      4             \n\t"
1128    "addiu          %[inim],      %[inim],      4             \n\t"
1129    "sllv           %[r6],        %[r6],        %[max1]       \n\t"
1130    "sllv           %[r7],        %[r7],        %[max1]       \n\t"
1131    "mult           $ac0,         %[r2],        %[r6]         \n\t"
1132    "mult           $ac1,         %[r3],        %[r7]         \n\t"
1133    "mult           $ac2,         %[r2],        %[r7]         \n\t"
1134    "mult           $ac3,         %[r3],        %[r6]         \n\t"
1135    "lh             %[r2],        2(%[cosptr])                \n\t"
1136    "lh             %[r3],        2(%[sinptr])                \n\t"
1137    "extr_r.w       %[r6],        $ac0,         14            \n\t"
1138    "extr_r.w       %[r7],        $ac1,         14            \n\t"
1139    "extr_r.w       %[r8],        $ac2,         14            \n\t"
1140    "extr_r.w       %[r9],        $ac3,         14            \n\t"
1141    "sllv           %[r0],        %[r0],        %[max1]       \n\t"
1142    "sllv           %[r1],        %[r1],        %[max1]       \n\t"
1143    "mult           $ac0,         %[r2],        %[r0]         \n\t"
1144    "mult           $ac1,         %[r3],        %[r1]         \n\t"
1145    "mult           $ac2,         %[r2],        %[r1]         \n\t"
1146    "mult           $ac3,         %[r3],        %[r0]         \n\t"
1147    "addiu          %[cosptr],    %[cosptr],    4             \n\t"
1148    "extr_r.w       %[r0],        $ac0,         14            \n\t"
1149    "extr_r.w       %[r1],        $ac1,         14            \n\t"
1150    "extr_r.w       %[r2],        $ac2,         14            \n\t"
1151    "extr_r.w       %[r3],        $ac3,         14            \n\t"
1152    "subu           %[r6],        %[r6],        %[r7]         \n\t"
1153    "addu           %[r8],        %[r8],        %[r9]         \n\t"
1154    "mult           $ac0,         %[r5],        %[r6]         \n\t"
1155    "mult           $ac1,         %[r5],        %[r8]         \n\t"
1156    "addiu          %[sinptr],    %[sinptr],    4             \n\t"
1157    "subu           %[r0],        %[r0],        %[r1]         \n\t"
1158    "addu           %[r2],        %[r2],        %[r3]         \n\t"
1159    "extr_r.w       %[r1],        $ac0,         11            \n\t"
1160    "extr_r.w       %[r3],        $ac1,         11            \n\t"
1161    "mult           $ac2,         %[r5],        %[r0]         \n\t"
1162    "mult           $ac3,         %[r5],        %[r2]         \n\t"
1163    "sw             %[r1],        0(%[outre1])                \n\t"
1164    "sw             %[r3],        0(%[outre2])                \n\t"
1165    "addiu          %[outre1],    %[outre1],    8             \n\t"
1166    "extr_r.w       %[r0],        $ac2,         11            \n\t"
1167    "extr_r.w       %[r2],        $ac3,         11            \n\t"
1168    "sw             %[r0],        -4(%[outre1])               \n\t"
1169    "sw             %[r2],        4(%[outre2])                \n\t"
1170    "bgtz           %[k],         21b                         \n\t"
1171    " addiu         %[outre2],    %[outre2],    8             \n\t"
1172    "b              3f                                        \n\t"
1173    " nop                                                     \n\t"
1174#else  // #if defined(MIPS_DSP_R2_LE)
1175    "lh             %[r0],        0(%[inre])                  \n\t"
1176    "lh             %[r1],        0(%[inim])                  \n\t"
1177    "addiu          %[k],         %[k],         -1            \n\t"
1178    "sllv           %[r0],        %[r0],        %[max1]       \n\t"
1179    "sllv           %[r1],        %[r1],        %[max1]       \n\t"
1180    "sra            %[r2],        %[r0],        16            \n\t"
1181    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1182    "sra            %[r0],        %[r0],        1             \n\t"
1183    "sra            %[r3],        %[r1],        16            \n\t"
1184    "andi           %[r1],        %[r1],        0xFFFF        \n\t"
1185    "sra            %[r1],        %[r1],        1             \n\t"
1186    "mul            %[r2],        %[r2],        %[r4]         \n\t"
1187    "mul            %[r0],        %[r0],        %[r4]         \n\t"
1188    "mul            %[r3],        %[r3],        %[r4]         \n\t"
1189    "mul            %[r1],        %[r1],        %[r4]         \n\t"
1190    "addiu          %[inre],      %[inre],      2             \n\t"
1191    "addiu          %[inim],      %[inim],      2             \n\t"
1192    "lh             %[r6],        0(%[cosptr])                \n\t"
1193    "lh             %[r7],        0(%[sinptr])                \n\t"
1194#if defined(MIPS_DSP_R1_LE)
1195    "shra_r.w       %[r0],        %[r0],        15            \n\t"
1196    "shra_r.w       %[r1],        %[r1],        15            \n\t"
1197#else  // #if defined(MIPS_DSP_R1_LE)
1198    "addiu          %[r0],        %[r0],        0x4000        \n\t"
1199    "addiu          %[r1],        %[r1],        0x4000        \n\t"
1200    "sra            %[r0],        %[r0],        15            \n\t"
1201    "sra            %[r1],        %[r1],        15            \n\t"
1202#endif  // #if defined(MIPS_DSP_R1_LE)
1203    "addu           %[r0],        %[r2],        %[r0]         \n\t"
1204    "addu           %[r1],        %[r3],        %[r1]         \n\t"
1205    "sra            %[r2],        %[r0],        16            \n\t"
1206    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1207    "mul            %[r9],        %[r2],        %[r6]         \n\t"
1208    "mul            %[r2],        %[r2],        %[r7]         \n\t"
1209    "mul            %[r8],        %[r0],        %[r6]         \n\t"
1210    "mul            %[r0],        %[r0],        %[r7]         \n\t"
1211    "sra            %[r3],        %[r1],        16            \n\t"
1212    "andi           %[r1],        %[r1],        0xFFFF        \n\t"
1213    "sll            %[r9],        %[r9],        2             \n\t"
1214    "sll            %[r2],        %[r2],        2             \n\t"
1215#if defined(MIPS_DSP_R1_LE)
1216    "shra_r.w       %[r8],        %[r8],        14            \n\t"
1217    "shra_r.w       %[r0],        %[r0],        14            \n\t"
1218#else  // #if defined(MIPS_DSP_R1_LE)
1219    "addiu          %[r8],        %[r8],        0x2000        \n\t"
1220    "addiu          %[r0],        %[r0],        0x2000        \n\t"
1221    "sra            %[r8],        %[r8],        14            \n\t"
1222    "sra            %[r0],        %[r0],        14            \n\t"
1223#endif  // #if defined(MIPS_DSP_R1_LE)
1224    "addu           %[r9],        %[r9],        %[r8]         \n\t"
1225    "addu           %[r2],        %[r2],        %[r0]         \n\t"
1226    "mul            %[r0],        %[r3],        %[r6]         \n\t"
1227    "mul            %[r3],        %[r3],        %[r7]         \n\t"
1228    "mul            %[r8],        %[r1],        %[r6]         \n\t"
1229    "mul            %[r1],        %[r1],        %[r7]         \n\t"
1230    "addiu          %[cosptr],    %[cosptr],    2             \n\t"
1231    "addiu          %[sinptr],    %[sinptr],    2             \n\t"
1232    "sll            %[r0],        %[r0],        2             \n\t"
1233    "sll            %[r3],        %[r3],        2             \n\t"
1234#if defined(MIPS_DSP_R1_LE)
1235    "shra_r.w       %[r8],        %[r8],        14            \n\t"
1236    "shra_r.w       %[r1],        %[r1],        14            \n\t"
1237#else  // #if defined(MIPS_DSP_R1_LE)
1238    "addiu          %[r8],        %[r8],        0x2000        \n\t"
1239    "addiu          %[r1],        %[r1],        0x2000        \n\t"
1240    "sra            %[r8],        %[r8],        14            \n\t"
1241    "sra            %[r1],        %[r1],        14            \n\t"
1242#endif  // #if defined(MIPS_DSP_R1_LE)
1243    "addu           %[r0],        %[r0],        %[r8]         \n\t"
1244    "addu           %[r3],        %[r3],        %[r1]         \n\t"
1245    "subu           %[r9],        %[r9],        %[r3]         \n\t"
1246    "addu           %[r0],        %[r0],        %[r2]         \n\t"
1247    "sra            %[r1],        %[r9],        16            \n\t"
1248    "andi           %[r9],        %[r9],        0xFFFF        \n\t"
1249    "mul            %[r1],        %[r1],        %[r5]         \n\t"
1250    "mul            %[r9],        %[r9],        %[r5]         \n\t"
1251    "sra            %[r2],        %[r0],        16            \n\t"
1252    "andi           %[r0],        %[r0],        0xFFFF        \n\t"
1253    "mul            %[r2],        %[r2],        %[r5]         \n\t"
1254    "mul            %[r0],        %[r0],        %[r5]         \n\t"
1255    "sll            %[r1],        %[r1],        5             \n\t"
1256#if defined(MIPS_DSP_R1_LE)
1257    "shra_r.w       %[r9],        %[r9],        11            \n\t"
1258#else  // #if defined(MIPS_DSP_R1_LE)
1259    "addiu          %[r9],        %[r9],        0x400         \n\t"
1260    "sra            %[r9],        %[r9],        11            \n\t"
1261#endif  // #if defined(MIPS_DSP_R1_LE)
1262    "addu           %[r1],        %[r1],        %[r9]         \n\t"
1263    "sll            %[r2],        %[r2],        5             \n\t"
1264#if defined(MIPS_DSP_R1_LE)
1265    "shra_r.w       %[r0],        %[r0],        11            \n\t"
1266#else  // #if defined(MIPS_DSP_R1_LE)
1267    "addiu          %[r0],        %[r0],        0x400         \n\t"
1268    "sra            %[r0],        %[r0],        11            \n\t"
1269#endif  // #if defined(MIPS_DSP_R1_LE)
1270    "addu           %[r0],        %[r0],        %[r2]         \n\t"
1271    "sw             %[r1],        0(%[outre1])                \n\t"
1272    "addiu          %[outre1],    %[outre1],    4             \n\t"
1273    "sw             %[r0],        0(%[outre2])                \n\t"
1274    "bgtz           %[k],         2b                          \n\t"
1275    " addiu         %[outre2],    %[outre2],    4             \n\t"
1276#endif  // #if defined(MIPS_DSP_R2_LE)
1277   "3:                                                        \n\t"
1278    ".set           pop                                       \n\t"
1279    : [k] "+r" (k), [r0] "=&r" (r0), [r1] "=&r" (r1),
1280      [r2] "=&r" (r2), [r3] "=&r" (r3), [r4] "=&r" (r4),
1281      [r5] "=&r" (r5), [r6] "=&r" (r6), [r7] "=&r" (r7),
1282      [r8] "=&r" (r8), [r9] "=&r" (r9), [max1] "=&r" (max1),
1283      [inre] "=&r" (inre), [inim] "=&r" (inim),
1284      [outre1] "=&r" (outre1), [outre2] "=&r" (outre2)
1285    : [max] "r" (max), [inreQ7] "r" (inreQ7),
1286      [inimQ7] "r" (inimQ7), [cosptr] "r" (cosptr),
1287      [sinptr] "r" (sinptr), [outre1Q16] "r" (outre1Q16),
1288      [outre2Q16] "r" (outre2Q16)
1289    : "hi", "lo", "memory"
1290#if defined(MIPS_DSP_R2_LE)
1291    , "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi", "$ac3lo"
1292#endif  // #if defined(MIPS_DSP_R2_LE)
1293  );
1294}
1295