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 18static __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 41static __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) 70static __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 81static __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 92static __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 104static __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 116static __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 129static __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 143static __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 166static __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 178static __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 202static __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