basic_op.h revision 89a3d233da8c7166e64afe4249130ceda670339c
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 + 0x00008000) >> 16)
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 ) + 0x4000 ) >> 15 )
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        result = (Word32) var1 *((Word32) 1 << var2);
226        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
227        {
228            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
229        }
230        else
231        {
232            var_out = extract_l (result);
233        }
234    }
235    return (var_out);
236}
237
238/*___________________________________________________________________________
239|                                                                           |
240|   Function Name : shr                                                     |
241|                                                                           |
242|   Purpose :                                                               |
243|                                                                           |
244|   Arithmetically shift the 16 bit input var1 right var2 positions with    |
245|   sign extension. If var2 is negative, arithmetically shift var1 left by  |
246|   -var2 with sign extension. Saturate the result in case of underflows or |
247|   overflows.                                                              |
248|                                                                           |
249|   Complexity weight : 1                                                   |
250|                                                                           |
251|   Inputs :                                                                |
252|                                                                           |
253|    var1                                                                   |
254|             16 bit short signed integer (Word16) whose value falls in the |
255|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
256|                                                                           |
257|    var2                                                                   |
258|             16 bit short signed integer (Word16) whose value falls in the |
259|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
260|                                                                           |
261|   Outputs :                                                               |
262|                                                                           |
263|    none                                                                   |
264|                                                                           |
265|   Return Value :                                                          |
266|                                                                           |
267|    var_out                                                                |
268|             16 bit short signed integer (Word16) whose value falls in the |
269|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
270|___________________________________________________________________________|
271*/
272
273static_vo Word16 shr (Word16 var1, Word16 var2)
274{
275    Word16 var_out;
276    if (var2 < 0)
277    {
278        if (var2 < -16)
279            var2 = -16;
280        var_out = shl(var1, (Word16)-var2);
281    }
282    else
283    {
284        if (var2 >= 15)
285        {
286            var_out = (Word16)((var1 < 0) ? -1 : 0);
287        }
288        else
289        {
290            if (var1 < 0)
291            {
292                var_out = (Word16)(~((~var1) >> var2));
293            }
294            else
295            {
296                var_out = (Word16)(var1 >> var2);
297            }
298        }
299    }
300    return (var_out);
301}
302
303/*___________________________________________________________________________
304|                                                                           |
305|   Function Name : mult                                                    |
306|                                                                           |
307|   Purpose :                                                               |
308|                                                                           |
309|    Performs the multiplication of var1 by var2 and gives a 16 bit result  |
310|    which is scaled i.e.:                                                  |
311|             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |
312|             mult(-32768,-32768) = 32767.                                  |
313|                                                                           |
314|   Complexity weight : 1                                                   |
315|                                                                           |
316|   Inputs :                                                                |
317|                                                                           |
318|    var1                                                                   |
319|             16 bit short signed integer (Word16) whose value falls in the |
320|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
321|                                                                           |
322|    var2                                                                   |
323|             16 bit short signed integer (Word16) whose value falls in the |
324|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
325|                                                                           |
326|   Outputs :                                                               |
327|                                                                           |
328|    none                                                                   |
329|                                                                           |
330|   Return Value :                                                          |
331|                                                                           |
332|    var_out                                                                |
333|             16 bit short signed integer (Word16) whose value falls in the |
334|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
335|___________________________________________________________________________|
336*/
337
338static_vo Word16 mult (Word16 var1, Word16 var2)
339{
340    Word16 var_out;
341    Word32 L_product;
342    L_product = (Word32) var1 *(Word32) var2;
343    L_product = (L_product & (Word32) 0xffff8000L) >> 15;
344    if (L_product & (Word32) 0x00010000L)
345        L_product = L_product | (Word32) 0xffff0000L;
346    var_out = saturate (L_product);
347    return (var_out);
348}
349
350/*___________________________________________________________________________
351|                                                                           |
352|   Function Name : L_mult                                                  |
353|                                                                           |
354|   Purpose :                                                               |
355|                                                                           |
356|   L_mult is the 32 bit result of the multiplication of var1 times var2    |
357|   with one shift left i.e.:                                               |
358|        L_mult(var1,var2) = L_shl((var1 times var2),1) and                   |
359|        L_mult(-32768,-32768) = 2147483647.                                |
360|                                                                           |
361|   Complexity weight : 1                                                   |
362|                                                                           |
363|   Inputs :                                                                |
364|                                                                           |
365|    var1                                                                   |
366|             16 bit short signed integer (Word16) whose value falls in the |
367|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
368|                                                                           |
369|    var2                                                                   |
370|             16 bit short signed integer (Word16) whose value falls in the |
371|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
372|                                                                           |
373|   Outputs :                                                               |
374|                                                                           |
375|    none                                                                   |
376|                                                                           |
377|   Return Value :                                                          |
378|                                                                           |
379|    L_var_out                                                              |
380|             32 bit long signed integer (Word32) whose value falls in the  |
381|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
382|___________________________________________________________________________|
383*/
384
385static_vo Word32 L_mult (Word16 var1, Word16 var2)
386{
387    Word32 L_var_out;
388    L_var_out = (Word32) var1 *(Word32) var2;
389    if (L_var_out != (Word32) 0x40000000L)
390    {
391        L_var_out *= 2;
392    }
393    else
394    {
395        L_var_out = MAX_32;
396    }
397    return (L_var_out);
398}
399
400/*___________________________________________________________________________
401|                                                                           |
402|   Function Name : round                                                   |
403|                                                                           |
404|   Purpose :                                                               |
405|                                                                           |
406|   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |
407|   with saturation. Shift the resulting bits right by 16 and return the 16 |
408|   bit number:                                                             |
409|               round(L_var1) = extract_h(L_add(L_var1,32768))              |
410|                                                                           |
411|   Complexity weight : 1                                                   |
412|                                                                           |
413|   Inputs :                                                                |
414|                                                                           |
415|    L_var1                                                                 |
416|             32 bit long signed integer (Word32 ) whose value falls in the |
417|             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
418|                                                                           |
419|   Outputs :                                                               |
420|                                                                           |
421|    none                                                                   |
422|                                                                           |
423|   Return Value :                                                          |
424|                                                                           |
425|    var_out                                                                |
426|             16 bit short signed integer (Word16) whose value falls in the |
427|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
428|___________________________________________________________________________|
429*/
430
431static_vo Word16 voround (Word32 L_var1)
432{
433    Word16 var_out;
434    Word32 L_rounded;
435    L_rounded = L_add (L_var1, (Word32) 0x00008000L);
436    var_out = extract_h (L_rounded);
437    return (var_out);
438}
439
440/*___________________________________________________________________________
441|                                                                           |
442|   Function Name : L_mac                                                   |
443|                                                                           |
444|   Purpose :                                                               |
445|                                                                           |
446|   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
447|   result to L_var3 with saturation, return a 32 bit result:               |
448|        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |
449|                                                                           |
450|   Complexity weight : 1                                                   |
451|                                                                           |
452|   Inputs :                                                                |
453|                                                                           |
454|    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
455|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
456|                                                                           |
457|    var1                                                                   |
458|             16 bit short signed integer (Word16) whose value falls in the |
459|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
460|                                                                           |
461|    var2                                                                   |
462|             16 bit short signed integer (Word16) whose value falls in the |
463|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
464|                                                                           |
465|   Outputs :                                                               |
466|                                                                           |
467|    none                                                                   |
468|                                                                           |
469|   Return Value :                                                          |
470|                                                                           |
471|    L_var_out                                                              |
472|             32 bit long signed integer (Word32) whose value falls in the  |
473|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
474|___________________________________________________________________________|
475*/
476
477static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
478{
479    Word32 L_var_out;
480    Word32 L_product;
481    L_product = ((var1 * var2) << 1);
482    L_var_out = L_add (L_var3, L_product);
483    return (L_var_out);
484}
485
486/*___________________________________________________________________________
487|                                                                           |
488|   Function Name : L_msu                                                   |
489|                                                                           |
490|   Purpose :                                                               |
491|                                                                           |
492|   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
493|   bit result to L_var3 with saturation, return a 32 bit result:           |
494|        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |
495|                                                                           |
496|   Complexity weight : 1                                                   |
497|                                                                           |
498|   Inputs :                                                                |
499|                                                                           |
500|    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
501|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
502|                                                                           |
503|    var1                                                                   |
504|             16 bit short signed integer (Word16) whose value falls in the |
505|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
506|                                                                           |
507|    var2                                                                   |
508|             16 bit short signed integer (Word16) whose value falls in the |
509|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
510|                                                                           |
511|   Outputs :                                                               |
512|                                                                           |
513|    none                                                                   |
514|                                                                           |
515|   Return Value :                                                          |
516|                                                                           |
517|    L_var_out                                                              |
518|             32 bit long signed integer (Word32) whose value falls in the  |
519|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
520|___________________________________________________________________________|
521*/
522
523static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
524{
525    Word32 L_var_out;
526    Word32 L_product;
527    L_product = (var1 * var2)<<1;
528    L_var_out = L_sub (L_var3, L_product);
529    return (L_var_out);
530}
531
532/*___________________________________________________________________________
533|                                                                           |
534|   Function Name : L_add                                                   |
535|                                                                           |
536|   Purpose :                                                               |
537|                                                                           |
538|   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |
539|   overflow control and saturation; the result is set at +2147483647 when  |
540|   overflow occurs or at -2147483648 when underflow occurs.                |
541|                                                                           |
542|   Complexity weight : 2                                                   |
543|                                                                           |
544|   Inputs :                                                                |
545|                                                                           |
546|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
547|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
548|                                                                           |
549|    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
550|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
551|                                                                           |
552|   Outputs :                                                               |
553|                                                                           |
554|    none                                                                   |
555|                                                                           |
556|   Return Value :                                                          |
557|                                                                           |
558|    L_var_out                                                              |
559|             32 bit long signed integer (Word32) whose value falls in the  |
560|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
561|___________________________________________________________________________|
562*/
563
564__attribute__((no_sanitize("integer")))
565static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
566{
567    Word32 L_var_out;
568    L_var_out = L_var1 + L_var2;
569    if (((L_var1 ^ L_var2) & MIN_32) == 0)
570    {
571        if ((L_var_out ^ L_var1) & MIN_32)
572        {
573            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
574        }
575    }
576    return (L_var_out);
577}
578
579/*___________________________________________________________________________
580|                                                                           |
581|   Function Name : L_sub                                                   |
582|                                                                           |
583|   Purpose :                                                               |
584|                                                                           |
585|   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
586|   overflow control and saturation; the result is set at +2147483647 when  |
587|   overflow occurs or at -2147483648 when underflow occurs.                |
588|                                                                           |
589|   Complexity weight : 2                                                   |
590|                                                                           |
591|   Inputs :                                                                |
592|                                                                           |
593|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
594|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
595|                                                                           |
596|    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
597|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
598|                                                                           |
599|   Outputs :                                                               |
600|                                                                           |
601|    none                                                                   |
602|                                                                           |
603|   Return Value :                                                          |
604|                                                                           |
605|    L_var_out                                                              |
606|             32 bit long signed integer (Word32) whose value falls in the  |
607|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
608|___________________________________________________________________________|
609*/
610
611__attribute__((no_sanitize("integer")))
612static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
613{
614    Word32 L_var_out;
615    L_var_out = L_var1 - L_var2;
616    if (((L_var1 ^ L_var2) & MIN_32) != 0)
617    {
618        if ((L_var_out ^ L_var1) & MIN_32)
619        {
620            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
621        }
622    }
623    return (L_var_out);
624}
625
626
627/*___________________________________________________________________________
628|                                                                           |
629|   Function Name : mult_r                                                  |
630|                                                                           |
631|   Purpose :                                                               |
632|                                                                           |
633|   Same as mult with rounding, i.e.:                                       |
634|     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
635|     mult_r(-32768,-32768) = 32767.                                        |
636|                                                                           |
637|   Complexity weight : 2                                                   |
638|                                                                           |
639|   Inputs :                                                                |
640|                                                                           |
641|    var1                                                                   |
642|             16 bit short signed integer (Word16) whose value falls in the |
643|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
644|                                                                           |
645|    var2                                                                   |
646|             16 bit short signed integer (Word16) whose value falls in the |
647|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
648|                                                                           |
649|   Outputs :                                                               |
650|                                                                           |
651|    none                                                                   |
652|                                                                           |
653|   Return Value :                                                          |
654|                                                                           |
655|    var_out                                                                |
656|             16 bit short signed integer (Word16) whose value falls in the |
657|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
658|___________________________________________________________________________|
659*/
660
661static_vo Word16 mult_r (Word16 var1, Word16 var2)
662{
663    Word16 var_out;
664    Word32 L_product_arr;
665    L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
666    L_product_arr += (Word32) 0x00004000L;      /* round */
667    L_product_arr &= (Word32) 0xffff8000L;
668    L_product_arr >>= 15;       /* shift */
669    if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
670    {
671        L_product_arr |= (Word32) 0xffff0000L;
672    }
673    var_out = saturate (L_product_arr);
674    return (var_out);
675}
676
677/*___________________________________________________________________________
678|                                                                           |
679|   Function Name : L_shl                                                   |
680|                                                                           |
681|   Purpose :                                                               |
682|                                                                           |
683|   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
684|   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
685|   shift L_var1 right by -var2 with sign extension. Saturate the result in |
686|   case of underflows or overflows.                                        |
687|                                                                           |
688|   Complexity weight : 2                                                   |
689|                                                                           |
690|   Inputs :                                                                |
691|                                                                           |
692|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
693|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
694|                                                                           |
695|    var2                                                                   |
696|             16 bit short signed integer (Word16) whose value falls in the |
697|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
698|                                                                           |
699|   Outputs :                                                               |
700|                                                                           |
701|    none                                                                   |
702|                                                                           |
703|   Return Value :                                                          |
704|                                                                           |
705|    L_var_out                                                              |
706|             32 bit long signed integer (Word32) whose value falls in the  |
707|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
708|___________________________________________________________________________|
709*/
710
711static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
712{
713    Word32 L_var_out = 0L;
714    if (var2 <= 0)
715    {
716        if (var2 < -32)
717            var2 = -32;
718        L_var_out = (L_var1 >> (Word16)-var2);
719    }
720    else
721    {
722        for (; var2 > 0; var2--)
723        {
724            if (L_var1 > (Word32) 0X3fffffffL)
725            {
726                L_var_out = MAX_32;
727                break;
728            }
729            else
730            {
731                if (L_var1 < (Word32) 0xc0000000L)
732                {
733                    //Overflow = 1;
734                    L_var_out = MIN_32;
735                    break;
736                }
737            }
738            L_var1 *= 2;
739            L_var_out = L_var1;
740        }
741    }
742    return (L_var_out);
743}
744
745static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
746{
747    Word32 L_var_out = 0L;
748
749    for (; var2 > 0; var2--)
750    {
751        if (L_var1 > (Word32) 0X3fffffffL)
752        {
753            L_var_out = MAX_32;
754            break;
755        }
756        else
757        {
758            if (L_var1 < (Word32) 0xc0000000L)
759            {
760                L_var_out = MIN_32;
761                break;
762            }
763        }
764        L_var1 <<=1 ;
765        L_var_out = L_var1;
766    }
767    return (L_var_out);
768}
769
770/*___________________________________________________________________________
771|                                                                           |
772|   Function Name : L_shr                                                   |
773|                                                                           |
774|   Purpose :                                                               |
775|                                                                           |
776|   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
777|   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
778|   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
779|   in case of underflows or overflows.                                     |
780|                                                                           |
781|   Complexity weight : 2                                                   |
782|                                                                           |
783|   Inputs :                                                                |
784|                                                                           |
785|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
786|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
787|                                                                           |
788|    var2                                                                   |
789|             16 bit short signed integer (Word16) whose value falls in the |
790|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
791|                                                                           |
792|   Outputs :                                                               |
793|                                                                           |
794|    none                                                                   |
795|                                                                           |
796|   Return Value :                                                          |
797|                                                                           |
798|    L_var_out                                                              |
799|             32 bit long signed integer (Word32) whose value falls in the  |
800|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
801|___________________________________________________________________________|
802*/
803
804static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
805{
806    Word32 L_var_out;
807    if (var2 < 0)
808    {
809        if (var2 < -32)
810            var2 = -32;
811        L_var_out = L_shl2(L_var1, (Word16)-var2);
812    }
813    else
814    {
815        if (var2 >= 31)
816        {
817            L_var_out = (L_var1 < 0L) ? -1 : 0;
818        }
819        else
820        {
821            if (L_var1 < 0)
822            {
823                L_var_out = ~((~L_var1) >> var2);
824            }
825            else
826            {
827                L_var_out = L_var1 >> var2;
828            }
829        }
830    }
831    return (L_var_out);
832}
833
834/*___________________________________________________________________________
835|                                                                           |
836|   Function Name : L_shr_r                                                 |
837|                                                                           |
838|   Purpose :                                                               |
839|                                                                           |
840|   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
841|   case of underflows or overflows :                                       |
842|    - If var2 is greater than zero :                                       |
843|          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
844|          is equal to zero                                                 |
845|                     then                                                  |
846|                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
847|                     else                                                  |
848|                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
849|    - If var2 is less than or equal to zero :                              |
850|                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
851|                                                                           |
852|   Complexity weight : 3                                                   |
853|                                                                           |
854|   Inputs :                                                                |
855|                                                                           |
856|    L_var1                                                                 |
857|             32 bit long signed integer (Word32) whose value falls in the  |
858|             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
859|                                                                           |
860|    var2                                                                   |
861|             16 bit short signed integer (Word16) whose value falls in the |
862|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
863|                                                                           |
864|   Outputs :                                                               |
865|                                                                           |
866|    none                                                                   |
867|                                                                           |
868|   Return Value :                                                          |
869|                                                                           |
870|    L_var_out                                                              |
871|             32 bit long signed integer (Word32) whose value falls in the  |
872|             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
873|___________________________________________________________________________|
874*/
875
876static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
877{
878    Word32 L_var_out;
879    if (var2 > 31)
880    {
881        L_var_out = 0;
882    }
883    else
884    {
885        L_var_out = L_shr (L_var1, var2);
886        if (var2 > 0)
887        {
888            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
889            {
890                L_var_out++;
891            }
892        }
893    }
894    return (L_var_out);
895}
896
897/*___________________________________________________________________________
898|                                                                           |
899|   Function Name : norm_s                                                  |
900|                                                                           |
901|   Purpose :                                                               |
902|                                                                           |
903|   Produces the number of left shift needed to normalize the 16 bit varia- |
904|   ble var1 for positive values on the interval with minimum of 16384 and  |
905|   maximum of 32767, and for negative values on the interval with minimum  |
906|   of -32768 and maximum of -16384; in order to normalize the result, the  |
907|   following operation must be done :                                      |
908|                    norm_var1 = shl(var1,norm_s(var1)).                    |
909|                                                                           |
910|   Complexity weight : 15                                                  |
911|                                                                           |
912|   Inputs :                                                                |
913|                                                                           |
914|    var1                                                                   |
915|             16 bit short signed integer (Word16) whose value falls in the |
916|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
917|                                                                           |
918|   Outputs :                                                               |
919|                                                                           |
920|    none                                                                   |
921|                                                                           |
922|   Return Value :                                                          |
923|                                                                           |
924|    var_out                                                                |
925|             16 bit short signed integer (Word16) whose value falls in the |
926|             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
927|___________________________________________________________________________|
928*/
929
930static_vo Word16 norm_s (Word16 var1)
931{
932    Word16 var_out = 0;
933    if (var1 == 0)
934    {
935        var_out = 0;
936    }
937    else
938    {
939        if (var1 == -1)
940        {
941            var_out = 15;
942        }
943        else
944        {
945            if (var1 < 0)
946            {
947                var1 = (Word16)~var1;
948            }
949            for (var_out = 0; var1 < 0x4000; var_out++)
950            {
951                var1 <<= 1;
952            }
953        }
954    }
955    return (var_out);
956}
957
958/*___________________________________________________________________________
959|                                                                           |
960|   Function Name : div_s                                                   |
961|                                                                           |
962|   Purpose :                                                               |
963|                                                                           |
964|   Produces a result which is the fractional integer division of var1  by  |
965|   var2; var1 and var2 must be positive and var2 must be greater or equal  |
966|   to var1; the result is positive (leading bit equal to 0) and truncated  |
967|   to 16 bits.                                                             |
968|   If var1 = var2 then div(var1,var2) = 32767.                             |
969|                                                                           |
970|   Complexity weight : 18                                                  |
971|                                                                           |
972|   Inputs :                                                                |
973|                                                                           |
974|    var1                                                                   |
975|             16 bit short signed integer (Word16) whose value falls in the |
976|             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
977|                                                                           |
978|    var2                                                                   |
979|             16 bit short signed integer (Word16) whose value falls in the |
980|             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
981|                                                                           |
982|   Outputs :                                                               |
983|                                                                           |
984|    none                                                                   |
985|                                                                           |
986|   Return Value :                                                          |
987|                                                                           |
988|    var_out                                                                |
989|             16 bit short signed integer (Word16) whose value falls in the |
990|             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
991|             It's a Q15 value (point between b15 and b14).                 |
992|___________________________________________________________________________|
993*/
994
995static_vo Word16 div_s (Word16 var1, Word16 var2)
996{
997    Word16 var_out = 0;
998    Word16 iteration;
999    Word32 L_num;
1000    Word32 L_denom;
1001    if ((var1 < 0) || (var2 < 0))
1002    {
1003        var_out = MAX_16;
1004        return var_out;
1005    }
1006    if (var2 == 0)
1007    {
1008        var_out = MAX_16;
1009        return var_out;
1010    }
1011    if (var1 == 0)
1012    {
1013        var_out = 0;
1014    }
1015    else
1016    {
1017        if (var1 == var2)
1018        {
1019            var_out = MAX_16;
1020        }
1021        else
1022        {
1023            L_num = L_deposit_l (var1);
1024            L_denom = L_deposit_l(var2);
1025            for (iteration = 0; iteration < 15; iteration++)
1026            {
1027                var_out <<= 1;
1028                L_num <<= 1;
1029                if (L_num >= L_denom)
1030                {
1031                    L_num -= L_denom;
1032                    var_out += 1;
1033                }
1034            }
1035        }
1036    }
1037    return (var_out);
1038}
1039
1040/*___________________________________________________________________________
1041|                                                                           |
1042|   Function Name : norm_l                                                  |
1043|                                                                           |
1044|   Purpose :                                                               |
1045|                                                                           |
1046|   Produces the number of left shifts needed to normalize the 32 bit varia-|
1047|   ble L_var1 for positive values on the interval with minimum of          |
1048|   1073741824 and maximum of 2147483647, and for negative values on the in-|
1049|   terval with minimum of -2147483648 and maximum of -1073741824; in order |
1050|   to normalize the result, the following operation must be done :         |
1051|                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
1052|                                                                           |
1053|   Complexity weight : 30                                                  |
1054|                                                                           |
1055|   Inputs :                                                                |
1056|                                                                           |
1057|    L_var1                                                                 |
1058|             32 bit long signed integer (Word32) whose value falls in the  |
1059|             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
1060|                                                                           |
1061|   Outputs :                                                               |
1062|                                                                           |
1063|    none                                                                   |
1064|                                                                           |
1065|   Return Value :                                                          |
1066|                                                                           |
1067|    var_out                                                                |
1068|             16 bit short signed integer (Word16) whose value falls in the |
1069|             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
1070|___________________________________________________________________________|
1071*/
1072
1073static_vo Word16 norm_l (Word32 L_var1)
1074{
1075    Word16 var_out = 0;
1076    if (L_var1 != 0)
1077    {
1078        var_out = 31;
1079        if (L_var1 != (Word32) 0xffffffffL)
1080        {
1081            L_var1 ^= (L_var1 >>31);
1082            for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1083            {
1084                L_var1 <<= 1;
1085            }
1086        }
1087    }
1088    return (var_out);
1089}
1090
1091#endif //__BASIC_OP_H__
1092
1093