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