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     L_var_out = L_var1 + L_var2;
573     if (((L_var1 ^ L_var2) & MIN_32) == 0)
574     {
575         if ((L_var_out ^ L_var1) & MIN_32)
576         {
577             L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
578         }
579     }
580     return (L_var_out);
581 }
582 
583 /*___________________________________________________________________________
584 |                                                                           |
585 |   Function Name : L_sub                                                   |
586 |                                                                           |
587 |   Purpose :                                                               |
588 |                                                                           |
589 |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
590 |   overflow control and saturation; the result is set at +2147483647 when  |
591 |   overflow occurs or at -2147483648 when underflow occurs.                |
592 |                                                                           |
593 |   Complexity weight : 2                                                   |
594 |                                                                           |
595 |   Inputs :                                                                |
596 |                                                                           |
597 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
598 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
599 |                                                                           |
600 |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
601 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
602 |                                                                           |
603 |   Outputs :                                                               |
604 |                                                                           |
605 |    none                                                                   |
606 |                                                                           |
607 |   Return Value :                                                          |
608 |                                                                           |
609 |    L_var_out                                                              |
610 |             32 bit long signed integer (Word32) whose value falls in the  |
611 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
612 |___________________________________________________________________________|
613 */
614 
615 __attribute__((no_sanitize("integer")))
L_sub(Word32 L_var1,Word32 L_var2)616 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
617 {
618     Word32 L_var_out;
619     L_var_out = L_var1 - L_var2;
620     if (((L_var1 ^ L_var2) & MIN_32) != 0)
621     {
622         if ((L_var_out ^ L_var1) & MIN_32)
623         {
624             L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
625         }
626     }
627     return (L_var_out);
628 }
629 
630 
631 /*___________________________________________________________________________
632 |                                                                           |
633 |   Function Name : mult_r                                                  |
634 |                                                                           |
635 |   Purpose :                                                               |
636 |                                                                           |
637 |   Same as mult with rounding, i.e.:                                       |
638 |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
639 |     mult_r(-32768,-32768) = 32767.                                        |
640 |                                                                           |
641 |   Complexity weight : 2                                                   |
642 |                                                                           |
643 |   Inputs :                                                                |
644 |                                                                           |
645 |    var1                                                                   |
646 |             16 bit short signed integer (Word16) whose value falls in the |
647 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
648 |                                                                           |
649 |    var2                                                                   |
650 |             16 bit short signed integer (Word16) whose value falls in the |
651 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
652 |                                                                           |
653 |   Outputs :                                                               |
654 |                                                                           |
655 |    none                                                                   |
656 |                                                                           |
657 |   Return Value :                                                          |
658 |                                                                           |
659 |    var_out                                                                |
660 |             16 bit short signed integer (Word16) whose value falls in the |
661 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
662 |___________________________________________________________________________|
663 */
664 
mult_r(Word16 var1,Word16 var2)665 static_vo Word16 mult_r (Word16 var1, Word16 var2)
666 {
667     Word16 var_out;
668     Word32 L_product_arr;
669     L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
670     L_product_arr += (Word32) 0x00004000L;      /* round */
671     L_product_arr &= (Word32) 0xffff8000L;
672     L_product_arr >>= 15;       /* shift */
673     if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
674     {
675         L_product_arr |= (Word32) 0xffff0000L;
676     }
677     var_out = saturate (L_product_arr);
678     return (var_out);
679 }
680 
681 /*___________________________________________________________________________
682 |                                                                           |
683 |   Function Name : L_shl                                                   |
684 |                                                                           |
685 |   Purpose :                                                               |
686 |                                                                           |
687 |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
688 |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
689 |   shift L_var1 right by -var2 with sign extension. Saturate the result in |
690 |   case of underflows or overflows.                                        |
691 |                                                                           |
692 |   Complexity weight : 2                                                   |
693 |                                                                           |
694 |   Inputs :                                                                |
695 |                                                                           |
696 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
697 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
698 |                                                                           |
699 |    var2                                                                   |
700 |             16 bit short signed integer (Word16) whose value falls in the |
701 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
702 |                                                                           |
703 |   Outputs :                                                               |
704 |                                                                           |
705 |    none                                                                   |
706 |                                                                           |
707 |   Return Value :                                                          |
708 |                                                                           |
709 |    L_var_out                                                              |
710 |             32 bit long signed integer (Word32) whose value falls in the  |
711 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
712 |___________________________________________________________________________|
713 */
714 
L_shl(Word32 L_var1,Word16 var2)715 static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
716 {
717     Word32 L_var_out = 0L;
718     if (var2 <= 0)
719     {
720         if (var2 < -32)
721             var2 = -32;
722         L_var_out = (L_var1 >> (Word16)-var2);
723     }
724     else
725     {
726         for (; var2 > 0; var2--)
727         {
728             if (L_var1 > (Word32) 0X3fffffffL)
729             {
730                 L_var_out = MAX_32;
731                 break;
732             }
733             else
734             {
735                 if (L_var1 < (Word32) 0xc0000000L)
736                 {
737                     //Overflow = 1;
738                     L_var_out = MIN_32;
739                     break;
740                 }
741             }
742             L_var1 *= 2;
743             L_var_out = L_var1;
744         }
745     }
746     return (L_var_out);
747 }
748 
L_shl2(Word32 L_var1,Word16 var2)749 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
750 {
751     Word32 L_var_out = 0L;
752 
753     for (; var2 > 0; var2--)
754     {
755         if (L_var1 > (Word32) 0X3fffffffL)
756         {
757             L_var_out = MAX_32;
758             break;
759         }
760         else
761         {
762             if (L_var1 < (Word32) 0xc0000000L)
763             {
764                 L_var_out = MIN_32;
765                 break;
766             }
767         }
768         L_var1 *= 2 ;
769         L_var_out = L_var1;
770     }
771     return (L_var_out);
772 }
773 
774 /*___________________________________________________________________________
775 |                                                                           |
776 |   Function Name : L_shr                                                   |
777 |                                                                           |
778 |   Purpose :                                                               |
779 |                                                                           |
780 |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
781 |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
782 |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
783 |   in case of underflows or overflows.                                     |
784 |                                                                           |
785 |   Complexity weight : 2                                                   |
786 |                                                                           |
787 |   Inputs :                                                                |
788 |                                                                           |
789 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
790 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
791 |                                                                           |
792 |    var2                                                                   |
793 |             16 bit short signed integer (Word16) whose value falls in the |
794 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
795 |                                                                           |
796 |   Outputs :                                                               |
797 |                                                                           |
798 |    none                                                                   |
799 |                                                                           |
800 |   Return Value :                                                          |
801 |                                                                           |
802 |    L_var_out                                                              |
803 |             32 bit long signed integer (Word32) whose value falls in the  |
804 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
805 |___________________________________________________________________________|
806 */
807 
L_shr(Word32 L_var1,Word16 var2)808 static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
809 {
810     Word32 L_var_out;
811     if (var2 < 0)
812     {
813         if (var2 < -32)
814             var2 = -32;
815         L_var_out = L_shl2(L_var1, (Word16)-var2);
816     }
817     else
818     {
819         if (var2 >= 31)
820         {
821             L_var_out = (L_var1 < 0L) ? -1 : 0;
822         }
823         else
824         {
825             if (L_var1 < 0)
826             {
827                 L_var_out = ~((~L_var1) >> var2);
828             }
829             else
830             {
831                 L_var_out = L_var1 >> var2;
832             }
833         }
834     }
835     return (L_var_out);
836 }
837 
838 /*___________________________________________________________________________
839 |                                                                           |
840 |   Function Name : L_shr_r                                                 |
841 |                                                                           |
842 |   Purpose :                                                               |
843 |                                                                           |
844 |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
845 |   case of underflows or overflows :                                       |
846 |    - If var2 is greater than zero :                                       |
847 |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
848 |          is equal to zero                                                 |
849 |                     then                                                  |
850 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
851 |                     else                                                  |
852 |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
853 |    - If var2 is less than or equal to zero :                              |
854 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
855 |                                                                           |
856 |   Complexity weight : 3                                                   |
857 |                                                                           |
858 |   Inputs :                                                                |
859 |                                                                           |
860 |    L_var1                                                                 |
861 |             32 bit long signed integer (Word32) whose value falls in the  |
862 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
863 |                                                                           |
864 |    var2                                                                   |
865 |             16 bit short signed integer (Word16) whose value falls in the |
866 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
867 |                                                                           |
868 |   Outputs :                                                               |
869 |                                                                           |
870 |    none                                                                   |
871 |                                                                           |
872 |   Return Value :                                                          |
873 |                                                                           |
874 |    L_var_out                                                              |
875 |             32 bit long signed integer (Word32) whose value falls in the  |
876 |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
877 |___________________________________________________________________________|
878 */
879 
L_shr_r(Word32 L_var1,Word16 var2)880 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
881 {
882     Word32 L_var_out;
883     if (var2 > 31)
884     {
885         L_var_out = 0;
886     }
887     else
888     {
889         L_var_out = L_shr (L_var1, var2);
890         if (var2 > 0)
891         {
892             if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
893             {
894                 L_var_out++;
895             }
896         }
897     }
898     return (L_var_out);
899 }
900 
901 /*___________________________________________________________________________
902 |                                                                           |
903 |   Function Name : norm_s                                                  |
904 |                                                                           |
905 |   Purpose :                                                               |
906 |                                                                           |
907 |   Produces the number of left shift needed to normalize the 16 bit varia- |
908 |   ble var1 for positive values on the interval with minimum of 16384 and  |
909 |   maximum of 32767, and for negative values on the interval with minimum  |
910 |   of -32768 and maximum of -16384; in order to normalize the result, the  |
911 |   following operation must be done :                                      |
912 |                    norm_var1 = shl(var1,norm_s(var1)).                    |
913 |                                                                           |
914 |   Complexity weight : 15                                                  |
915 |                                                                           |
916 |   Inputs :                                                                |
917 |                                                                           |
918 |    var1                                                                   |
919 |             16 bit short signed integer (Word16) whose value falls in the |
920 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
921 |                                                                           |
922 |   Outputs :                                                               |
923 |                                                                           |
924 |    none                                                                   |
925 |                                                                           |
926 |   Return Value :                                                          |
927 |                                                                           |
928 |    var_out                                                                |
929 |             16 bit short signed integer (Word16) whose value falls in the |
930 |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
931 |___________________________________________________________________________|
932 */
933 
norm_s(Word16 var1)934 static_vo Word16 norm_s (Word16 var1)
935 {
936     Word16 var_out = 0;
937     if (var1 == 0)
938     {
939         var_out = 0;
940     }
941     else
942     {
943         if (var1 == -1)
944         {
945             var_out = 15;
946         }
947         else
948         {
949             if (var1 < 0)
950             {
951                 var1 = (Word16)~var1;
952             }
953             for (var_out = 0; var1 < 0x4000; var_out++)
954             {
955                 var1 <<= 1;
956             }
957         }
958     }
959     return (var_out);
960 }
961 
962 /*___________________________________________________________________________
963 |                                                                           |
964 |   Function Name : div_s                                                   |
965 |                                                                           |
966 |   Purpose :                                                               |
967 |                                                                           |
968 |   Produces a result which is the fractional integer division of var1  by  |
969 |   var2; var1 and var2 must be positive and var2 must be greater or equal  |
970 |   to var1; the result is positive (leading bit equal to 0) and truncated  |
971 |   to 16 bits.                                                             |
972 |   If var1 = var2 then div(var1,var2) = 32767.                             |
973 |                                                                           |
974 |   Complexity weight : 18                                                  |
975 |                                                                           |
976 |   Inputs :                                                                |
977 |                                                                           |
978 |    var1                                                                   |
979 |             16 bit short signed integer (Word16) whose value falls in the |
980 |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
981 |                                                                           |
982 |    var2                                                                   |
983 |             16 bit short signed integer (Word16) whose value falls in the |
984 |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
985 |                                                                           |
986 |   Outputs :                                                               |
987 |                                                                           |
988 |    none                                                                   |
989 |                                                                           |
990 |   Return Value :                                                          |
991 |                                                                           |
992 |    var_out                                                                |
993 |             16 bit short signed integer (Word16) whose value falls in the |
994 |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
995 |             It's a Q15 value (point between b15 and b14).                 |
996 |___________________________________________________________________________|
997 */
998 
div_s(Word16 var1,Word16 var2)999 static_vo Word16 div_s (Word16 var1, Word16 var2)
1000 {
1001     Word16 var_out = 0;
1002     Word16 iteration;
1003     Word32 L_num;
1004     Word32 L_denom;
1005     if ((var1 < 0) || (var2 < 0))
1006     {
1007         var_out = MAX_16;
1008         return var_out;
1009     }
1010     if (var2 == 0)
1011     {
1012         var_out = MAX_16;
1013         return var_out;
1014     }
1015     if (var1 == 0)
1016     {
1017         var_out = 0;
1018     }
1019     else
1020     {
1021         if (var1 == var2)
1022         {
1023             var_out = MAX_16;
1024         }
1025         else
1026         {
1027             L_num = L_deposit_l (var1);
1028             L_denom = L_deposit_l(var2);
1029             for (iteration = 0; iteration < 15; iteration++)
1030             {
1031                 var_out <<= 1;
1032                 L_num <<= 1;
1033                 if (L_num >= L_denom)
1034                 {
1035                     L_num -= L_denom;
1036                     var_out += 1;
1037                 }
1038             }
1039         }
1040     }
1041     return (var_out);
1042 }
1043 
1044 /*___________________________________________________________________________
1045 |                                                                           |
1046 |   Function Name : norm_l                                                  |
1047 |                                                                           |
1048 |   Purpose :                                                               |
1049 |                                                                           |
1050 |   Produces the number of left shifts needed to normalize the 32 bit varia-|
1051 |   ble L_var1 for positive values on the interval with minimum of          |
1052 |   1073741824 and maximum of 2147483647, and for negative values on the in-|
1053 |   terval with minimum of -2147483648 and maximum of -1073741824; in order |
1054 |   to normalize the result, the following operation must be done :         |
1055 |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
1056 |                                                                           |
1057 |   Complexity weight : 30                                                  |
1058 |                                                                           |
1059 |   Inputs :                                                                |
1060 |                                                                           |
1061 |    L_var1                                                                 |
1062 |             32 bit long signed integer (Word32) whose value falls in the  |
1063 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
1064 |                                                                           |
1065 |   Outputs :                                                               |
1066 |                                                                           |
1067 |    none                                                                   |
1068 |                                                                           |
1069 |   Return Value :                                                          |
1070 |                                                                           |
1071 |    var_out                                                                |
1072 |             16 bit short signed integer (Word16) whose value falls in the |
1073 |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
1074 |___________________________________________________________________________|
1075 */
1076 
norm_l(Word32 L_var1)1077 static_vo Word16 norm_l (Word32 L_var1)
1078 {
1079     Word16 var_out = 0;
1080     if (L_var1 != 0)
1081     {
1082         var_out = 31;
1083         if (L_var1 != (Word32) 0xffffffffL)
1084         {
1085             L_var1 ^= (L_var1 >>31);
1086             for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1087             {
1088                 L_var1 <<= 1;
1089             }
1090         }
1091     }
1092     return (var_out);
1093 }
1094 
1095 #endif //__BASIC_OP_H__
1096 
1097