Home | History | Annotate | Download | only in signal_processing
      1 /*
      2  *  Copyright (c) 2013 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 #include <assert.h>
     11 
     12 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     13 
     14 void WebRtcSpl_FilterARFastQ12(const int16_t* data_in,
     15                                int16_t* data_out,
     16                                const int16_t* __restrict coefficients,
     17                                int coefficients_length,
     18                                int data_length) {
     19   int r0, r1, r2, r3;
     20   int coef0, offset;
     21   int i, j, k;
     22   int coefptr, outptr, tmpout, inptr;
     23 #if !defined(MIPS_DSP_R1_LE)
     24   int max16 = 0x7FFF;
     25   int min16 = 0xFFFF8000;
     26 #endif  // #if !defined(MIPS_DSP_R1_LE)
     27 
     28   assert(data_length > 0);
     29   assert(coefficients_length > 1);
     30 
     31   __asm __volatile (
     32     ".set       push                                             \n\t"
     33     ".set       noreorder                                        \n\t"
     34     "addiu      %[i],       %[data_length],          0           \n\t"
     35     "lh         %[coef0],   0(%[coefficients])                   \n\t"
     36     "addiu      %[j],       %[coefficients_length],  -1          \n\t"
     37     "andi       %[k],       %[j],                    1           \n\t"
     38     "sll        %[offset],  %[j],                    1           \n\t"
     39     "subu       %[outptr],  %[data_out],             %[offset]   \n\t"
     40     "addiu      %[inptr],   %[data_in],              0           \n\t"
     41     "bgtz       %[k],       3f                                   \n\t"
     42     " addu      %[coefptr], %[coefficients],         %[offset]   \n\t"
     43    "1:                                                           \n\t"
     44     "lh         %[r0],      0(%[inptr])                          \n\t"
     45     "addiu      %[i],       %[i],                    -1          \n\t"
     46     "addiu      %[tmpout],  %[outptr],               0           \n\t"
     47     "mult       %[r0],      %[coef0]                             \n\t"
     48    "2:                                                           \n\t"
     49     "lh         %[r0],      0(%[tmpout])                         \n\t"
     50     "lh         %[r1],      0(%[coefptr])                        \n\t"
     51     "lh         %[r2],      2(%[tmpout])                         \n\t"
     52     "lh         %[r3],      -2(%[coefptr])                       \n\t"
     53     "addiu      %[tmpout],  %[tmpout],               4           \n\t"
     54     "msub       %[r0],      %[r1]                                \n\t"
     55     "msub       %[r2],      %[r3]                                \n\t"
     56     "addiu      %[j],       %[j],                    -2          \n\t"
     57     "bgtz       %[j],       2b                                   \n\t"
     58     " addiu     %[coefptr], %[coefptr],              -4          \n\t"
     59 #if defined(MIPS_DSP_R1_LE)
     60     "extr_r.w   %[r0],      $ac0,                    12          \n\t"
     61 #else  // #if defined(MIPS_DSP_R1_LE)
     62     "mflo       %[r0]                                            \n\t"
     63 #endif  // #if defined(MIPS_DSP_R1_LE)
     64     "addu       %[coefptr], %[coefficients],         %[offset]   \n\t"
     65     "addiu      %[inptr],   %[inptr],                2           \n\t"
     66     "addiu      %[j],       %[coefficients_length],  -1          \n\t"
     67 #if defined(MIPS_DSP_R1_LE)
     68     "shll_s.w   %[r0],      %[r0],                   16          \n\t"
     69     "sra        %[r0],      %[r0],                   16          \n\t"
     70 #else  // #if defined(MIPS_DSP_R1_LE)
     71     "addiu      %[r0],      %[r0],                   2048        \n\t"
     72     "sra        %[r0],      %[r0],                   12          \n\t"
     73     "slt        %[r1],      %[max16],                %[r0]       \n\t"
     74     "movn       %[r0],      %[max16],                %[r1]       \n\t"
     75     "slt        %[r1],      %[r0],                   %[min16]    \n\t"
     76     "movn       %[r0],      %[min16],                %[r1]       \n\t"
     77 #endif  // #if defined(MIPS_DSP_R1_LE)
     78     "sh         %[r0],      0(%[tmpout])                         \n\t"
     79     "bgtz       %[i],       1b                                   \n\t"
     80     " addiu     %[outptr],  %[outptr],               2           \n\t"
     81     "b          5f                                               \n\t"
     82     " nop                                                        \n\t"
     83    "3:                                                           \n\t"
     84     "lh         %[r0],      0(%[inptr])                          \n\t"
     85     "addiu      %[i],       %[i],                    -1          \n\t"
     86     "addiu      %[tmpout],  %[outptr],               0           \n\t"
     87     "mult       %[r0],      %[coef0]                             \n\t"
     88    "4:                                                           \n\t"
     89     "lh         %[r0],      0(%[tmpout])                         \n\t"
     90     "lh         %[r1],      0(%[coefptr])                        \n\t"
     91     "lh         %[r2],      2(%[tmpout])                         \n\t"
     92     "lh         %[r3],      -2(%[coefptr])                       \n\t"
     93     "addiu      %[tmpout],  %[tmpout],               4           \n\t"
     94     "msub       %[r0],      %[r1]                                \n\t"
     95     "msub       %[r2],      %[r3]                                \n\t"
     96     "addiu      %[j],       %[j],                    -2          \n\t"
     97     "bgtz       %[j],       4b                                   \n\t"
     98     " addiu     %[coefptr], %[coefptr],              -4          \n\t"
     99     "lh         %[r0],      0(%[tmpout])                         \n\t"
    100     "lh         %[r1],      0(%[coefptr])                        \n\t"
    101     "msub       %[r0],      %[r1]                                \n\t"
    102 #if defined(MIPS_DSP_R1_LE)
    103     "extr_r.w   %[r0],      $ac0,                    12          \n\t"
    104 #else  // #if defined(MIPS_DSP_R1_LE)
    105     "mflo       %[r0]                                            \n\t"
    106 #endif  // #if defined(MIPS_DSP_R1_LE)
    107     "addu       %[coefptr], %[coefficients],         %[offset]   \n\t"
    108     "addiu      %[inptr],   %[inptr],                2           \n\t"
    109     "addiu      %[j],       %[coefficients_length],  -1          \n\t"
    110 #if defined(MIPS_DSP_R1_LE)
    111     "shll_s.w   %[r0],      %[r0],                   16          \n\t"
    112     "sra        %[r0],      %[r0],                   16          \n\t"
    113 #else  // #if defined(MIPS_DSP_R1_LE)
    114     "addiu      %[r0],      %[r0],                   2048        \n\t"
    115     "sra        %[r0],      %[r0],                   12          \n\t"
    116     "slt        %[r1],      %[max16],                %[r0]       \n\t"
    117     "movn       %[r0],      %[max16],                %[r1]       \n\t"
    118     "slt        %[r1],      %[r0],                   %[min16]    \n\t"
    119     "movn       %[r0],      %[min16],                %[r1]       \n\t"
    120 #endif  // #if defined(MIPS_DSP_R1_LE)
    121     "sh         %[r0],      2(%[tmpout])                         \n\t"
    122     "bgtz       %[i],       3b                                   \n\t"
    123     " addiu     %[outptr],  %[outptr],               2           \n\t"
    124    "5:                                                           \n\t"
    125     ".set       pop                                              \n\t"
    126     : [i] "=&r" (i), [j] "=&r" (j), [k] "=&r" (k), [r0] "=&r" (r0),
    127       [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3),
    128       [coef0] "=&r" (coef0), [offset] "=&r" (offset),
    129       [outptr] "=&r" (outptr), [inptr] "=&r" (inptr),
    130       [coefptr] "=&r" (coefptr), [tmpout] "=&r" (tmpout)
    131     : [coefficients] "r" (coefficients), [data_length] "r" (data_length),
    132       [coefficients_length] "r" (coefficients_length),
    133 #if !defined(MIPS_DSP_R1_LE)
    134       [max16] "r" (max16), [min16] "r" (min16),
    135 #endif
    136       [data_out] "r" (data_out), [data_in] "r" (data_in)
    137     : "hi", "lo", "memory"
    138   );
    139 }
    140 
    141