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