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 
     11 /*
     12  * This file contains the implementation of function
     13  * WebRtcSpl_MaxAbsValueW16()
     14  *
     15  * The description header can be found in signal_processing_library.h.
     16  *
     17  */
     18 
     19 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
     20 
     21 // Maximum absolute value of word16 vector.
     22 int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, int length) {
     23   int32_t totMax = 0;
     24   int32_t tmp32_0, tmp32_1, tmp32_2, tmp32_3;
     25   int i, loop_size;
     26 
     27   if (vector == NULL || length <= 0) {
     28     return -1;
     29   }
     30 #if defined(MIPS_DSP_R1)
     31   const int32_t* tmpvec32 = (int32_t*)vector;
     32   loop_size = length >> 4;
     33 
     34   for (i = 0; i < loop_size; i++) {
     35     __asm__ volatile (
     36       "lw         %[tmp32_0],     0(%[tmpvec32])              \n\t"
     37       "lw         %[tmp32_1],     4(%[tmpvec32])              \n\t"
     38       "lw         %[tmp32_2],     8(%[tmpvec32])              \n\t"
     39       "lw         %[tmp32_3],     12(%[tmpvec32])             \n\t"
     40 
     41       "absq_s.ph  %[tmp32_0],     %[tmp32_0]                  \n\t"
     42       "absq_s.ph  %[tmp32_1],     %[tmp32_1]                  \n\t"
     43       "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
     44       "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
     45 
     46       "lw         %[tmp32_0],     16(%[tmpvec32])             \n\t"
     47       "absq_s.ph  %[tmp32_2],     %[tmp32_2]                  \n\t"
     48       "cmp.lt.ph  %[totMax],      %[tmp32_1]                  \n\t"
     49       "pick.ph    %[totMax],      %[tmp32_1],     %[totMax]   \n\t"
     50 
     51       "lw         %[tmp32_1],     20(%[tmpvec32])             \n\t"
     52       "absq_s.ph  %[tmp32_3],     %[tmp32_3]                  \n\t"
     53       "cmp.lt.ph  %[totMax],      %[tmp32_2]                  \n\t"
     54       "pick.ph    %[totMax],      %[tmp32_2],     %[totMax]   \n\t"
     55 
     56       "lw         %[tmp32_2],     24(%[tmpvec32])             \n\t"
     57       "cmp.lt.ph  %[totMax],      %[tmp32_3]                  \n\t"
     58       "pick.ph    %[totMax],      %[tmp32_3],     %[totMax]   \n\t"
     59 
     60       "lw         %[tmp32_3],     28(%[tmpvec32])             \n\t"
     61       "absq_s.ph  %[tmp32_0],     %[tmp32_0]                  \n\t"
     62       "absq_s.ph  %[tmp32_1],     %[tmp32_1]                  \n\t"
     63       "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
     64       "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
     65 
     66       "absq_s.ph  %[tmp32_2],     %[tmp32_2]                  \n\t"
     67       "cmp.lt.ph  %[totMax],      %[tmp32_1]                  \n\t"
     68       "pick.ph    %[totMax],      %[tmp32_1],     %[totMax]   \n\t"
     69       "absq_s.ph  %[tmp32_3],     %[tmp32_3]                  \n\t"
     70       "cmp.lt.ph  %[totMax],      %[tmp32_2]                  \n\t"
     71       "pick.ph    %[totMax],      %[tmp32_2],     %[totMax]   \n\t"
     72 
     73       "cmp.lt.ph  %[totMax],      %[tmp32_3]                  \n\t"
     74       "pick.ph    %[totMax],      %[tmp32_3],     %[totMax]   \n\t"
     75 
     76       "addiu      %[tmpvec32],    %[tmpvec32],    32          \n\t"
     77       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
     78         [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3),
     79         [totMax] "+r" (totMax), [tmpvec32] "+r" (tmpvec32)
     80       :
     81       : "memory"
     82     );
     83   }
     84   __asm__ volatile (
     85     "rotr       %[tmp32_0],     %[totMax],      16          \n\t"
     86     "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
     87     "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
     88     "packrl.ph  %[totMax],      $0,             %[totMax]   \n\t"
     89     : [tmp32_0] "=&r" (tmp32_0), [totMax] "+r" (totMax)
     90     :
     91   );
     92   loop_size = length & 0xf;
     93   for (i = 0; i < loop_size; i++) {
     94     __asm__ volatile (
     95       "lh         %[tmp32_0],     0(%[tmpvec32])              \n\t"
     96       "addiu      %[tmpvec32],    %[tmpvec32],     2          \n\t"
     97       "absq_s.w   %[tmp32_0],     %[tmp32_0]                  \n\t"
     98       "slt        %[tmp32_1],     %[totMax],       %[tmp32_0] \n\t"
     99       "movn       %[totMax],      %[tmp32_0],      %[tmp32_1] \n\t"
    100       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
    101         [tmpvec32] "+r" (tmpvec32), [totMax] "+r" (totMax)
    102       :
    103       : "memory"
    104     );
    105   }
    106 #else  // #if defined(MIPS_DSP_R1)
    107   int32_t v16MaxMax = WEBRTC_SPL_WORD16_MAX;
    108   int32_t r, r1, r2, r3;
    109   const int16_t* tmpvector = vector;
    110   loop_size = length >> 4;
    111   for (i = 0; i < loop_size; i++) {
    112     __asm__ volatile (
    113       "lh     %[tmp32_0],     0(%[tmpvector])                 \n\t"
    114       "lh     %[tmp32_1],     2(%[tmpvector])                 \n\t"
    115       "lh     %[tmp32_2],     4(%[tmpvector])                 \n\t"
    116       "lh     %[tmp32_3],     6(%[tmpvector])                 \n\t"
    117 
    118       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
    119       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
    120       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
    121       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
    122 
    123       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
    124       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
    125       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
    126       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
    127       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
    128       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
    129       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
    130       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
    131 
    132       "lh     %[tmp32_0],     8(%[tmpvector])                 \n\t"
    133       "lh     %[tmp32_1],     10(%[tmpvector])                \n\t"
    134       "lh     %[tmp32_2],     12(%[tmpvector])                \n\t"
    135       "lh     %[tmp32_3],     14(%[tmpvector])                \n\t"
    136 
    137       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
    138       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
    139       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
    140       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
    141 
    142       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
    143       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
    144       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
    145       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
    146       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
    147       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
    148       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
    149       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
    150 
    151       "lh     %[tmp32_0],     16(%[tmpvector])                \n\t"
    152       "lh     %[tmp32_1],     18(%[tmpvector])                \n\t"
    153       "lh     %[tmp32_2],     20(%[tmpvector])                \n\t"
    154       "lh     %[tmp32_3],     22(%[tmpvector])                \n\t"
    155 
    156       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
    157       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
    158       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
    159       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
    160 
    161       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
    162       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
    163       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
    164       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
    165       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
    166       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
    167       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
    168       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
    169 
    170       "lh     %[tmp32_0],     24(%[tmpvector])                \n\t"
    171       "lh     %[tmp32_1],     26(%[tmpvector])                \n\t"
    172       "lh     %[tmp32_2],     28(%[tmpvector])                \n\t"
    173       "lh     %[tmp32_3],     30(%[tmpvector])                \n\t"
    174 
    175       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
    176       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
    177       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
    178       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
    179 
    180       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
    181       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
    182       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
    183       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
    184       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
    185       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
    186       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
    187       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
    188 
    189       "addiu  %[tmpvector],   %[tmpvector],   32              \n\t"
    190       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
    191         [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3),
    192         [totMax] "+r" (totMax), [r] "=&r" (r), [tmpvector] "+r" (tmpvector),
    193         [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3)
    194       :
    195       : "memory"
    196     );
    197   }
    198   loop_size = length & 0xf;
    199   for (i = 0; i < loop_size; i++) {
    200     __asm__ volatile (
    201       "lh         %[tmp32_0],     0(%[tmpvector])             \n\t"
    202       "addiu      %[tmpvector],   %[tmpvector],    2          \n\t"
    203       "abs        %[tmp32_0],     %[tmp32_0]                  \n\t"
    204       "slt        %[tmp32_1],     %[totMax],       %[tmp32_0] \n\t"
    205       "movn       %[totMax],      %[tmp32_0],      %[tmp32_1] \n\t"
    206       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
    207         [tmpvector] "+r" (tmpvector), [totMax] "+r" (totMax)
    208       :
    209       : "memory"
    210     );
    211   }
    212 
    213   __asm__ volatile (
    214     "slt    %[r],       %[v16MaxMax],   %[totMax]   \n\t"
    215     "movn   %[totMax],  %[v16MaxMax],   %[r]        \n\t"
    216     : [totMax] "+r" (totMax), [r] "=&r" (r)
    217     : [v16MaxMax] "r" (v16MaxMax)
    218   );
    219 #endif  // #if defined(MIPS_DSP_R1)
    220   return (int16_t)totMax;
    221 }
    222 
    223 #if defined(MIPS_DSP_R1_LE)
    224 // Maximum absolute value of word32 vector. Version for MIPS platform.
    225 int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, int length) {
    226   // Use uint32_t for the local variables, to accommodate the return value
    227   // of abs(0x80000000), which is 0x80000000.
    228 
    229   uint32_t absolute = 0, maximum = 0;
    230   int tmp1 = 0, max_value = 0x7fffffff;
    231 
    232   if (vector == NULL || length <= 0) {
    233     return -1;
    234   }
    235 
    236   __asm__ volatile (
    237     ".set push                                                        \n\t"
    238     ".set noreorder                                                   \n\t"
    239 
    240    "1:                                                                \n\t"
    241     "lw         %[absolute],      0(%[vector])                        \n\t"
    242     "absq_s.w   %[absolute],      %[absolute]                         \n\t"
    243     "addiu      %[length],        %[length],          -1              \n\t"
    244     "slt        %[tmp1],          %[maximum],         %[absolute]     \n\t"
    245     "movn       %[maximum],       %[absolute],        %[tmp1]         \n\t"
    246     "bgtz       %[length],        1b                                  \n\t"
    247     " addiu     %[vector],        %[vector],          4               \n\t"
    248     "slt        %[tmp1],          %[max_value],       %[maximum]      \n\t"
    249     "movn       %[maximum],       %[max_value],       %[tmp1]         \n\t"
    250 
    251     ".set pop                                                         \n\t"
    252 
    253     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [absolute] "+r" (absolute)
    254     : [vector] "r" (vector), [length] "r" (length), [max_value] "r" (max_value)
    255     : "memory"
    256   );
    257 
    258   return (int32_t)maximum;
    259 }
    260 #endif  // #if defined(MIPS_DSP_R1_LE)
    261 
    262 // Maximum value of word16 vector. Version for MIPS platform.
    263 int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, int length) {
    264   int16_t maximum = WEBRTC_SPL_WORD16_MIN;
    265   int tmp1;
    266   int16_t value;
    267 
    268   if (vector == NULL || length <= 0) {
    269     return maximum;
    270   }
    271 
    272   __asm__ volatile (
    273     ".set push                                                        \n\t"
    274     ".set noreorder                                                   \n\t"
    275 
    276    "1:                                                                \n\t"
    277     "lh         %[value],         0(%[vector])                        \n\t"
    278     "addiu      %[length],        %[length],          -1              \n\t"
    279     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
    280     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
    281     "bgtz       %[length],        1b                                  \n\t"
    282     " addiu     %[vector],        %[vector],          2               \n\t"
    283     ".set pop                                                         \n\t"
    284 
    285     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
    286     : [vector] "r" (vector), [length] "r" (length)
    287     : "memory"
    288   );
    289 
    290   return maximum;
    291 }
    292 
    293 // Maximum value of word32 vector. Version for MIPS platform.
    294 int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, int length) {
    295   int32_t maximum = WEBRTC_SPL_WORD32_MIN;
    296   int tmp1, value;
    297 
    298   if (vector == NULL || length <= 0) {
    299     return maximum;
    300   }
    301 
    302   __asm__ volatile (
    303     ".set push                                                        \n\t"
    304     ".set noreorder                                                   \n\t"
    305 
    306    "1:                                                                \n\t"
    307     "lw         %[value],         0(%[vector])                        \n\t"
    308     "addiu      %[length],        %[length],          -1              \n\t"
    309     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
    310     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
    311     "bgtz       %[length],        1b                                  \n\t"
    312     " addiu     %[vector],        %[vector],          4               \n\t"
    313 
    314     ".set pop                                                         \n\t"
    315 
    316     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
    317     : [vector] "r" (vector), [length] "r" (length)
    318     : "memory"
    319   );
    320 
    321   return maximum;
    322 }
    323 
    324 // Minimum value of word16 vector. Version for MIPS platform.
    325 int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, int length) {
    326   int16_t minimum = WEBRTC_SPL_WORD16_MAX;
    327   int tmp1;
    328   int16_t value;
    329 
    330   if (vector == NULL || length <= 0) {
    331     return minimum;
    332   }
    333 
    334   __asm__ volatile (
    335     ".set push                                                        \n\t"
    336     ".set noreorder                                                   \n\t"
    337 
    338    "1:                                                                \n\t"
    339     "lh         %[value],         0(%[vector])                        \n\t"
    340     "addiu      %[length],        %[length],          -1              \n\t"
    341     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
    342     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
    343     "bgtz       %[length],        1b                                  \n\t"
    344     " addiu     %[vector],        %[vector],          2               \n\t"
    345 
    346     ".set pop                                                         \n\t"
    347 
    348     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
    349     : [vector] "r" (vector), [length] "r" (length)
    350     : "memory"
    351   );
    352 
    353   return minimum;
    354 }
    355 
    356 // Minimum value of word32 vector. Version for MIPS platform.
    357 int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, int length) {
    358   int32_t minimum = WEBRTC_SPL_WORD32_MAX;
    359   int tmp1, value;
    360 
    361   if (vector == NULL || length <= 0) {
    362     return minimum;
    363   }
    364 
    365   __asm__ volatile (
    366     ".set push                                                        \n\t"
    367     ".set noreorder                                                   \n\t"
    368 
    369    "1:                                                                \n\t"
    370     "lw         %[value],         0(%[vector])                        \n\t"
    371     "addiu      %[length],        %[length],          -1              \n\t"
    372     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
    373     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
    374     "bgtz       %[length],        1b                                  \n\t"
    375     " addiu     %[vector],        %[vector],          4               \n\t"
    376 
    377     ".set pop                                                         \n\t"
    378 
    379     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
    380     : [vector] "r" (vector), [length] "r" (length)
    381     : "memory"
    382   );
    383 
    384   return minimum;
    385 }
    386