11aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org/*
21aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
31aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *
41aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
51aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
61aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
71aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
81aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
91aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org */
101aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#include <assert.h>
111aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org
123936bb118a858e3c21f06ced98ddc893d216523cpbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
131aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org
141aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.orgvoid WebRtcSpl_FilterARFastQ12(const int16_t* data_in,
151aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org                               int16_t* data_out,
161aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org                               const int16_t* __restrict coefficients,
171aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org                               int coefficients_length,
181aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org                               int data_length) {
191aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int r0, r1, r2, r3;
201aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int coef0, offset;
211aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int i, j, k;
221aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int coefptr, outptr, tmpout, inptr;
231aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if !defined(MIPS_DSP_R1_LE)
241aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int max16 = 0x7FFF;
251aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  int min16 = 0xFFFF8000;
261aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif  // #if !defined(MIPS_DSP_R1_LE)
271aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org
281aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  assert(data_length > 0);
291aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  assert(coefficients_length > 1);
301aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org
311aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  __asm __volatile (
321aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    ".set       push                                             \n\t"
331aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    ".set       noreorder                                        \n\t"
341aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[i],       %[data_length],          0           \n\t"
351aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[coef0],   0(%[coefficients])                   \n\t"
361aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[j],       %[coefficients_length],  -1          \n\t"
371aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "andi       %[k],       %[j],                    1           \n\t"
381aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sll        %[offset],  %[j],                    1           \n\t"
391aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "subu       %[outptr],  %[data_out],             %[offset]   \n\t"
401aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[inptr],   %[data_in],              0           \n\t"
411aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "bgtz       %[k],       3f                                   \n\t"
421aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " addu      %[coefptr], %[coefficients],         %[offset]   \n\t"
431aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org   "1:                                                           \n\t"
441aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r0],      0(%[inptr])                          \n\t"
451aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[i],       %[i],                    -1          \n\t"
461aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[tmpout],  %[outptr],               0           \n\t"
471aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "mult       %[r0],      %[coef0]                             \n\t"
481aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org   "2:                                                           \n\t"
491aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r0],      0(%[tmpout])                         \n\t"
501aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r1],      0(%[coefptr])                        \n\t"
511aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r2],      2(%[tmpout])                         \n\t"
521aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r3],      -2(%[coefptr])                       \n\t"
531aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[tmpout],  %[tmpout],               4           \n\t"
541aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "msub       %[r0],      %[r1]                                \n\t"
551aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "msub       %[r2],      %[r3]                                \n\t"
561aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[j],       %[j],                    -2          \n\t"
571aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "bgtz       %[j],       2b                                   \n\t"
581aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " addiu     %[coefptr], %[coefptr],              -4          \n\t"
591aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
601aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "extr_r.w   %[r0],      $ac0,                    12          \n\t"
611aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#else  // #if defined(MIPS_DSP_R1_LE)
621aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "mflo       %[r0]                                            \n\t"
631aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif  // #if defined(MIPS_DSP_R1_LE)
641aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addu       %[coefptr], %[coefficients],         %[offset]   \n\t"
651aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[inptr],   %[inptr],                2           \n\t"
661aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[j],       %[coefficients_length],  -1          \n\t"
671aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
681aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "shll_s.w   %[r0],      %[r0],                   16          \n\t"
691aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sra        %[r0],      %[r0],                   16          \n\t"
701aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#else  // #if defined(MIPS_DSP_R1_LE)
711aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[r0],      %[r0],                   2048        \n\t"
721aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sra        %[r0],      %[r0],                   12          \n\t"
731aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "slt        %[r1],      %[max16],                %[r0]       \n\t"
741aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "movn       %[r0],      %[max16],                %[r1]       \n\t"
751aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "slt        %[r1],      %[r0],                   %[min16]    \n\t"
761aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "movn       %[r0],      %[min16],                %[r1]       \n\t"
771aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif  // #if defined(MIPS_DSP_R1_LE)
781aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sh         %[r0],      0(%[tmpout])                         \n\t"
791aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "bgtz       %[i],       1b                                   \n\t"
801aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " addiu     %[outptr],  %[outptr],               2           \n\t"
811aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "b          5f                                               \n\t"
821aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " nop                                                        \n\t"
831aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org   "3:                                                           \n\t"
841aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r0],      0(%[inptr])                          \n\t"
851aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[i],       %[i],                    -1          \n\t"
861aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[tmpout],  %[outptr],               0           \n\t"
871aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "mult       %[r0],      %[coef0]                             \n\t"
881aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org   "4:                                                           \n\t"
891aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r0],      0(%[tmpout])                         \n\t"
901aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r1],      0(%[coefptr])                        \n\t"
911aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r2],      2(%[tmpout])                         \n\t"
921aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r3],      -2(%[coefptr])                       \n\t"
931aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[tmpout],  %[tmpout],               4           \n\t"
941aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "msub       %[r0],      %[r1]                                \n\t"
951aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "msub       %[r2],      %[r3]                                \n\t"
961aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[j],       %[j],                    -2          \n\t"
971aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "bgtz       %[j],       4b                                   \n\t"
981aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " addiu     %[coefptr], %[coefptr],              -4          \n\t"
991aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r0],      0(%[tmpout])                         \n\t"
1001aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "lh         %[r1],      0(%[coefptr])                        \n\t"
1011aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "msub       %[r0],      %[r1]                                \n\t"
1021aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
1031aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "extr_r.w   %[r0],      $ac0,                    12          \n\t"
1041aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#else  // #if defined(MIPS_DSP_R1_LE)
1051aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "mflo       %[r0]                                            \n\t"
1061aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif  // #if defined(MIPS_DSP_R1_LE)
1071aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addu       %[coefptr], %[coefficients],         %[offset]   \n\t"
1081aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[inptr],   %[inptr],                2           \n\t"
1091aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[j],       %[coefficients_length],  -1          \n\t"
1101aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
1111aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "shll_s.w   %[r0],      %[r0],                   16          \n\t"
1121aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sra        %[r0],      %[r0],                   16          \n\t"
1131aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#else  // #if defined(MIPS_DSP_R1_LE)
1141aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "addiu      %[r0],      %[r0],                   2048        \n\t"
1151aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sra        %[r0],      %[r0],                   12          \n\t"
1161aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "slt        %[r1],      %[max16],                %[r0]       \n\t"
1171aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "movn       %[r0],      %[max16],                %[r1]       \n\t"
1181aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "slt        %[r1],      %[r0],                   %[min16]    \n\t"
1191aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "movn       %[r0],      %[min16],                %[r1]       \n\t"
1201aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif  // #if defined(MIPS_DSP_R1_LE)
1211aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "sh         %[r0],      2(%[tmpout])                         \n\t"
1221aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    "bgtz       %[i],       3b                                   \n\t"
1231aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    " addiu     %[outptr],  %[outptr],               2           \n\t"
1241aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org   "5:                                                           \n\t"
1251aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    ".set       pop                                              \n\t"
1261aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0),
1271aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
1281aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [coef0] "=&r" (coef0), [offset] "=&r" (offset),
1291aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [outptr] "=&r" (outptr), [inptr] "=&r" (inptr),
1301aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout)
1311aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    : [coefficients] "r" (coefficients), [data_length] "r" (data_length),
1321aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [coefficients_length] "r" (coefficients_length),
1331aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#if !defined(MIPS_DSP_R1_LE)
1341aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [max16] "r" (max16), [min16] "r" (min16),
1351aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org#endif
1361aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org      [data_out] "r" (data_out), [data_in] "r" (data_in)
1371aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org    : "hi", "lo", "memory"
1381aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org  );
1391aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org}
1401aa406c729cf075f59b5381d9fa632014f4824b9andrew@webrtc.org
141