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