• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WEBRTC_SPL_MUL_16_16(int32_t a,int32_t b)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 
WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a,int32_t b)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 
WEBRTC_SPL_MUL_32_32_RSFT32BI(int32_t a,int32_t b)69 static __inline int32_t WEBRTC_SPL_MUL_32_32_RSFT32BI(int32_t a,
70                                                       int32_t b) {
71   int32_t tmp = 0;
72 
73   if ((32767 < a) || (a < 0))
74     tmp = WEBRTC_SPL_MUL_16_32_RSFT16(((int16_t)(a >> 16)), b);
75   tmp += WEBRTC_SPL_MUL_16_32_RSFT16(((int16_t)((a & 0x0000FFFF) >> 1)),
76                                      b) >> 15;
77 
78   return tmp;
79 }
80 
WEBRTC_SPL_MUL_32_32_RSFT32(int16_t a,int16_t b,int32_t c)81 static __inline int32_t WEBRTC_SPL_MUL_32_32_RSFT32(int16_t a,
82                                                     int16_t b,
83                                                     int32_t c) {
84   int32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
85 
86   __asm __volatile(
87     "sra                %[tmp1],   %[c],      16      \n\t"
88     "andi               %[tmp2],   %[c],      0xFFFF  \n\t"
89 #if defined(MIPS32_R2_LE)
90     "seh                %[a],      %[a]               \n\t"
91     "seh                %[b],      %[b]               \n\t"
92 #else
93     "sll                %[a],      %[a],      16      \n\t"
94     "sra                %[a],      %[a],      16      \n\t"
95     "sll                %[b],      %[b],      16      \n\t"
96     "sra                %[b],      %[b],      16      \n\t"
97 #endif
98     "sra                %[tmp2],   %[tmp2],   1       \n\t"
99     "mul                %[tmp3],   %[a],      %[tmp2] \n\t"
100     "mul                %[tmp4],   %[b],      %[tmp2] \n\t"
101     "mul                %[tmp2],   %[a],      %[tmp1] \n\t"
102     "mul                %[tmp1],   %[b],      %[tmp1] \n\t"
103 #if defined(MIPS_DSP_R1_LE)
104     "shra_r.w           %[tmp3],   %[tmp3],   15      \n\t"
105     "shra_r.w           %[tmp4],   %[tmp4],   15      \n\t"
106 #else
107     "addiu              %[tmp3],   %[tmp3],   0x4000  \n\t"
108     "sra                %[tmp3],   %[tmp3],   15      \n\t"
109     "addiu              %[tmp4],   %[tmp4],   0x4000  \n\t"
110     "sra                %[tmp4],   %[tmp4],   15      \n\t"
111 #endif
112     "addu               %[tmp3],   %[tmp3],   %[tmp2] \n\t"
113     "addu               %[tmp4],   %[tmp4],   %[tmp1] \n\t"
114     "sra                %[tmp4],   %[tmp4],   16      \n\t"
115     "addu               %[tmp1],   %[tmp3],   %[tmp4] \n\t"
116     : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2),
117       [tmp3] "=&r" (tmp3), [tmp4] "=&r" (tmp4),
118       [a] "+r" (a), [b] "+r" (b)
119     : [c] "r" (c)
120     : "hi", "lo"
121   );
122   return tmp1;
123 }
124 
125 #if defined(MIPS_DSP_R1_LE)
WebRtcSpl_SatW32ToW16(int32_t value32)126 static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
127   __asm __volatile(
128     "shll_s.w   %[value32], %[value32], 16      \n\t"
129     "sra        %[value32], %[value32], 16      \n\t"
130     : [value32] "+r" (value32)
131     :
132   );
133   int16_t out16 = (int16_t)value32;
134   return out16;
135 }
136 
WebRtcSpl_AddSatW16(int16_t a,int16_t b)137 static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
138   int32_t value32 = 0;
139 
140   __asm __volatile(
141     "addq_s.ph      %[value32],     %[a],   %[b]    \n\t"
142     : [value32] "=r" (value32)
143     : [a] "r" (a), [b] "r" (b)
144   );
145   return (int16_t)value32;
146 }
147 
WebRtcSpl_AddSatW32(int32_t l_var1,int32_t l_var2)148 static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
149   int32_t l_sum;
150 
151   __asm __volatile(
152     "addq_s.w   %[l_sum],       %[l_var1],      %[l_var2]    \n\t"
153     : [l_sum] "=r" (l_sum)
154     : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
155   );
156 
157   return l_sum;
158 }
159 
WebRtcSpl_SubSatW16(int16_t var1,int16_t var2)160 static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
161   int32_t value32;
162 
163   __asm __volatile(
164     "subq_s.ph  %[value32], %[var1],    %[var2]     \n\t"
165     : [value32] "=r" (value32)
166     : [var1] "r" (var1), [var2] "r" (var2)
167   );
168 
169   return (int16_t)value32;
170 }
171 
WebRtcSpl_SubSatW32(int32_t l_var1,int32_t l_var2)172 static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
173   int32_t l_diff;
174 
175   __asm __volatile(
176     "subq_s.w   %[l_diff],      %[l_var1],      %[l_var2]    \n\t"
177     : [l_diff] "=r" (l_diff)
178     : [l_var1] "r" (l_var1), [l_var2] "r" (l_var2)
179   );
180 
181   return l_diff;
182 }
183 #endif
184 
WebRtcSpl_GetSizeInBits(uint32_t n)185 static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
186   int bits = 0;
187   int i32 = 32;
188 
189   __asm __volatile(
190     "clz    %[bits],    %[n]                    \n\t"
191     "subu   %[bits],    %[i32],     %[bits]     \n\t"
192     : [bits] "=&r" (bits)
193     : [n] "r" (n), [i32] "r" (i32)
194   );
195 
196   return bits;
197 }
198 
WebRtcSpl_NormW32(int32_t a)199 static __inline int WebRtcSpl_NormW32(int32_t a) {
200   int zeros = 0;
201 
202   __asm __volatile(
203     ".set       push                                \n\t"
204     ".set       noreorder                           \n\t"
205     "bnez       %[a],       1f                      \n\t"
206     " sra       %[zeros],   %[a],       31          \n\t"
207     "b          2f                                  \n\t"
208     " move      %[zeros],   $zero                   \n\t"
209    "1:                                              \n\t"
210     "xor        %[zeros],   %[a],       %[zeros]    \n\t"
211     "clz        %[zeros],   %[zeros]                \n\t"
212     "addiu      %[zeros],   %[zeros],   -1          \n\t"
213    "2:                                              \n\t"
214     ".set       pop                                 \n\t"
215     : [zeros]"=&r"(zeros)
216     : [a] "r" (a)
217   );
218 
219   return zeros;
220 }
221 
WebRtcSpl_NormU32(uint32_t a)222 static __inline int WebRtcSpl_NormU32(uint32_t a) {
223   int zeros = 0;
224 
225   __asm __volatile(
226     "clz    %[zeros],   %[a]    \n\t"
227     : [zeros] "=r" (zeros)
228     : [a] "r" (a)
229   );
230 
231   return (zeros & 0x1f);
232 }
233 
WebRtcSpl_NormW16(int16_t a)234 static __inline int WebRtcSpl_NormW16(int16_t a) {
235   int zeros = 0;
236   int a0 = a << 16;
237 
238   __asm __volatile(
239     ".set       push                                \n\t"
240     ".set       noreorder                           \n\t"
241     "bnez       %[a0],      1f                      \n\t"
242     " sra       %[zeros],   %[a0],      31          \n\t"
243     "b          2f                                  \n\t"
244     " move      %[zeros],   $zero                   \n\t"
245    "1:                                              \n\t"
246     "xor        %[zeros],   %[a0],      %[zeros]    \n\t"
247     "clz        %[zeros],   %[zeros]                \n\t"
248     "addiu      %[zeros],   %[zeros],   -1          \n\t"
249    "2:                                              \n\t"
250     ".set       pop                                 \n\t"
251     : [zeros]"=&r"(zeros)
252     : [a0] "r" (a0)
253   );
254 
255   return zeros;
256 }
257 
WebRtc_MulAccumW16(int16_t a,int16_t b,int32_t c)258 static __inline int32_t WebRtc_MulAccumW16(int16_t a,
259                                            int16_t b,
260                                            int32_t c) {
261   int32_t res = 0, c1 = 0;
262   __asm __volatile(
263 #if defined(MIPS32_R2_LE)
264     "seh    %[a],       %[a]            \n\t"
265     "seh    %[b],       %[b]            \n\t"
266 #else
267     "sll    %[a],       %[a],   16      \n\t"
268     "sll    %[b],       %[b],   16      \n\t"
269     "sra    %[a],       %[a],   16      \n\t"
270     "sra    %[b],       %[b],   16      \n\t"
271 #endif
272     "mul    %[res],     %[a],   %[b]    \n\t"
273     "addu   %[c1],      %[c],   %[res]  \n\t"
274     : [c1] "=r" (c1), [res] "=&r" (res)
275     : [a] "r" (a), [b] "r" (b), [c] "r" (c)
276     : "hi", "lo"
277   );
278   return (c1);
279 }
280 
281 #endif  // WEBRTC_SPL_SPL_INL_MIPS_H_
282