• 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 "rtc_base/checks.h"
20 #include "common_audio/signal_processing/include/signal_processing_library.h"
21 
22 // Maximum absolute value of word16 vector.
WebRtcSpl_MaxAbsValueW16_mips(const int16_t * vector,size_t length)23 int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, size_t length) {
24   int32_t totMax = 0;
25   int32_t tmp32_0, tmp32_1, tmp32_2, tmp32_3;
26   size_t i, loop_size;
27 
28   RTC_DCHECK_GT(length, 0);
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,size_t length)225 int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, size_t 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   RTC_DCHECK_GT(length, 0);
233 
234   __asm__ volatile (
235     ".set push                                                        \n\t"
236     ".set noreorder                                                   \n\t"
237 
238    "1:                                                                \n\t"
239     "lw         %[absolute],      0(%[vector])                        \n\t"
240     "absq_s.w   %[absolute],      %[absolute]                         \n\t"
241     "addiu      %[length],        %[length],          -1              \n\t"
242     "slt        %[tmp1],          %[maximum],         %[absolute]     \n\t"
243     "movn       %[maximum],       %[absolute],        %[tmp1]         \n\t"
244     "bgtz       %[length],        1b                                  \n\t"
245     " addiu     %[vector],        %[vector],          4               \n\t"
246     "slt        %[tmp1],          %[max_value],       %[maximum]      \n\t"
247     "movn       %[maximum],       %[max_value],       %[tmp1]         \n\t"
248 
249     ".set pop                                                         \n\t"
250 
251     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [absolute] "+r" (absolute)
252     : [vector] "r" (vector), [length] "r" (length), [max_value] "r" (max_value)
253     : "memory"
254   );
255 
256   return (int32_t)maximum;
257 }
258 #endif  // #if defined(MIPS_DSP_R1_LE)
259 
260 // Maximum value of word16 vector. Version for MIPS platform.
WebRtcSpl_MaxValueW16_mips(const int16_t * vector,size_t length)261 int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, size_t length) {
262   int16_t maximum = WEBRTC_SPL_WORD16_MIN;
263   int tmp1;
264   int16_t value;
265 
266   RTC_DCHECK_GT(length, 0);
267 
268   __asm__ volatile (
269     ".set push                                                        \n\t"
270     ".set noreorder                                                   \n\t"
271 
272    "1:                                                                \n\t"
273     "lh         %[value],         0(%[vector])                        \n\t"
274     "addiu      %[length],        %[length],          -1              \n\t"
275     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
276     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
277     "bgtz       %[length],        1b                                  \n\t"
278     " addiu     %[vector],        %[vector],          2               \n\t"
279     ".set pop                                                         \n\t"
280 
281     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
282     : [vector] "r" (vector), [length] "r" (length)
283     : "memory"
284   );
285 
286   return maximum;
287 }
288 
289 // Maximum value of word32 vector. Version for MIPS platform.
WebRtcSpl_MaxValueW32_mips(const int32_t * vector,size_t length)290 int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, size_t length) {
291   int32_t maximum = WEBRTC_SPL_WORD32_MIN;
292   int tmp1, value;
293 
294   RTC_DCHECK_GT(length, 0);
295 
296   __asm__ volatile (
297     ".set push                                                        \n\t"
298     ".set noreorder                                                   \n\t"
299 
300    "1:                                                                \n\t"
301     "lw         %[value],         0(%[vector])                        \n\t"
302     "addiu      %[length],        %[length],          -1              \n\t"
303     "slt        %[tmp1],          %[maximum],         %[value]        \n\t"
304     "movn       %[maximum],       %[value],           %[tmp1]         \n\t"
305     "bgtz       %[length],        1b                                  \n\t"
306     " addiu     %[vector],        %[vector],          4               \n\t"
307 
308     ".set pop                                                         \n\t"
309 
310     : [tmp1] "=&r" (tmp1), [maximum] "+r" (maximum), [value] "=&r" (value)
311     : [vector] "r" (vector), [length] "r" (length)
312     : "memory"
313   );
314 
315   return maximum;
316 }
317 
318 // Minimum value of word16 vector. Version for MIPS platform.
WebRtcSpl_MinValueW16_mips(const int16_t * vector,size_t length)319 int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, size_t length) {
320   int16_t minimum = WEBRTC_SPL_WORD16_MAX;
321   int tmp1;
322   int16_t value;
323 
324   RTC_DCHECK_GT(length, 0);
325 
326   __asm__ volatile (
327     ".set push                                                        \n\t"
328     ".set noreorder                                                   \n\t"
329 
330    "1:                                                                \n\t"
331     "lh         %[value],         0(%[vector])                        \n\t"
332     "addiu      %[length],        %[length],          -1              \n\t"
333     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
334     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
335     "bgtz       %[length],        1b                                  \n\t"
336     " addiu     %[vector],        %[vector],          2               \n\t"
337 
338     ".set pop                                                         \n\t"
339 
340     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
341     : [vector] "r" (vector), [length] "r" (length)
342     : "memory"
343   );
344 
345   return minimum;
346 }
347 
348 // Minimum value of word32 vector. Version for MIPS platform.
WebRtcSpl_MinValueW32_mips(const int32_t * vector,size_t length)349 int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, size_t length) {
350   int32_t minimum = WEBRTC_SPL_WORD32_MAX;
351   int tmp1, value;
352 
353   RTC_DCHECK_GT(length, 0);
354 
355   __asm__ volatile (
356     ".set push                                                        \n\t"
357     ".set noreorder                                                   \n\t"
358 
359    "1:                                                                \n\t"
360     "lw         %[value],         0(%[vector])                        \n\t"
361     "addiu      %[length],        %[length],          -1              \n\t"
362     "slt        %[tmp1],          %[value],           %[minimum]      \n\t"
363     "movn       %[minimum],       %[value],           %[tmp1]         \n\t"
364     "bgtz       %[length],        1b                                  \n\t"
365     " addiu     %[vector],        %[vector],          4               \n\t"
366 
367     ".set pop                                                         \n\t"
368 
369     : [tmp1] "=&r" (tmp1), [minimum] "+r" (minimum), [value] "=&r" (value)
370     : [vector] "r" (vector), [length] "r" (length)
371     : "memory"
372   );
373 
374   return minimum;
375 }
376