Home | History | Annotate | Download | only in source
      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.
     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 
    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