1919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org/*
2919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *
4919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org */
10919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
112f20fbec1d465d513a5a73e575f759cdde7a5407Peter Kasting#include <stddef.h>
122f20fbec1d465d513a5a73e575f759cdde7a5407Peter Kasting
13919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h"
14919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#include "webrtc/typedefs.h"
15919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
16919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
17919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// cth_Q15[] and sth_Q15[].
18919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.orgvoid WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,     // Input samples
19919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                int16_t* ar_f_Q0,     // Input samples
20919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                int16_t* cth_Q15,     // Filter coefficients
21919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                int16_t* sth_Q15,     // Filter coefficients
22b7306ae6fe7e50ff69fb6ae5f8d2f92b616e3ca8Niklas Enbom                                size_t order_coef) { // order of the filter
23919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int n = 0;
24919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
25919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  for (n = 0; n < HALF_SUBFRAMELEN - 1; n++) {
26b7306ae6fe7e50ff69fb6ae5f8d2f92b616e3ca8Niklas Enbom    int count = (int)(order_coef - 1);
27919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int offset;
28919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if !defined(MIPS_DSP_R1_LE)
29919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int16_t* tmp_cth;
30919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int16_t* tmp_sth;
31919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int16_t* tmp_arg;
32919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int32_t max_q16 = 0x7fff;
33919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int32_t min_q16 = 0xffff8000;
34919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
35919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    // Declare variables used as temporary registers.
36919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    int32_t r0, r1, r2, t0, t1, t2, t_ar;
37919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
38919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    __asm __volatile (
39919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      ".set          push                                                \n\t"
40919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      ".set          noreorder                                           \n\t"
41919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "bltz          %[count],     2f                                    \n\t"
42919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      " lh           %[t_ar],      0(%[tmp])                             \n\t"
43919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      // Inner loop
44919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org     "1:                                                                 \n\t"
45919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sll           %[offset],    %[count],               1             \n\t"
46919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
47919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lhx           %[r0],        %[offset](%[cth_Q15])                 \n\t"
48919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lhx           %[r1],        %[offset](%[sth_Q15])                 \n\t"
49919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lhx           %[r2],        %[offset](%[ar_g_Q0])                 \n\t"
50919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
51919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[tmp_cth],   %[cth_Q15],             %[offset]     \n\t"
52919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[tmp_sth],   %[sth_Q15],             %[offset]     \n\t"
53919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[tmp_arg],   %[ar_g_Q0],             %[offset]     \n\t"
54919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lh            %[r0],        0(%[tmp_cth])                         \n\t"
55919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lh            %[r1],        0(%[tmp_sth])                         \n\t"
56919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "lh            %[r2],        0(%[tmp_arg])                         \n\t"
57919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
58919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "mul           %[t0],        %[r0],                  %[t_ar]       \n\t"
59919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "mul           %[t1],        %[r1],                  %[t_ar]       \n\t"
60919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "mul           %[t2],        %[r1],                  %[r2]         \n\t"
61919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "mul           %[r0],        %[r0],                  %[r2]         \n\t"
62919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "subu          %[t0],        %[t0],                  %[t2]         \n\t"
63919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[t1],        %[t1],                  %[r0]         \n\t"
64919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
65919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "shra_r.w      %[t1],        %[t1],                  15            \n\t"
66919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "shra_r.w      %[t0],        %[t0],                  15            \n\t"
67919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
68919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addiu         %[t1],        %[t1],                  0x4000        \n\t"
69919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sra           %[t1],        %[t1],                  15            \n\t"
70919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addiu         %[t0],        %[t0],                  0x4000        \n\t"
71919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sra           %[t0],        %[t0],                  15            \n\t"
72919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
73919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addiu         %[offset],    %[offset],              2             \n\t"
74919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
75919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "shll_s.w      %[t1],        %[t1],                  16            \n\t"
76919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "shll_s.w      %[t_ar],      %[t0],                  16            \n\t"
77919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
78919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "slt           %[r0],        %[t1],                  %[max_q16]    \n\t"
79919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "slt           %[r1],        %[t0],                  %[max_q16]    \n\t"
80919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "movz          %[t1],        %[max_q16],             %[r0]         \n\t"
81919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "movz          %[t0],        %[max_q16],             %[r1]         \n\t"
82919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
83919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[offset],    %[offset],              %[ar_g_Q0]    \n\t"
84919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
85919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sra           %[t1],        %[t1],                  16            \n\t"
86919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sra           %[t_ar],      %[t_ar],                16            \n\t"
87919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
88919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "slt           %[r0],        %[t1],                  %[min_q16]    \n\t"
89919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "slt           %[r1],        %[t0],                  %[min_q16]    \n\t"
90919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "movn          %[t1],        %[min_q16],             %[r0]         \n\t"
91919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "movn          %[t0],        %[min_q16],             %[r1]         \n\t"
92919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "addu          %[t_ar],      $zero,                  %[t0]         \n\t"
93919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
94919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sh            %[t1],        0(%[offset])                          \n\t"
95919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "bgtz          %[count],     1b                                    \n\t"
96919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      " addiu        %[count],     %[count],               -1            \n\t"
97919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org     "2:                                                                 \n\t"
98919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sh            %[t_ar],      0(%[tmp])                             \n\t"
99919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "sh            %[t_ar],      0(%[ar_g_Q0])                         \n\t"
100919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      ".set          pop                                                 \n\t"
101919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      : [t_ar] "=&r" (t_ar), [count] "+r" (count), [offset] "=&r" (offset),
102919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2), [t0] "=&r" (t0),
103919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if !defined(MIPS_DSP_R1_LE)
104919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [tmp_cth] "=&r" (tmp_cth), [tmp_sth] "=&r" (tmp_sth),
105919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [tmp_arg] "=&r" (tmp_arg),
106919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
107919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [t1] "=&r" (t1), [t2] "=&r" (t2)
108919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      : [tmp] "r" (&ar_f_Q0[n+1]), [cth_Q15] "r" (cth_Q15),
109919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if !defined(MIPS_DSP_R1_LE)
110919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [max_q16] "r" (max_q16), [min_q16] "r" (min_q16),
111919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
112919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org        [sth_Q15] "r" (sth_Q15), [ar_g_Q0] "r" (ar_g_Q0)
113919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      : "memory", "hi", "lo"
114919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    );
115919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  }
116919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org}
117919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
118919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// MIPS optimization of the inner loop used for function
119919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// WebRtcIsacfix_NormLatticeFilterMa(). It does:
120919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org//
121919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// for 0 <= n < HALF_SUBFRAMELEN - 1:
122919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org//   *ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
123919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org//   *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
124919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org//
125919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// Note, function WebRtcIsacfix_FilterMaLoopMIPS and WebRtcIsacfix_FilterMaLoopC
126919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org// are not bit-exact. The accuracy of the MIPS function is same or better.
127919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.orgvoid WebRtcIsacfix_FilterMaLoopMIPS(int16_t input0,  // Filter coefficient
128919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                    int16_t input1,  // Filter coefficient
129919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                    int32_t input2,  // Inverse coeff (1/input1)
130919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                    int32_t* ptr0,   // Sample buffer
131919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                    int32_t* ptr1,   // Sample buffer
132919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org                                    int32_t* ptr2) { // Sample buffer
133919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R2_LE)
134919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // MIPS DSPR2 version. 4 available accumulators allows loop unrolling 4 times.
135919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // This variant is not bit-exact with WebRtcIsacfix_FilterMaLoopC, since we
136919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // are exploiting 64-bit accumulators. The accuracy of the MIPS DSPR2 function
137919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // is same or better.
138919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int n = (HALF_SUBFRAMELEN - 1) >> 2;
139919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int m = (HALF_SUBFRAMELEN - 1) & 3;
140919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
141919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int r0, r1, r2, r3;
142919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int t0, t1, t2, t3;
143919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int s0, s1, s2, s3;
144919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
145919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  __asm __volatile (
146919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          push                                      \n\t"
147919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          noreorder                                 \n\t"
148919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org   "1:                                                       \n\t"
149919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r0],        0(%[ptr0])                  \n\t"
150919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r1],        4(%[ptr0])                  \n\t"
151919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r2],        8(%[ptr0])                  \n\t"
152919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r3],        12(%[ptr0])                 \n\t"
153919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[r0],        %[input0]     \n\t"
154919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac1,         %[r1],        %[input0]     \n\t"
155919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac2,         %[r2],        %[input0]     \n\t"
156919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac3,         %[r3],        %[input0]     \n\t"
157919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[t0],        0(%[ptr2])                  \n\t"
158919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s0],        $ac0,         15            \n\t"
159919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s1],        $ac1,         15            \n\t"
160919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s2],        $ac2,         15            \n\t"
161919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s3],        $ac3,         15            \n\t"
162919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[t1],        4(%[ptr2])                  \n\t"
163919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[t2],        8(%[ptr2])                  \n\t"
164919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[t3],        12(%[ptr2])                 \n\t"
165919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t0],        %[t0],        %[s0]         \n\t"
166919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t1],        %[t1],        %[s1]         \n\t"
167919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t2],        %[t2],        %[s2]         \n\t"
168919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t3],        %[t3],        %[s3]         \n\t"
169919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[t0],        %[input2]     \n\t"
170919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac1,         %[t1],        %[input2]     \n\t"
171919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac2,         %[t2],        %[input2]     \n\t"
172919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac3,         %[t3],        %[input2]     \n\t"
173919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr0],      %[ptr0],      16            \n\t"
174919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t0],        $ac0,         16            \n\t"
175919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t1],        $ac1,         16            \n\t"
176919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t2],        $ac2,         16            \n\t"
177919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t3],        $ac3,         16            \n\t"
178919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[n],         %[n],         -1            \n\t"
179919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[r0],        %[input1]     \n\t"
180919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac1,         %[r1],        %[input1]     \n\t"
181919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac2,         %[r2],        %[input1]     \n\t"
182919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac3,         %[r3],        %[input1]     \n\t"
183919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t0],        0(%[ptr2])                  \n\t"
184919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s0],        $ac0,         15            \n\t"
185919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s1],        $ac1,         15            \n\t"
186919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s2],        $ac2,         15            \n\t"
187919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[s3],        $ac3,         15            \n\t"
188919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t1],        4(%[ptr2])                  \n\t"
189919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t2],        8(%[ptr2])                  \n\t"
190919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t3],        12(%[ptr2])                 \n\t"
191919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[t0],        %[input0]     \n\t"
192919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac1,         %[t1],        %[input0]     \n\t"
193919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac2,         %[t2],        %[input0]     \n\t"
194919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac3,         %[t3],        %[input0]     \n\t"
195919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr2],      %[ptr2],      16            \n\t"
196919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t0],        $ac0,         15            \n\t"
197919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t1],        $ac1,         15            \n\t"
198919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t2],        $ac2,         15            \n\t"
199919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t3],        $ac3,         15            \n\t"
200919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t0],        %[t0],        %[s0]         \n\t"
201919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t1],        %[t1],        %[s1]         \n\t"
202919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t2],        %[t2],        %[s2]         \n\t"
203919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t3],        %[t3],        %[s3]         \n\t"
204919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t0],        0(%[ptr1])                  \n\t"
205919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t1],        4(%[ptr1])                  \n\t"
206919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t2],        8(%[ptr1])                  \n\t"
207919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t3],        12(%[ptr1])                 \n\t"
208919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "bgtz          %[n],         1b                          \n\t"
209919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    " addiu        %[ptr1],      %[ptr1],      16            \n\t"
210919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "beq           %[m],         %0,           3f            \n\t"
211919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    " nop                                                    \n\t"
212919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org   "2:                                                       \n\t"
213919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r0],        0(%[ptr0])                  \n\t"
214919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[t0],        0(%[ptr2])                  \n\t"
215919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr0],      %[ptr0],      4             \n\t"
216919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[r0],        %[input0]     \n\t"
217919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac1,         %[r0],        %[input1]     \n\t"
218919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[r1],        $ac0,         15            \n\t"
219919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t1],        $ac1,         15            \n\t"
220919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t0],        %[t0],        %[r1]         \n\t"
221919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[t0],        %[input2]     \n\t"
222919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t0],        $ac0,         16            \n\t"
223919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t0],        0(%[ptr2])                  \n\t"
224919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mult          $ac0,         %[t0],        %[input0]     \n\t"
225919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr2],      %[ptr2],      4             \n\t"
226919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[m],         %[m],         -1            \n\t"
227919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "extr_rs.w     %[t0],        $ac0,         15            \n\t"
228919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[t0],        %[t0],        %[t1]         \n\t"
229919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[t0],        0(%[ptr1])                  \n\t"
230919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "bgtz          %[m],         2b                          \n\t"
231919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    " addiu        %[ptr1],      %[ptr1],      4             \n\t"
232919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org   "3:                                                       \n\t"
233919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          pop                                       \n\t"
234919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2),
235919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [r3] "=&r" (r3), [t0] "=&r" (t0), [t1] "=&r" (t1),
236919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [t2] "=&r" (t2), [t3] "=&r" (t3), [s0] "=&r" (s0),
237919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [s1] "=&r" (s1), [s2] "=&r" (s2), [s3] "=&r" (s3),
238919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [ptr0] "+r" (ptr0), [ptr1] "+r" (ptr1), [m] "+r" (m),
239919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [ptr2] "+r" (ptr2), [n] "+r" (n)
240919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : [input0] "r" (input0), [input1] "r" (input1),
241919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [input2] "r" (input2)
242919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : "memory", "hi", "lo", "$ac1hi", "$ac1lo", "$ac2hi",
243919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      "$ac2lo", "$ac3hi", "$ac3lo"
244919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  );
245919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
246919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // Non-DSPR2 version of the function. Avoiding the accumulator usage due to
247919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  // large latencies. This variant is bit-exact with C code.
248919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int n = HALF_SUBFRAMELEN - 1;
249919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int32_t t16a, t16b;
250919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  int32_t r0, r1, r2, r3, r4;
251919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
252919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  __asm __volatile (
253919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          push                                      \n\t"
254919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          noreorder                                 \n\t"
255919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[t16a],      %[input2],     16           \n\t"
256919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "andi          %[t16b],      %[input2],     0xFFFF       \n\t"
257919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS32R2_LE)
258919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "seh           %[t16b],      %[t16b]                     \n\t"
259919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "seh           %[input0],    %[input0]                   \n\t"
260919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "seh           %[input1],    %[input1]                   \n\t"
261919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#else
262919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[t16b],      %[t16b],       16           \n\t"
263919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[t16b],      %[t16b],       16           \n\t"
264919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[input0],    %[input0],     16           \n\t"
265919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[input0],    %[input0],     16           \n\t"
266919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[input1],    %[input1],     16           \n\t"
267919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[input1],    %[input1],     16           \n\t"
268919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
269919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[r0],        %[t16a],       1            \n\t"
270919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "slt           %[r1],        %[t16b],       $zero        \n\t"
271919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "movn          %[t16a],      %[r0],         %[r1]        \n\t"
272919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org   "1:                                                       \n\t"
273919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r0],        0(%[ptr0])                  \n\t"
274919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "lw            %[r1],        0(%[ptr2])                  \n\t"
275919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr0],      %[ptr0],       4            \n\t"
276919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r2],        %[r0],         16           \n\t"
277919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "andi          %[r0],        %[r0],         0xFFFF       \n\t"
278919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r3],        %[r2],         %[input0]    \n\t"
279919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r4],        %[r0],         %[input0]    \n\t"
280919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r2],        %[r2],         %[input1]    \n\t"
281919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r0],        %[r0],         %[input1]    \n\t"
282919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[ptr2],      %[ptr2],       4            \n\t"
283919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[r3],        %[r3],         1            \n\t"
284919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r4],        %[r4],         1            \n\t"
285919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[r4],        %[r4],         0x2000       \n\t"
286919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r4],        %[r4],         14           \n\t"
287919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r3],        %[r3],         %[r4]        \n\t"
288919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r1],        %[r1],         %[r3]        \n\t"
289919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r3],        %[r1],         16           \n\t"
290919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "andi          %[r4],        %[r1],         0xFFFF       \n\t"
291919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r4],        %[r4],         1            \n\t"
292919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r1],        %[r1],         %[t16a]      \n\t"
293919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r3],        %[r3],         %[t16b]      \n\t"
294919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r4],        %[r4],         %[t16b]      \n\t"
295919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[r2],        %[r2],         1            \n\t"
296919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r0],        %[r0],         1            \n\t"
297919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[r0],        %[r0],         0x2000       \n\t"
298919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r0],        %[r0],         14           \n\t"
299919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r0],        %[r0],         %[r2]        \n\t"
300919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[n],         %[n],          -1           \n\t"
301919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r1],        %[r1],         %[r3]        \n\t"
302919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[r4],        %[r4],         0x4000       \n\t"
303919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r4],        %[r4],         15           \n\t"
304919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r1],        %[r1],         %[r4]        \n\t"
305919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r2],        %[r1],         16           \n\t"
306919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "andi          %[r3],        %[r1],         0xFFFF       \n\t"
307919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r3],        %[r3],         %[input0]    \n\t"
308919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "mul           %[r2],        %[r2],         %[input0]    \n\t"
309919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[r1],        -4(%[ptr2])                 \n\t"
310919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r3],        %[r3],         1            \n\t"
311919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addiu         %[r3],        %[r3],         0x2000       \n\t"
312919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sra           %[r3],        %[r3],         14           \n\t"
313919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r0],        %[r0],         %[r3]        \n\t"
314919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sll           %[r2],        %[r2],         1            \n\t"
315919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "addu          %[r0],        %[r0],         %[r2]        \n\t"
316919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "sw            %[r0],        0(%[ptr1])                  \n\t"
317919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    "bgtz          %[n],         1b                          \n\t"
318919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    " addiu        %[ptr1],      %[ptr1],       4            \n\t"
319919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    ".set          pop                                       \n\t"
320919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : [t16a] "=&r" (t16a), [t16b] "=&r" (t16b), [r0] "=&r" (r0),
321919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
322919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [r4] "=&r" (r4), [ptr0] "+r" (ptr0), [ptr1] "+r" (ptr1),
323919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [ptr2] "+r" (ptr2), [n] "+r" (n)
324919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : [input0] "r" (input0), [input1] "r" (input1),
325919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      [input2] "r" (input2)
326919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org    : "hi", "lo", "memory"
327919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  );
328919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
329919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org}
330