• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
16 extern const int16_t WebRtcIsacfix_kCosTab1[FRAMESAMPLES/2];
17 extern const int16_t WebRtcIsacfix_kSinTab1[FRAMESAMPLES/2];
18 extern const int16_t WebRtcIsacfix_kCosTab2[FRAMESAMPLES/4];
19 extern 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.
WebRtcIsacfix_Time2SpecMIPS(int16_t * inre1Q9,int16_t * inre2Q9,int16_t * outreQ7,int16_t * outimQ7)24 void 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 
WebRtcIsacfix_Spec2TimeMIPS(int16_t * inreQ7,int16_t * inimQ7,int32_t * outre1Q16,int32_t * outre2Q16)598 void 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