Home | History | Annotate | Download | only in include
      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 header file includes the inline functions in
     13 // the fix point signal processing library.
     14 
     15 #ifndef WEBRTC_SPL_SPL_INL_MIPS_H_
     16 #define WEBRTC_SPL_SPL_INL_MIPS_H_
     17 
     18 static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a,
     19                                              int32_t b) {
     20   int32_t value32 = 0;
     21   int32_t a1 = 0, b1 = 0;
     22 
     23   __asm __volatile(
     24 #if defined(MIPS32_R2_LE)
     25     "seh    %[a1],          %[a]                \n\t"
     26     "seh    %[b1],          %[b]                \n\t"
     27 #else
     28     "sll    %[a1],          %[a],         16    \n\t"
     29     "sll    %[b1],          %[b],         16    \n\t"
     30     "sra    %[a1],          %[a1],        16    \n\t"
     31     "sra    %[b1],          %[b1],        16    \n\t"
     32 #endif
     33     "mul    %[value32],     %[a1],  %[b1]       \n\t"
     34     : [value32] "=r" (value32), [a1] "=&r" (a1), [b1] "=&r" (b1)
     35     : [a] "r" (a), [b] "r" (b)
     36     : "hi", "lo"
     37   );
     38   return value32;
     39 }
     40 
     41 static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a,
     42                                                     int32_t b) {
     43   int32_t value32 = 0, b1 = 0, b2 = 0;
     44   int32_t a1 = 0;
     45 
     46   __asm __volatile(
     47 #if defined(MIPS32_R2_LE)
     48     "seh    %[a1],          %[a]                        \n\t"
     49 #else
     50     "sll    %[a1],          %[a],           16          \n\t"
     51     "sra    %[a1],          %[a1],          16          \n\t"
     52 #endif
     53     "andi   %[b2],          %[b],           0xFFFF      \n\t"
     54     "sra    %[b1],          %[b],           16          \n\t"
     55     "sra    %[b2],          %[b2],          1           \n\t"
     56     "mul    %[value32],     %[a1],          %[b1]       \n\t"
     57     "mul    %[b2],          %[a1],          %[b2]       \n\t"
     58     "addiu  %[b2],          %[b2],          0x4000      \n\t"
     59     "sra    %[b2],          %[b2],          15          \n\t"
     60     "addu   %[value32],     %[value32],     %[b2]       \n\t"
     61     : [value32] "=&r" (value32), [b1] "=&r" (b1), [b2] "=&r" (b2),
     62       [a1] "=&r" (a1)
     63     : [a] "r" (a), [b] "r" (b)
     64     : "hi", "lo"
     65   );
     66   return value32;
     67 }
     68 
     69 #if defined(MIPS_DSP_R1_LE)
     70 static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
     71   __asm __volatile(
     72     "shll_s.w   %[value32], %[value32], 16      \n\t"
     73     "sra        %[value32], %[value32], 16      \n\t"
     74     : [value32] "+r" (value32)
     75     :
     76   );
     77   int16_t out16 = (int16_t)value32;
     78   return out16;
     79 }
     80 
     81 static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
     82   int32_t value32 = 0;
     83 
     84   __asm __volatile(
     85     "addq_s.ph      %[value32],     %[a],   %[b]    \n\t"
     86     : [value32] "=r" (value32)
     87     : [a] "r" (a), [b] "r" (b)
     88   );
     89   return (int16_t)value32;
     90 }
     91 
     92 static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
     93   int32_t l_sum;
     94 
     95   __asm __volatile(
     96     "addq_s.w   %[l_sum],       %[l_var1],      %[l_var2]    \n\t"
     97     : [l_sum] "=r" (l_sum)
     98     : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
     99   );
    100 
    101   return l_sum;
    102 }
    103 
    104 static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
    105   int32_t value32;
    106 
    107   __asm __volatile(
    108     "subq_s.ph  %[value32], %[var1],    %[var2]     \n\t"
    109     : [value32] "=r" (value32)
    110     : [var1] "r" (var1), [var2] "r" (var2)
    111   );
    112 
    113   return (int16_t)value32;
    114 }
    115 
    116 static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
    117   int32_t l_diff;
    118 
    119   __asm __volatile(
    120     "subq_s.w   %[l_diff],      %[l_var1],      %[l_var2]    \n\t"
    121     : [l_diff] "=r" (l_diff)
    122     : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
    123   );
    124 
    125   return l_diff;
    126 }
    127 #endif
    128 
    129 static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
    130   int bits = 0;
    131   int i32 = 32;
    132 
    133   __asm __volatile(
    134     "clz    %[bits],    %[n]                    \n\t"
    135     "subu   %[bits],    %[i32],     %[bits]     \n\t"
    136     : [bits] "=&r" (bits)
    137     : [n] "r" (n), [i32] "r" (i32)
    138   );
    139 
    140   return (int16_t)bits;
    141 }
    142 
    143 static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
    144   int zeros = 0;
    145 
    146   __asm __volatile(
    147     ".set       push                                \n\t"
    148     ".set       noreorder                           \n\t"
    149     "bnez       %[a],       1f                      \n\t"
    150     " sra       %[zeros],   %[a],       31          \n\t"
    151     "b          2f                                  \n\t"
    152     " move      %[zeros],   $zero                   \n\t"
    153    "1:                                              \n\t"
    154     "xor        %[zeros],   %[a],       %[zeros]    \n\t"
    155     "clz        %[zeros],   %[zeros]                \n\t"
    156     "addiu      %[zeros],   %[zeros],   -1          \n\t"
    157    "2:                                              \n\t"
    158     ".set       pop                                 \n\t"
    159     : [zeros]"=&r"(zeros)
    160     : [a] "r" (a)
    161   );
    162 
    163   return (int16_t)zeros;
    164 }
    165 
    166 static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
    167   int zeros = 0;
    168 
    169   __asm __volatile(
    170     "clz    %[zeros],   %[a]    \n\t"
    171     : [zeros] "=r" (zeros)
    172     : [a] "r" (a)
    173   );
    174 
    175   return (int16_t)(zeros & 0x1f);
    176 }
    177 
    178 static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
    179   int zeros = 0;
    180   int a0 = a << 16;
    181 
    182   __asm __volatile(
    183     ".set       push                                \n\t"
    184     ".set       noreorder                           \n\t"
    185     "bnez       %[a0],      1f                      \n\t"
    186     " sra       %[zeros],   %[a0],      31          \n\t"
    187     "b          2f                                  \n\t"
    188     " move      %[zeros],   $zero                   \n\t"
    189    "1:                                              \n\t"
    190     "xor        %[zeros],   %[a0],      %[zeros]    \n\t"
    191     "clz        %[zeros],   %[zeros]                \n\t"
    192     "addiu      %[zeros],   %[zeros],   -1          \n\t"
    193    "2:                                              \n\t"
    194     ".set       pop                                 \n\t"
    195     : [zeros]"=&r"(zeros)
    196     : [a0] "r" (a0)
    197   );
    198 
    199   return (int16_t)zeros;
    200 }
    201 
    202 static __inline int32_t WebRtc_MulAccumW16(int16_t a,
    203                                            int16_t b,
    204                                            int32_t c) {
    205   int32_t res = 0, c1 = 0;
    206   __asm __volatile(
    207 #if defined(MIPS32_R2_LE)
    208     "seh    %[a],       %[a]            \n\t"
    209     "seh    %[b],       %[b]            \n\t"
    210 #else
    211     "sll    %[a],       %[a],   16      \n\t"
    212     "sll    %[b],       %[b],   16      \n\t"
    213     "sra    %[a],       %[a],   16      \n\t"
    214     "sra    %[b],       %[b],   16      \n\t"
    215 #endif
    216     "mul    %[res],     %[a],   %[b]    \n\t"
    217     "addu   %[c1],      %[c],   %[res]  \n\t"
    218     : [c1] "=r" (c1), [res] "=&r" (res)
    219     : [a] "r" (a), [b] "r" (b), [c] "r" (c)
    220     : "hi", "lo"
    221   );
    222   return (c1);
    223 }
    224 
    225 #endif  // WEBRTC_SPL_SPL_INL_MIPS_H_
    226