• 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 file contains the implementation of function
13  * WebRtcSpl_MaxAbsValueW16()
14  *
15  * The description header can be found in signal_processing_library.h.
16  *
17  */
18 
19 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
20 
21 // Maximum absolute value of word16 vector.
WebRtcSpl_MaxAbsValueW16_mips(const int16_t * vector,int length)22 int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, int length) {
23   int32_t totMax = 0;
24   int32_t tmp32_0, tmp32_1, tmp32_2, tmp32_3;
25   int i, loop_size;
26 
27   if (vector == NULL || length <= 0) {
28     return -1;
29   }
30 #if defined(MIPS_DSP_R1)
31   const int32_t* tmpvec32 = (int32_t*)vector;
32   loop_size = length >> 4;
33 
34   for (i = 0; i < loop_size; i++) {
35     __asm__ volatile (
36       "lw         %[tmp32_0],     0(%[tmpvec32])              \n\t"
37       "lw         %[tmp32_1],     4(%[tmpvec32])              \n\t"
38       "lw         %[tmp32_2],     8(%[tmpvec32])              \n\t"
39       "lw         %[tmp32_3],     12(%[tmpvec32])             \n\t"
40 
41       "absq_s.ph  %[tmp32_0],     %[tmp32_0]                  \n\t"
42       "absq_s.ph  %[tmp32_1],     %[tmp32_1]                  \n\t"
43       "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
44       "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
45 
46       "lw         %[tmp32_0],     16(%[tmpvec32])             \n\t"
47       "absq_s.ph  %[tmp32_2],     %[tmp32_2]                  \n\t"
48       "cmp.lt.ph  %[totMax],      %[tmp32_1]                  \n\t"
49       "pick.ph    %[totMax],      %[tmp32_1],     %[totMax]   \n\t"
50 
51       "lw         %[tmp32_1],     20(%[tmpvec32])             \n\t"
52       "absq_s.ph  %[tmp32_3],     %[tmp32_3]                  \n\t"
53       "cmp.lt.ph  %[totMax],      %[tmp32_2]                  \n\t"
54       "pick.ph    %[totMax],      %[tmp32_2],     %[totMax]   \n\t"
55 
56       "lw         %[tmp32_2],     24(%[tmpvec32])             \n\t"
57       "cmp.lt.ph  %[totMax],      %[tmp32_3]                  \n\t"
58       "pick.ph    %[totMax],      %[tmp32_3],     %[totMax]   \n\t"
59 
60       "lw         %[tmp32_3],     28(%[tmpvec32])             \n\t"
61       "absq_s.ph  %[tmp32_0],     %[tmp32_0]                  \n\t"
62       "absq_s.ph  %[tmp32_1],     %[tmp32_1]                  \n\t"
63       "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
64       "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
65 
66       "absq_s.ph  %[tmp32_2],     %[tmp32_2]                  \n\t"
67       "cmp.lt.ph  %[totMax],      %[tmp32_1]                  \n\t"
68       "pick.ph    %[totMax],      %[tmp32_1],     %[totMax]   \n\t"
69       "absq_s.ph  %[tmp32_3],     %[tmp32_3]                  \n\t"
70       "cmp.lt.ph  %[totMax],      %[tmp32_2]                  \n\t"
71       "pick.ph    %[totMax],      %[tmp32_2],     %[totMax]   \n\t"
72 
73       "cmp.lt.ph  %[totMax],      %[tmp32_3]                  \n\t"
74       "pick.ph    %[totMax],      %[tmp32_3],     %[totMax]   \n\t"
75 
76       "addiu      %[tmpvec32],    %[tmpvec32],    32          \n\t"
77       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
78         [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3),
79         [totMax] "+r" (totMax), [tmpvec32] "+r" (tmpvec32)
80       :
81       : "memory"
82     );
83   }
84   __asm__ volatile (
85     "rotr       %[tmp32_0],     %[totMax],      16          \n\t"
86     "cmp.lt.ph  %[totMax],      %[tmp32_0]                  \n\t"
87     "pick.ph    %[totMax],      %[tmp32_0],     %[totMax]   \n\t"
88     "packrl.ph  %[totMax],      $0,             %[totMax]   \n\t"
89     : [tmp32_0] "=&r" (tmp32_0), [totMax] "+r" (totMax)
90     :
91   );
92   loop_size = length & 0xf;
93   for (i = 0; i < loop_size; i++) {
94     __asm__ volatile (
95       "lh         %[tmp32_0],     0(%[tmpvec32])              \n\t"
96       "addiu      %[tmpvec32],    %[tmpvec32],     2          \n\t"
97       "absq_s.w   %[tmp32_0],     %[tmp32_0]                  \n\t"
98       "slt        %[tmp32_1],     %[totMax],       %[tmp32_0] \n\t"
99       "movn       %[totMax],      %[tmp32_0],      %[tmp32_1] \n\t"
100       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
101         [tmpvec32] "+r" (tmpvec32), [totMax] "+r" (totMax)
102       :
103       : "memory"
104     );
105   }
106 #else  // #if defined(MIPS_DSP_R1)
107   int32_t v16MaxMax = WEBRTC_SPL_WORD16_MAX;
108   int32_t r, r1, r2, r3;
109   const int16_t* tmpvector = vector;
110   loop_size = length >> 4;
111   for (i = 0; i < loop_size; i++) {
112     __asm__ volatile (
113       "lh     %[tmp32_0],     0(%[tmpvector])                 \n\t"
114       "lh     %[tmp32_1],     2(%[tmpvector])                 \n\t"
115       "lh     %[tmp32_2],     4(%[tmpvector])                 \n\t"
116       "lh     %[tmp32_3],     6(%[tmpvector])                 \n\t"
117 
118       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
119       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
120       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
121       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
122 
123       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
124       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
125       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
126       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
127       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
128       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
129       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
130       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
131 
132       "lh     %[tmp32_0],     8(%[tmpvector])                 \n\t"
133       "lh     %[tmp32_1],     10(%[tmpvector])                \n\t"
134       "lh     %[tmp32_2],     12(%[tmpvector])                \n\t"
135       "lh     %[tmp32_3],     14(%[tmpvector])                \n\t"
136 
137       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
138       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
139       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
140       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
141 
142       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
143       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
144       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
145       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
146       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
147       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
148       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
149       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
150 
151       "lh     %[tmp32_0],     16(%[tmpvector])                \n\t"
152       "lh     %[tmp32_1],     18(%[tmpvector])                \n\t"
153       "lh     %[tmp32_2],     20(%[tmpvector])                \n\t"
154       "lh     %[tmp32_3],     22(%[tmpvector])                \n\t"
155 
156       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
157       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
158       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
159       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
160 
161       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
162       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
163       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
164       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
165       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
166       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
167       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
168       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
169 
170       "lh     %[tmp32_0],     24(%[tmpvector])                \n\t"
171       "lh     %[tmp32_1],     26(%[tmpvector])                \n\t"
172       "lh     %[tmp32_2],     28(%[tmpvector])                \n\t"
173       "lh     %[tmp32_3],     30(%[tmpvector])                \n\t"
174 
175       "abs    %[tmp32_0],     %[tmp32_0]                      \n\t"
176       "abs    %[tmp32_1],     %[tmp32_1]                      \n\t"
177       "abs    %[tmp32_2],     %[tmp32_2]                      \n\t"
178       "abs    %[tmp32_3],     %[tmp32_3]                      \n\t"
179 
180       "slt    %[r],           %[totMax],      %[tmp32_0]      \n\t"
181       "movn   %[totMax],      %[tmp32_0],     %[r]            \n\t"
182       "slt    %[r1],          %[totMax],      %[tmp32_1]      \n\t"
183       "movn   %[totMax],      %[tmp32_1],     %[r1]           \n\t"
184       "slt    %[r2],          %[totMax],      %[tmp32_2]      \n\t"
185       "movn   %[totMax],      %[tmp32_2],     %[r2]           \n\t"
186       "slt    %[r3],          %[totMax],      %[tmp32_3]      \n\t"
187       "movn   %[totMax],      %[tmp32_3],     %[r3]           \n\t"
188 
189       "addiu  %[tmpvector],   %[tmpvector],   32              \n\t"
190       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
191         [tmp32_2] "=&r" (tmp32_2), [tmp32_3] "=&r" (tmp32_3),
192         [totMax] "+r" (totMax), [r] "=&r" (r), [tmpvector] "+r" (tmpvector),
193         [r1] "=&r" (r1), [r2] "=&r" (r2), [r3] "=&r" (r3)
194       :
195       : "memory"
196     );
197   }
198   loop_size = length & 0xf;
199   for (i = 0; i < loop_size; i++) {
200     __asm__ volatile (
201       "lh         %[tmp32_0],     0(%[tmpvector])             \n\t"
202       "addiu      %[tmpvector],   %[tmpvector],    2          \n\t"
203       "abs        %[tmp32_0],     %[tmp32_0]                  \n\t"
204       "slt        %[tmp32_1],     %[totMax],       %[tmp32_0] \n\t"
205       "movn       %[totMax],      %[tmp32_0],      %[tmp32_1] \n\t"
206       : [tmp32_0] "=&r" (tmp32_0), [tmp32_1] "=&r" (tmp32_1),
207         [tmpvector] "+r" (tmpvector), [totMax] "+r" (totMax)
208       :
209       : "memory"
210     );
211   }
212 
213   __asm__ volatile (
214     "slt    %[r],       %[v16MaxMax],   %[totMax]   \n\t"
215     "movn   %[totMax],  %[v16MaxMax],   %[r]        \n\t"
216     : [totMax] "+r" (totMax), [r] "=&r" (r)
217     : [v16MaxMax] "r" (v16MaxMax)
218   );
219 #endif  // #if defined(MIPS_DSP_R1)
220   return (int16_t)totMax;
221 }
222 
223 #if defined(MIPS_DSP_R1_LE)
224 // Maximum absolute value of word32 vector. Version for MIPS platform.
WebRtcSpl_MaxAbsValueW32_mips(const int32_t * vector,int length)225 int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, int length) {
226   // Use uint32_t for the local variables, to accommodate the return value
227   // of abs(0x80000000), which is 0x80000000.
228 
229   uint32_t absolute = 0, maximum = 0;
230   int tmp1 = 0, max_value = 0x7fffffff;
231 
232   if (vector == NULL || length <= 0) {
233     return -1;
234   }
235 
236   __asm__ volatile (
237     ".set push                                                        \n\t"
238     ".set noreorder                                                   \n\t"
239 
240    "1:                                                                \n\t"
241     "lw         %[absolute],      0(%[vector])                        \n\t"
242     "absq_s.w   %[absolute],      %[absolute]                         \n\t"
243     "addiu      %[length],        %[length],          -1              \n\t"
244     "slt        %[tmp1],          %[maximum],         %[absolute]     \n\t"
245     "movn       %[maximum],       %[absolute],        %[tmp1]         \n\t"
246     "bgtz       %[length],        1b                                  \n\t"
247     " addiu     %[vector],        %[vector],          4               \n\t"
248     "slt        %[tmp1],          %[max_value],       %[maximum]      \n\t"
249     "movn       %[maximum],       %[max_value],       %[tmp1]         \n\t"
250 
251     ".set pop                                                         \n\t"
252 
253     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [absolute] "+r" (absolute)
254     : [vector] "r" (vector), [length] "r" (length), [max_value] "r" (max_value)
255     : "memory"
256   );
257 
258   return (int32_t)maximum;
259 }
260 #endif  // #if defined(MIPS_DSP_R1_LE)
261 
262 // Maximum value of word16 vector. Version for MIPS platform.
WebRtcSpl_MaxValueW16_mips(const int16_t * vector,int length)263 int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, int length) {
264   int16_t maximum = WEBRTC_SPL_WORD16_MIN;
265   int tmp1;
266   int16_t value;
267 
268   if (vector == NULL || length <= 0) {
269     return maximum;
270   }
271 
272   __asm__ volatile (
273     ".set push                                                        \n\t"
274     ".set noreorder                                                   \n\t"
275 
276    "1:                                                                \n\t"
277     "lh         %[value],         0(%[vector])                        \n\t"
278     "addiu      %[length],        %[length],          -1              \n\t"
279     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
280     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
281     "bgtz       %[length],        1b                                  \n\t"
282     " addiu     %[vector],        %[vector],          2               \n\t"
283     ".set pop                                                         \n\t"
284 
285     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
286     : [vector] "r" (vector), [length] "r" (length)
287     : "memory"
288   );
289 
290   return maximum;
291 }
292 
293 // Maximum value of word32 vector. Version for MIPS platform.
WebRtcSpl_MaxValueW32_mips(const int32_t * vector,int length)294 int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, int length) {
295   int32_t maximum = WEBRTC_SPL_WORD32_MIN;
296   int tmp1, value;
297 
298   if (vector == NULL || length <= 0) {
299     return maximum;
300   }
301 
302   __asm__ volatile (
303     ".set push                                                        \n\t"
304     ".set noreorder                                                   \n\t"
305 
306    "1:                                                                \n\t"
307     "lw         %[value],         0(%[vector])                        \n\t"
308     "addiu      %[length],        %[length],          -1              \n\t"
309     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
310     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
311     "bgtz       %[length],        1b                                  \n\t"
312     " addiu     %[vector],        %[vector],          4               \n\t"
313 
314     ".set pop                                                         \n\t"
315 
316     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
317     : [vector] "r" (vector), [length] "r" (length)
318     : "memory"
319   );
320 
321   return maximum;
322 }
323 
324 // Minimum value of word16 vector. Version for MIPS platform.
WebRtcSpl_MinValueW16_mips(const int16_t * vector,int length)325 int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, int length) {
326   int16_t minimum = WEBRTC_SPL_WORD16_MAX;
327   int tmp1;
328   int16_t value;
329 
330   if (vector == NULL || length <= 0) {
331     return minimum;
332   }
333 
334   __asm__ volatile (
335     ".set push                                                        \n\t"
336     ".set noreorder                                                   \n\t"
337 
338    "1:                                                                \n\t"
339     "lh         %[value],         0(%[vector])                        \n\t"
340     "addiu      %[length],        %[length],          -1              \n\t"
341     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
342     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
343     "bgtz       %[length],        1b                                  \n\t"
344     " addiu     %[vector],        %[vector],          2               \n\t"
345 
346     ".set pop                                                         \n\t"
347 
348     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
349     : [vector] "r" (vector), [length] "r" (length)
350     : "memory"
351   );
352 
353   return minimum;
354 }
355 
356 // Minimum value of word32 vector. Version for MIPS platform.
WebRtcSpl_MinValueW32_mips(const int32_t * vector,int length)357 int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, int length) {
358   int32_t minimum = WEBRTC_SPL_WORD32_MAX;
359   int tmp1, value;
360 
361   if (vector == NULL || length <= 0) {
362     return minimum;
363   }
364 
365   __asm__ volatile (
366     ".set push                                                        \n\t"
367     ".set noreorder                                                   \n\t"
368 
369    "1:                                                                \n\t"
370     "lw         %[value],         0(%[vector])                        \n\t"
371     "addiu      %[length],        %[length],          -1              \n\t"
372     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
373     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
374     "bgtz       %[length],        1b                                  \n\t"
375     " addiu     %[vector],        %[vector],          4               \n\t"
376 
377     ".set pop                                                         \n\t"
378 
379     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
380     : [vector] "r" (vector), [length] "r" (length)
381     : "memory"
382   );
383 
384   return minimum;
385 }
386