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