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*/
68static_vo Word16 add (Word16 var1, Word16 var2);                /* Short add,1 */
69static_vo Word16 sub (Word16 var1, Word16 var2);                /* Short sub,1 */
70static_vo Word16 shl (Word16 var1, Word16 var2);                                /* Short shift left,    1   */
71static_vo Word16 shr (Word16 var1, Word16 var2);                                /* Short shift right,   1   */
72static_vo Word16 mult (Word16 var1, Word16 var2);                               /* Short mult,          1   */
73static_vo Word32 L_mult (Word16 var1, Word16 var2);                             /* Long mult,           1   */
74static_vo Word16 voround (Word32 L_var1);                                       /* Round,               1   */
75static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);               /* Mac,  1  */
76static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);           /* Msu,  1  */
77static_vo Word32 L_add (Word32 L_var1, Word32 L_var2);              /* Long add,        2 */
78static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2);              /* Long sub,        2 */
79static_vo Word16 mult_r (Word16 var1, Word16 var2);                 /* Mult with round, 2 */
80static_vo Word32 L_shl2(Word32 L_var1, Word16 var2);                    /* var2 > 0*/
81static_vo Word32 L_shl (Word32 L_var1, Word16 var2);                /* Long shift left, 2 */
82static_vo Word32 L_shr (Word32 L_var1, Word16 var2);                /* Long shift right, 2*/
83static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2);              /* Long shift right with round,  3   */
84static_vo Word16 norm_s (Word16 var1);                          /* Short norm,           15  */
85static_vo Word16 div_s (Word16 var1, Word16 var2);              /* Short division,       18  */
86static_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*/
126static_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
169static_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
213static_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
277static_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
342static_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
389static_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
435static_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
481static_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
527static_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")))
569static_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")))
616static_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
665static_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
715static_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
749static_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
808static_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
880static_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
934static_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
999static_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
1077static_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