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