xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrwb/enc/inc/basic_op.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  ** Copyright 2003-2010, VisualOn, Inc.
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 
17 
18 #ifndef __BASIC_OP_H__
19 #define __BASIC_OP_H__
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "typedef.h"
24 
25 #define MAX_32 (Word32)0x7fffffffL
26 #define MIN_32 (Word32)0x80000000L
27 
28 #define MAX_16 ((Word16)+32767)   /* 0x7fff */
29 #define MIN_16 ((Word16)-32768)   /* 0x8000 */
30 
31 
32 #define  static_vo  static __inline
33 
34 #define saturate(L_var1) (((L_var1) > 0X00007fffL) ? (MAX_16): (((L_var1) < (Word32) 0xffff8000L) ? (MIN_16): ((L_var1) & 0xffff)))
35 
36 #define abs_s(x)       ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16))  /* Short abs,           1   */
37 #define L_deposit_h(x) (((Word32)(x)) << 16)                                               /* 16 bit var1 -> MSB,     2 */
38 #define L_deposit_l(x) ((Word32)(x))                                                       /* 16 bit var1 -> LSB,     2 */
39 #define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)                  /* Long abs,              3*/
40 #define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1))))                   /* Short negate,        1*/
41 #define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))                 /* Long negate,     2*/
42 
43 
44 #define extract_h(a)            ((Word16)((a) >> 16))
45 #define extract_l(x)            (Word16)((x))
46 #define add1(a,b)               ((a) + (b))
47 #define vo_L_msu(a,b,c)         ((a) - (((b) * (c)) << 1))
48 #define vo_mult32(a, b)         ((a) * (b))
49 #define vo_mult(a,b)            (((a) * (b)) >> 15)
50 #define vo_L_mult(a,b)          (((a) * (b)) << 1)
51 #define vo_shr_r(var1, var2)    (((var1)+((Word16)(1L<<((var2)-1))))>>(var2))
52 #define vo_sub(a,b)             ((a) - (b))
53 #define vo_L_deposit_h(a)       ((Word32)((a) << 16))
54 #define vo_round(a)             ((((a) >> 15) + 1) >> 1)
55 #define vo_extract_l(a)         ((Word16)(a))
56 #define vo_L_add(a,b)           ((a) + (b))
57 #define vo_L_sub(a,b)           ((a) - (b))
58 #define vo_mult_r(a,b)          (((( (a) * (b) ) >> 14) + 1 ) >> 1 )
59 #define vo_negate(a)            (-(a))
60 #define vo_L_shr_r(L_var1, var2) (((L_var1)+((Word32)(1L<<((var2)-1))))>>(var2))
61 
62 
63 /*___________________________________________________________________________
64 |                                                                           |
65 |   Prototypes for basic arithmetic operators                               |
66 |___________________________________________________________________________|
67 */
68 static_vo Word16 add (Word16 var1, Word16 var2);                /* Short add,1 */
69 static_vo Word16 sub (Word16 var1, Word16 var2);                /* Short sub,1 */
70 static_vo Word16 shl (Word16 var1, Word16 var2);                                /* Short shift left,    1   */
71 static_vo Word16 shr (Word16 var1, Word16 var2);                                /* Short shift right,   1   */
72 static_vo Word16 mult (Word16 var1, Word16 var2);                               /* Short mult,          1   */
73 static_vo Word32 L_mult (Word16 var1, Word16 var2);                             /* Long mult,           1   */
74 static_vo Word16 voround (Word32 L_var1);                                       /* Round,               1   */
75 static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);               /* Mac,  1  */
76 static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);           /* Msu,  1  */
77 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2);              /* Long add,        2 */
78 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2);              /* Long sub,        2 */
79 static_vo Word16 mult_r (Word16 var1, Word16 var2);                 /* Mult with round, 2 */
80 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2);                    /* var2 > 0*/
81 static_vo Word32 L_shl (Word32 L_var1, Word16 var2);                /* Long shift left, 2 */
82 static_vo Word32 L_shr (Word32 L_var1, Word16 var2);                /* Long shift right, 2*/
83 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2);              /* Long shift right with round,  3   */
84 static_vo Word16 norm_s (Word16 var1);                          /* Short norm,           15  */
85 static_vo Word16 div_s (Word16 var1, Word16 var2);              /* Short division,       18  */
86 static_vo Word16 norm_l (Word32 L_var1);                        /* Long norm,            30  */
87 
88 /*___________________________________________________________________________
89 |                                                                           |
90 |   Functions                                                               |
91 |___________________________________________________________________________|
92 */
93 /*___________________________________________________________________________
94 |                                                                           |
95 |   Function Name : add                                                     |
96 |                                                                           |
97 |   Purpose :                                                               |
98 |                                                                           |
99 |    Performs the addition (var1+var2) with overflow control and saturation;|
100 |    the 16 bit result is set at +32767 when overflow occurs or at -32768   |
101 |    when underflow occurs.                                                 |
102 |                                                                           |
103 |   Complexity weight : 1                                                   |
104 |                                                                           |
105 |   Inputs :                                                                |
106 |                                                                           |
107 |    var1                                                                   |
108 |             16 bit short signed integer (Word16) whose value falls in the |
109 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
110 |                                                                           |
111 |    var2                                                                   |
112 |             16 bit short signed integer (Word16) whose value falls in the |
113 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
114 |                                                                           |
115 |   Outputs :                                                               |
116 |                                                                           |
117 |    none                                                                   |
118 |                                                                           |
119 |   Return Value :                                                          |
120 |                                                                           |
121 |    var_out                                                                |
122 |             16 bit short signed integer (Word16) whose value falls in the |
123 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
124 |___________________________________________________________________________|
125 */
add(Word16 var1,Word16 var2)126 static_vo Word16 add (Word16 var1, Word16 var2)
127 {
128     Word16 var_out;
129     Word32 L_sum;
130     L_sum = (Word32) var1 + var2;
131     var_out = saturate (L_sum);
132     return (var_out);
133 }
134 
135 /*___________________________________________________________________________
136 |                                                                           |
137 |   Function Name : sub                                                     |
138 |                                                                           |
139 |   Purpose :                                                               |
140 |                                                                           |
141 |    Performs the subtraction (var1+var2) with overflow control and satu-   |
142 |    ration; the 16 bit result is set at +32767 when overflow occurs or at  |
143 |    -32768 when underflow occurs.                                          |
144 |                                                                           |
145 |   Complexity weight : 1                                                   |
146 |                                                                           |
147 |   Inputs :                                                                |
148 |                                                                           |
149 |    var1                                                                   |
150 |             16 bit short signed integer (Word16) whose value falls in the |
151 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
152 |                                                                           |
153 |    var2                                                                   |
154 |             16 bit short signed integer (Word16) whose value falls in the |
155 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
156 |                                                                           |
157 |   Outputs :                                                               |
158 |                                                                           |
159 |    none                                                                   |
160 |                                                                           |
161 |   Return Value :                                                          |
162 |                                                                           |
163 |    var_out                                                                |
164 |             16 bit short signed integer (Word16) whose value falls in the |
165 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
166 |___________________________________________________________________________|
167 */
168 
sub(Word16 var1,Word16 var2)169 static_vo Word16 sub (Word16 var1, Word16 var2)
170 {
171     Word16 var_out;
172     Word32 L_diff;
173     L_diff = (Word32) var1 - var2;
174     var_out = saturate (L_diff);
175     return (var_out);
176 }
177 
178 /*___________________________________________________________________________
179 |                                                                           |
180 |   Function Name : shl                                                     |
181 |                                                                           |
182 |   Purpose :                                                               |
183 |                                                                           |
184 |   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
185 |   the var2 LSB of the result. If var2 is negative, arithmetically shift   |
186 |   var1 right by -var2 with sign extension. Saturate the result in case of |
187 |   underflows or overflows.                                                |
188 |                                                                           |
189 |   Complexity weight : 1                                                   |
190 |                                                                           |
191 |   Inputs :                                                                |
192 |                                                                           |
193 |    var1                                                                   |
194 |             16 bit short signed integer (Word16) whose value falls in the |
195 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
196 |                                                                           |
197 |    var2                                                                   |
198 |             16 bit short signed integer (Word16) whose value falls in the |
199 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
200 |                                                                           |
201 |   Outputs :                                                               |
202 |                                                                           |
203 |    none                                                                   |
204 |                                                                           |
205 |   Return Value :                                                          |
206 |                                                                           |
207 |    var_out                                                                |
208 |             16 bit short signed integer (Word16) whose value falls in the |
209 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
210 |___________________________________________________________________________|
211 */
212 
shl(Word16 var1,Word16 var2)213 static_vo Word16 shl (Word16 var1, Word16 var2)
214 {
215     Word16 var_out;
216     Word32 result;
217     if (var2 < 0)
218     {
219         if (var2 < -16)
220             var2 = -16;
221         var_out = var1 >> ((Word16)-var2);
222     }
223     else
224     {
225         if (var2 > 15 && var1 != 0)
226         {
227             var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
228         }
229         else
230         {
231             result = (Word32) var1 *((Word32) 1 << var2);
232             if ((result != (Word32) ((Word16) result))) {
233                 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
234             } else {
235                 var_out = extract_l (result);
236             }
237         }
238     }
239     return (var_out);
240 }
241 
242 /*___________________________________________________________________________
243 |                                                                           |
244 |   Function Name : shr                                                     |
245 |                                                                           |
246 |   Purpose :                                                               |
247 |                                                                           |
248 |   Arithmetically shift the 16 bit input var1 right var2 positions with    |
249 |   sign extension. If var2 is negative, arithmetically shift var1 left by  |
250 |   -var2 with sign extension. Saturate the result in case of underflows or |
251 |   overflows.                                                              |
252 |                                                                           |
253 |   Complexity weight : 1                                                   |
254 |                                                                           |
255 |   Inputs :                                                                |
256 |                                                                           |
257 |    var1                                                                   |
258 |             16 bit short signed integer (Word16) whose value falls in the |
259 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
260 |                                                                           |
261 |    var2                                                                   |
262 |             16 bit short signed integer (Word16) whose value falls in the |
263 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
264 |                                                                           |
265 |   Outputs :                                                               |
266 |                                                                           |
267 |    none                                                                   |
268 |                                                                           |
269 |   Return Value :                                                          |
270 |                                                                           |
271 |    var_out                                                                |
272 |             16 bit short signed integer (Word16) whose value falls in the |
273 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
274 |___________________________________________________________________________|
275 */
276 
shr(Word16 var1,Word16 var2)277 static_vo Word16 shr (Word16 var1, Word16 var2)
278 {
279     Word16 var_out;
280     if (var2 < 0)
281     {
282         if (var2 < -16)
283             var2 = -16;
284         var_out = shl(var1, (Word16)-var2);
285     }
286     else
287     {
288         if (var2 >= 15)
289         {
290             var_out = (Word16)((var1 < 0) ? -1 : 0);
291         }
292         else
293         {
294             if (var1 < 0)
295             {
296                 var_out = (Word16)(~((~var1) >> var2));
297             }
298             else
299             {
300                 var_out = (Word16)(var1 >> var2);
301             }
302         }
303     }
304     return (var_out);
305 }
306 
307 /*___________________________________________________________________________
308 |                                                                           |
309 |   Function Name : mult                                                    |
310 |                                                                           |
311 |   Purpose :                                                               |
312 |                                                                           |
313 |    Performs the multiplication of var1 by var2 and gives a 16 bit result  |
314 |    which is scaled i.e.:                                                  |
315 |             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |
316 |             mult(-32768,-32768) = 32767.                                  |
317 |                                                                           |
318 |   Complexity weight : 1                                                   |
319 |                                                                           |
320 |   Inputs :                                                                |
321 |                                                                           |
322 |    var1                                                                   |
323 |             16 bit short signed integer (Word16) whose value falls in the |
324 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
325 |                                                                           |
326 |    var2                                                                   |
327 |             16 bit short signed integer (Word16) whose value falls in the |
328 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
329 |                                                                           |
330 |   Outputs :                                                               |
331 |                                                                           |
332 |    none                                                                   |
333 |                                                                           |
334 |   Return Value :                                                          |
335 |                                                                           |
336 |    var_out                                                                |
337 |             16 bit short signed integer (Word16) whose value falls in the |
338 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
339 |___________________________________________________________________________|
340 */
341 
mult(Word16 var1,Word16 var2)342 static_vo Word16 mult (Word16 var1, Word16 var2)
343 {
344     Word16 var_out;
345     Word32 L_product;
346     L_product = (Word32) var1 *(Word32) var2;
347     L_product = (L_product & (Word32) 0xffff8000L) >> 15;
348     if (L_product & (Word32) 0x00010000L)
349         L_product = L_product | (Word32) 0xffff0000L;
350     var_out = saturate (L_product);
351     return (var_out);
352 }
353 
354 /*___________________________________________________________________________
355 |                                                                           |
356 |   Function Name : L_mult                                                  |
357 |                                                                           |
358 |   Purpose :                                                               |
359 |                                                                           |
360 |   L_mult is the 32 bit result of the multiplication of var1 times var2    |
361 |   with one shift left i.e.:                                               |
362 |        L_mult(var1,var2) = L_shl((var1 times var2),1) and                   |
363 |        L_mult(-32768,-32768) = 2147483647.                                |
364 |                                                                           |
365 |   Complexity weight : 1                                                   |
366 |                                                                           |
367 |   Inputs :                                                                |
368 |                                                                           |
369 |    var1                                                                   |
370 |             16 bit short signed integer (Word16) whose value falls in the |
371 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
372 |                                                                           |
373 |    var2                                                                   |
374 |             16 bit short signed integer (Word16) whose value falls in the |
375 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
376 |                                                                           |
377 |   Outputs :                                                               |
378 |                                                                           |
379 |    none                                                                   |
380 |                                                                           |
381 |   Return Value :                                                          |
382 |                                                                           |
383 |    L_var_out                                                              |
384 |             32 bit long signed integer (Word32) whose value falls in the  |
385 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
386 |___________________________________________________________________________|
387 */
388 
L_mult(Word16 var1,Word16 var2)389 static_vo Word32 L_mult (Word16 var1, Word16 var2)
390 {
391     Word32 L_var_out;
392     L_var_out = (Word32) var1 *(Word32) var2;
393     if (L_var_out != (Word32) 0x40000000L)
394     {
395         L_var_out *= 2;
396     }
397     else
398     {
399         L_var_out = MAX_32;
400     }
401     return (L_var_out);
402 }
403 
404 /*___________________________________________________________________________
405 |                                                                           |
406 |   Function Name : round                                                   |
407 |                                                                           |
408 |   Purpose :                                                               |
409 |                                                                           |
410 |   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |
411 |   with saturation. Shift the resulting bits right by 16 and return the 16 |
412 |   bit number:                                                             |
413 |               round(L_var1) = extract_h(L_add(L_var1,32768))              |
414 |                                                                           |
415 |   Complexity weight : 1                                                   |
416 |                                                                           |
417 |   Inputs :                                                                |
418 |                                                                           |
419 |    L_var1                                                                 |
420 |             32 bit long signed integer (Word32 ) whose value falls in the |
421 |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
422 |                                                                           |
423 |   Outputs :                                                               |
424 |                                                                           |
425 |    none                                                                   |
426 |                                                                           |
427 |   Return Value :                                                          |
428 |                                                                           |
429 |    var_out                                                                |
430 |             16 bit short signed integer (Word16) whose value falls in the |
431 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
432 |___________________________________________________________________________|
433 */
434 
voround(Word32 L_var1)435 static_vo Word16 voround (Word32 L_var1)
436 {
437     Word16 var_out;
438     Word32 L_rounded;
439     L_rounded = L_add (L_var1, (Word32) 0x00008000L);
440     var_out = extract_h (L_rounded);
441     return (var_out);
442 }
443 
444 /*___________________________________________________________________________
445 |                                                                           |
446 |   Function Name : L_mac                                                   |
447 |                                                                           |
448 |   Purpose :                                                               |
449 |                                                                           |
450 |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
451 |   result to L_var3 with saturation, return a 32 bit result:               |
452 |        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |
453 |                                                                           |
454 |   Complexity weight : 1                                                   |
455 |                                                                           |
456 |   Inputs :                                                                |
457 |                                                                           |
458 |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
459 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
460 |                                                                           |
461 |    var1                                                                   |
462 |             16 bit short signed integer (Word16) whose value falls in the |
463 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
464 |                                                                           |
465 |    var2                                                                   |
466 |             16 bit short signed integer (Word16) whose value falls in the |
467 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
468 |                                                                           |
469 |   Outputs :                                                               |
470 |                                                                           |
471 |    none                                                                   |
472 |                                                                           |
473 |   Return Value :                                                          |
474 |                                                                           |
475 |    L_var_out                                                              |
476 |             32 bit long signed integer (Word32) whose value falls in the  |
477 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
478 |___________________________________________________________________________|
479 */
480 
L_mac(Word32 L_var3,Word16 var1,Word16 var2)481 static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
482 {
483     Word32 L_var_out;
484     Word32 L_product;
485     L_product = ((var1 * var2) << 1);
486     L_var_out = L_add (L_var3, L_product);
487     return (L_var_out);
488 }
489 
490 /*___________________________________________________________________________
491 |                                                                           |
492 |   Function Name : L_msu                                                   |
493 |                                                                           |
494 |   Purpose :                                                               |
495 |                                                                           |
496 |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
497 |   bit result to L_var3 with saturation, return a 32 bit result:           |
498 |        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |
499 |                                                                           |
500 |   Complexity weight : 1                                                   |
501 |                                                                           |
502 |   Inputs :                                                                |
503 |                                                                           |
504 |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
505 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
506 |                                                                           |
507 |    var1                                                                   |
508 |             16 bit short signed integer (Word16) whose value falls in the |
509 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
510 |                                                                           |
511 |    var2                                                                   |
512 |             16 bit short signed integer (Word16) whose value falls in the |
513 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
514 |                                                                           |
515 |   Outputs :                                                               |
516 |                                                                           |
517 |    none                                                                   |
518 |                                                                           |
519 |   Return Value :                                                          |
520 |                                                                           |
521 |    L_var_out                                                              |
522 |             32 bit long signed integer (Word32) whose value falls in the  |
523 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
524 |___________________________________________________________________________|
525 */
526 
L_msu(Word32 L_var3,Word16 var1,Word16 var2)527 static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
528 {
529     Word32 L_var_out;
530     Word32 L_product;
531     L_product = (var1 * var2)<<1;
532     L_var_out = L_sub (L_var3, L_product);
533     return (L_var_out);
534 }
535 
536 /*___________________________________________________________________________
537 |                                                                           |
538 |   Function Name : L_add                                                   |
539 |                                                                           |
540 |   Purpose :                                                               |
541 |                                                                           |
542 |   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |
543 |   overflow control and saturation; the result is set at +2147483647 when  |
544 |   overflow occurs or at -2147483648 when underflow occurs.                |
545 |                                                                           |
546 |   Complexity weight : 2                                                   |
547 |                                                                           |
548 |   Inputs :                                                                |
549 |                                                                           |
550 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
551 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
552 |                                                                           |
553 |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
554 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
555 |                                                                           |
556 |   Outputs :                                                               |
557 |                                                                           |
558 |    none                                                                   |
559 |                                                                           |
560 |   Return Value :                                                          |
561 |                                                                           |
562 |    L_var_out                                                              |
563 |             32 bit long signed integer (Word32) whose value falls in the  |
564 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
565 |___________________________________________________________________________|
566 */
567 
568 __attribute__((no_sanitize("integer")))
L_add(Word32 L_var1,Word32 L_var2)569 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
570 {
571     Word32 L_var_out;
572     if (__builtin_add_overflow(L_var1, L_var2, &L_var_out))
573     {
574         // saturating...
575         L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
576     }
577     return (L_var_out);
578 }
579 
580 /*___________________________________________________________________________
581 |                                                                           |
582 |   Function Name : L_sub                                                   |
583 |                                                                           |
584 |   Purpose :                                                               |
585 |                                                                           |
586 |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
587 |   overflow control and saturation; the result is set at +2147483647 when  |
588 |   overflow occurs or at -2147483648 when underflow occurs.                |
589 |                                                                           |
590 |   Complexity weight : 2                                                   |
591 |                                                                           |
592 |   Inputs :                                                                |
593 |                                                                           |
594 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
595 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
596 |                                                                           |
597 |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
598 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
599 |                                                                           |
600 |   Outputs :                                                               |
601 |                                                                           |
602 |    none                                                                   |
603 |                                                                           |
604 |   Return Value :                                                          |
605 |                                                                           |
606 |    L_var_out                                                              |
607 |             32 bit long signed integer (Word32) whose value falls in the  |
608 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
609 |___________________________________________________________________________|
610 */
611 
612 __attribute__((no_sanitize("integer")))
L_sub(Word32 L_var1,Word32 L_var2)613 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
614 {
615     Word32 L_var_out;
616     if (__builtin_sub_overflow(L_var1, L_var2, &L_var_out))
617     {
618         // saturating...
619         L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
620     }
621     return (L_var_out);
622 }
623 
624 
625 /*___________________________________________________________________________
626 |                                                                           |
627 |   Function Name : mult_r                                                  |
628 |                                                                           |
629 |   Purpose :                                                               |
630 |                                                                           |
631 |   Same as mult with rounding, i.e.:                                       |
632 |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
633 |     mult_r(-32768,-32768) = 32767.                                        |
634 |                                                                           |
635 |   Complexity weight : 2                                                   |
636 |                                                                           |
637 |   Inputs :                                                                |
638 |                                                                           |
639 |    var1                                                                   |
640 |             16 bit short signed integer (Word16) whose value falls in the |
641 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
642 |                                                                           |
643 |    var2                                                                   |
644 |             16 bit short signed integer (Word16) whose value falls in the |
645 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
646 |                                                                           |
647 |   Outputs :                                                               |
648 |                                                                           |
649 |    none                                                                   |
650 |                                                                           |
651 |   Return Value :                                                          |
652 |                                                                           |
653 |    var_out                                                                |
654 |             16 bit short signed integer (Word16) whose value falls in the |
655 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
656 |___________________________________________________________________________|
657 */
658 
mult_r(Word16 var1,Word16 var2)659 static_vo Word16 mult_r (Word16 var1, Word16 var2)
660 {
661     Word16 var_out;
662     Word32 L_product_arr;
663     L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
664     L_product_arr += (Word32) 0x00004000L;      /* round */
665     L_product_arr &= (Word32) 0xffff8000L;
666     L_product_arr >>= 15;       /* shift */
667     if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
668     {
669         L_product_arr |= (Word32) 0xffff0000L;
670     }
671     var_out = saturate (L_product_arr);
672     return (var_out);
673 }
674 
675 /*___________________________________________________________________________
676 |                                                                           |
677 |   Function Name : L_shl                                                   |
678 |                                                                           |
679 |   Purpose :                                                               |
680 |                                                                           |
681 |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
682 |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
683 |   shift L_var1 right by -var2 with sign extension. Saturate the result in |
684 |   case of underflows or overflows.                                        |
685 |                                                                           |
686 |   Complexity weight : 2                                                   |
687 |                                                                           |
688 |   Inputs :                                                                |
689 |                                                                           |
690 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
691 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
692 |                                                                           |
693 |    var2                                                                   |
694 |             16 bit short signed integer (Word16) whose value falls in the |
695 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
696 |                                                                           |
697 |   Outputs :                                                               |
698 |                                                                           |
699 |    none                                                                   |
700 |                                                                           |
701 |   Return Value :                                                          |
702 |                                                                           |
703 |    L_var_out                                                              |
704 |             32 bit long signed integer (Word32) whose value falls in the  |
705 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
706 |___________________________________________________________________________|
707 */
708 
L_shl(Word32 L_var1,Word16 var2)709 static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
710 {
711     Word32 L_var_out = 0L;
712     if (var2 <= 0)
713     {
714         if (var2 < -32)
715             var2 = -32;
716         L_var_out = (L_var1 >> (Word16)-var2);
717     }
718     else
719     {
720         for (; var2 > 0; var2--)
721         {
722             if (L_var1 > (Word32) 0X3fffffffL)
723             {
724                 L_var_out = MAX_32;
725                 break;
726             }
727             else
728             {
729                 if (L_var1 < (Word32) 0xc0000000L)
730                 {
731                     //Overflow = 1;
732                     L_var_out = MIN_32;
733                     break;
734                 }
735             }
736             L_var1 *= 2;
737             L_var_out = L_var1;
738         }
739     }
740     return (L_var_out);
741 }
742 
L_shl2(Word32 L_var1,Word16 var2)743 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
744 {
745     Word32 L_var_out = 0L;
746 
747     for (; var2 > 0; var2--)
748     {
749         if (L_var1 > (Word32) 0X3fffffffL)
750         {
751             L_var_out = MAX_32;
752             break;
753         }
754         else
755         {
756             if (L_var1 < (Word32) 0xc0000000L)
757             {
758                 L_var_out = MIN_32;
759                 break;
760             }
761         }
762         L_var1 *= 2 ;
763         L_var_out = L_var1;
764     }
765     return (L_var_out);
766 }
767 
768 /*___________________________________________________________________________
769 |                                                                           |
770 |   Function Name : L_shr                                                   |
771 |                                                                           |
772 |   Purpose :                                                               |
773 |                                                                           |
774 |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
775 |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
776 |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
777 |   in case of underflows or overflows.                                     |
778 |                                                                           |
779 |   Complexity weight : 2                                                   |
780 |                                                                           |
781 |   Inputs :                                                                |
782 |                                                                           |
783 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
784 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
785 |                                                                           |
786 |    var2                                                                   |
787 |             16 bit short signed integer (Word16) whose value falls in the |
788 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
789 |                                                                           |
790 |   Outputs :                                                               |
791 |                                                                           |
792 |    none                                                                   |
793 |                                                                           |
794 |   Return Value :                                                          |
795 |                                                                           |
796 |    L_var_out                                                              |
797 |             32 bit long signed integer (Word32) whose value falls in the  |
798 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
799 |___________________________________________________________________________|
800 */
801 
L_shr(Word32 L_var1,Word16 var2)802 static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
803 {
804     Word32 L_var_out;
805     if (var2 < 0)
806     {
807         if (var2 < -32)
808             var2 = -32;
809         L_var_out = L_shl2(L_var1, (Word16)-var2);
810     }
811     else
812     {
813         if (var2 >= 31)
814         {
815             L_var_out = (L_var1 < 0L) ? -1 : 0;
816         }
817         else
818         {
819             if (L_var1 < 0)
820             {
821                 L_var_out = ~((~L_var1) >> var2);
822             }
823             else
824             {
825                 L_var_out = L_var1 >> var2;
826             }
827         }
828     }
829     return (L_var_out);
830 }
831 
832 /*___________________________________________________________________________
833 |                                                                           |
834 |   Function Name : L_shr_r                                                 |
835 |                                                                           |
836 |   Purpose :                                                               |
837 |                                                                           |
838 |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
839 |   case of underflows or overflows :                                       |
840 |    - If var2 is greater than zero :                                       |
841 |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
842 |          is equal to zero                                                 |
843 |                     then                                                  |
844 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
845 |                     else                                                  |
846 |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
847 |    - If var2 is less than or equal to zero :                              |
848 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
849 |                                                                           |
850 |   Complexity weight : 3                                                   |
851 |                                                                           |
852 |   Inputs :                                                                |
853 |                                                                           |
854 |    L_var1                                                                 |
855 |             32 bit long signed integer (Word32) whose value falls in the  |
856 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
857 |                                                                           |
858 |    var2                                                                   |
859 |             16 bit short signed integer (Word16) whose value falls in the |
860 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
861 |                                                                           |
862 |   Outputs :                                                               |
863 |                                                                           |
864 |    none                                                                   |
865 |                                                                           |
866 |   Return Value :                                                          |
867 |                                                                           |
868 |    L_var_out                                                              |
869 |             32 bit long signed integer (Word32) whose value falls in the  |
870 |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
871 |___________________________________________________________________________|
872 */
873 
L_shr_r(Word32 L_var1,Word16 var2)874 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
875 {
876     Word32 L_var_out;
877     if (var2 > 31)
878     {
879         L_var_out = 0;
880     }
881     else
882     {
883         L_var_out = L_shr (L_var1, var2);
884         if (var2 > 0)
885         {
886             if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
887             {
888                 L_var_out++;
889             }
890         }
891     }
892     return (L_var_out);
893 }
894 
895 /*___________________________________________________________________________
896 |                                                                           |
897 |   Function Name : norm_s                                                  |
898 |                                                                           |
899 |   Purpose :                                                               |
900 |                                                                           |
901 |   Produces the number of left shift needed to normalize the 16 bit varia- |
902 |   ble var1 for positive values on the interval with minimum of 16384 and  |
903 |   maximum of 32767, and for negative values on the interval with minimum  |
904 |   of -32768 and maximum of -16384; in order to normalize the result, the  |
905 |   following operation must be done :                                      |
906 |                    norm_var1 = shl(var1,norm_s(var1)).                    |
907 |                                                                           |
908 |   Complexity weight : 15                                                  |
909 |                                                                           |
910 |   Inputs :                                                                |
911 |                                                                           |
912 |    var1                                                                   |
913 |             16 bit short signed integer (Word16) whose value falls in the |
914 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
915 |                                                                           |
916 |   Outputs :                                                               |
917 |                                                                           |
918 |    none                                                                   |
919 |                                                                           |
920 |   Return Value :                                                          |
921 |                                                                           |
922 |    var_out                                                                |
923 |             16 bit short signed integer (Word16) whose value falls in the |
924 |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
925 |___________________________________________________________________________|
926 */
927 
norm_s(Word16 var1)928 static_vo Word16 norm_s (Word16 var1)
929 {
930     Word16 var_out = 0;
931     if (var1 == 0)
932     {
933         var_out = 0;
934     }
935     else
936     {
937         if (var1 == -1)
938         {
939             var_out = 15;
940         }
941         else
942         {
943             if (var1 < 0)
944             {
945                 var1 = (Word16)~var1;
946             }
947             for (var_out = 0; var1 < 0x4000; var_out++)
948             {
949                 var1 <<= 1;
950             }
951         }
952     }
953     return (var_out);
954 }
955 
956 /*___________________________________________________________________________
957 |                                                                           |
958 |   Function Name : div_s                                                   |
959 |                                                                           |
960 |   Purpose :                                                               |
961 |                                                                           |
962 |   Produces a result which is the fractional integer division of var1  by  |
963 |   var2; var1 and var2 must be positive and var2 must be greater or equal  |
964 |   to var1; the result is positive (leading bit equal to 0) and truncated  |
965 |   to 16 bits.                                                             |
966 |   If var1 = var2 then div(var1,var2) = 32767.                             |
967 |                                                                           |
968 |   Complexity weight : 18                                                  |
969 |                                                                           |
970 |   Inputs :                                                                |
971 |                                                                           |
972 |    var1                                                                   |
973 |             16 bit short signed integer (Word16) whose value falls in the |
974 |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
975 |                                                                           |
976 |    var2                                                                   |
977 |             16 bit short signed integer (Word16) whose value falls in the |
978 |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
979 |                                                                           |
980 |   Outputs :                                                               |
981 |                                                                           |
982 |    none                                                                   |
983 |                                                                           |
984 |   Return Value :                                                          |
985 |                                                                           |
986 |    var_out                                                                |
987 |             16 bit short signed integer (Word16) whose value falls in the |
988 |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
989 |             It's a Q15 value (point between b15 and b14).                 |
990 |___________________________________________________________________________|
991 */
992 
div_s(Word16 var1,Word16 var2)993 static_vo Word16 div_s (Word16 var1, Word16 var2)
994 {
995     Word16 var_out = 0;
996     Word16 iteration;
997     Word32 L_num;
998     Word32 L_denom;
999     if ((var1 < 0) || (var2 < 0))
1000     {
1001         var_out = MAX_16;
1002         return var_out;
1003     }
1004     if (var2 == 0)
1005     {
1006         var_out = MAX_16;
1007         return var_out;
1008     }
1009     if (var1 == 0)
1010     {
1011         var_out = 0;
1012     }
1013     else
1014     {
1015         if (var1 == var2)
1016         {
1017             var_out = MAX_16;
1018         }
1019         else
1020         {
1021             L_num = L_deposit_l (var1);
1022             L_denom = L_deposit_l(var2);
1023             for (iteration = 0; iteration < 15; iteration++)
1024             {
1025                 var_out <<= 1;
1026                 L_num <<= 1;
1027                 if (L_num >= L_denom)
1028                 {
1029                     L_num -= L_denom;
1030                     var_out += 1;
1031                 }
1032             }
1033         }
1034     }
1035     return (var_out);
1036 }
1037 
1038 /*___________________________________________________________________________
1039 |                                                                           |
1040 |   Function Name : norm_l                                                  |
1041 |                                                                           |
1042 |   Purpose :                                                               |
1043 |                                                                           |
1044 |   Produces the number of left shifts needed to normalize the 32 bit varia-|
1045 |   ble L_var1 for positive values on the interval with minimum of          |
1046 |   1073741824 and maximum of 2147483647, and for negative values on the in-|
1047 |   terval with minimum of -2147483648 and maximum of -1073741824; in order |
1048 |   to normalize the result, the following operation must be done :         |
1049 |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
1050 |                                                                           |
1051 |   Complexity weight : 30                                                  |
1052 |                                                                           |
1053 |   Inputs :                                                                |
1054 |                                                                           |
1055 |    L_var1                                                                 |
1056 |             32 bit long signed integer (Word32) whose value falls in the  |
1057 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
1058 |                                                                           |
1059 |   Outputs :                                                               |
1060 |                                                                           |
1061 |    none                                                                   |
1062 |                                                                           |
1063 |   Return Value :                                                          |
1064 |                                                                           |
1065 |    var_out                                                                |
1066 |             16 bit short signed integer (Word16) whose value falls in the |
1067 |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
1068 |___________________________________________________________________________|
1069 */
1070 
norm_l(Word32 L_var1)1071 static_vo Word16 norm_l (Word32 L_var1)
1072 {
1073     Word16 var_out = 0;
1074     if (L_var1 != 0)
1075     {
1076         var_out = 31;
1077         if (L_var1 != (Word32) 0xffffffffL)
1078         {
1079             L_var1 ^= (L_var1 >>31);
1080             for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1081             {
1082                 L_var1 <<= 1;
1083             }
1084         }
1085     }
1086     return (var_out);
1087 }
1088 
1089 #endif //__BASIC_OP_H__
1090 
1091