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 #ifdef LINUX
     33 #define  static_vo  static __inline__
     34 #else
     35 #define  static_vo  static __inline
     36 #endif
     37 
     38 #define saturate(L_var1) (((L_var1) > 0X00007fffL) ? (MAX_16): (((L_var1) < (Word32) 0xffff8000L) ? (MIN_16): ((L_var1) & 0xffff)))
     39 
     40 #define abs_s(x)       ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16))  /* Short abs,           1   */
     41 #define L_deposit_h(x) (((Word32)(x)) << 16)                                               /* 16 bit var1 -> MSB,     2 */
     42 #define L_deposit_l(x) ((Word32)(x))                                                       /* 16 bit var1 -> LSB,     2 */
     43 #define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)                  /* Long abs,              3*/
     44 #define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1))))                   /* Short negate,        1*/
     45 #define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))                 /* Long negate,     2*/
     46 
     47 
     48 #define extract_h(a)			((Word16)(a >> 16))
     49 #define extract_l(x)            	(Word16)((x))
     50 #define add1(a,b)			(a + b)
     51 #define vo_L_msu(a,b,c)			( a - (( b * c ) << 1) )
     52 #define vo_mult32(a, b)         ((a) * (b))
     53 #define vo_mult(a,b)			(( a * b ) >> 15 )
     54 #define	vo_L_mult(a,b)	    		(((a) * (b)) << 1)
     55 #define vo_shr_r(var1, var2)   		((var1+((Word16)(1L<<(var2-1))))>>var2)
     56 #define vo_sub(a,b)			(a - b)
     57 #define vo_L_deposit_h(a)		((Word32)((a) << 16))
     58 #define vo_round(a)			((a + 0x00008000) >> 16)
     59 #define vo_extract_l(a)			((Word16)(a))
     60 #define vo_L_add(a,b)			(a + b)
     61 #define vo_L_sub(a,b)			(a - b)
     62 #define vo_mult_r(a,b)			((( a * b ) + 0x4000 ) >> 15 )
     63 #define vo_negate(a)		        (-a)
     64 #define vo_L_shr_r(L_var1, var2)        ((L_var1+((Word32)(1L<<(var2-1))))>>var2)
     65 
     66 
     67 /*___________________________________________________________________________
     68 |                                                                           |
     69 |   Prototypes for basic arithmetic operators                               |
     70 |___________________________________________________________________________|
     71 */
     72 static_vo Word16 add (Word16 var1, Word16 var2);				/* Short add,1 */
     73 static_vo Word16 sub (Word16 var1, Word16 var2);				/* Short sub,1 */
     74 static_vo Word16 shl (Word16 var1, Word16 var2);                                /* Short shift left,    1   */
     75 static_vo Word16 shr (Word16 var1, Word16 var2);                                /* Short shift right,   1   */
     76 static_vo Word16 mult (Word16 var1, Word16 var2);                               /* Short mult,          1   */
     77 static_vo Word32 L_mult (Word16 var1, Word16 var2);                             /* Long mult,           1   */
     78 static_vo Word16 voround (Word32 L_var1);                                       /* Round,               1   */
     79 static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);            	/* Mac,  1  */
     80 static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);   		/* Msu,  1  */
     81 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2);   		 	/* Long add,        2 */
     82 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2);   			/* Long sub,        2 */
     83 static_vo Word16 mult_r (Word16 var1, Word16 var2);      		 	/* Mult with round, 2 */
     84 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2);             		/* var2 > 0*/
     85 static_vo Word32 L_shl (Word32 L_var1, Word16 var2);    	 	 	/* Long shift left, 2 */
     86 static_vo Word32 L_shr (Word32 L_var1, Word16 var2);    	 	 	/* Long shift right, 2*/
     87 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2); 				/* Long shift right with round,  3   */
     88 static_vo Word16 norm_s (Word16 var1);             				/* Short norm,           15  */
     89 static_vo Word16 div_s (Word16 var1, Word16 var2); 				/* Short division,       18  */
     90 static_vo Word16 norm_l (Word32 L_var1);           				/* Long norm,            30  */
     91 
     92 /*___________________________________________________________________________
     93 |                                                                           |
     94 |   Functions                                                               |
     95 |___________________________________________________________________________|
     96 */
     97 /*___________________________________________________________________________
     98 |                                                                           |
     99 |   Function Name : add                                                     |
    100 |                                                                           |
    101 |   Purpose :                                                               |
    102 |                                                                           |
    103 |    Performs the addition (var1+var2) with overflow control and saturation;|
    104 |    the 16 bit result is set at +32767 when overflow occurs or at -32768   |
    105 |    when underflow occurs.                                                 |
    106 |                                                                           |
    107 |   Complexity weight : 1                                                   |
    108 |                                                                           |
    109 |   Inputs :                                                                |
    110 |                                                                           |
    111 |    var1                                                                   |
    112 |             16 bit short signed integer (Word16) whose value falls in the |
    113 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    114 |                                                                           |
    115 |    var2                                                                   |
    116 |             16 bit short signed integer (Word16) whose value falls in the |
    117 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    118 |                                                                           |
    119 |   Outputs :                                                               |
    120 |                                                                           |
    121 |    none                                                                   |
    122 |                                                                           |
    123 |   Return Value :                                                          |
    124 |                                                                           |
    125 |    var_out                                                                |
    126 |             16 bit short signed integer (Word16) whose value falls in the |
    127 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
    128 |___________________________________________________________________________|
    129 */
    130 static_vo Word16 add (Word16 var1, Word16 var2)
    131 {
    132 	Word16 var_out;
    133 	Word32 L_sum;
    134 	L_sum = (Word32) var1 + var2;
    135 	var_out = saturate (L_sum);
    136 	return (var_out);
    137 }
    138 
    139 /*___________________________________________________________________________
    140 |                                                                           |
    141 |   Function Name : sub                                                     |
    142 |                                                                           |
    143 |   Purpose :                                                               |
    144 |                                                                           |
    145 |    Performs the subtraction (var1+var2) with overflow control and satu-   |
    146 |    ration; the 16 bit result is set at +32767 when overflow occurs or at  |
    147 |    -32768 when underflow occurs.                                          |
    148 |                                                                           |
    149 |   Complexity weight : 1                                                   |
    150 |                                                                           |
    151 |   Inputs :                                                                |
    152 |                                                                           |
    153 |    var1                                                                   |
    154 |             16 bit short signed integer (Word16) whose value falls in the |
    155 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    156 |                                                                           |
    157 |    var2                                                                   |
    158 |             16 bit short signed integer (Word16) whose value falls in the |
    159 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    160 |                                                                           |
    161 |   Outputs :                                                               |
    162 |                                                                           |
    163 |    none                                                                   |
    164 |                                                                           |
    165 |   Return Value :                                                          |
    166 |                                                                           |
    167 |    var_out                                                                |
    168 |             16 bit short signed integer (Word16) whose value falls in the |
    169 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
    170 |___________________________________________________________________________|
    171 */
    172 
    173 static_vo Word16 sub (Word16 var1, Word16 var2)
    174 {
    175 	Word16 var_out;
    176 	Word32 L_diff;
    177 	L_diff = (Word32) var1 - var2;
    178 	var_out = saturate (L_diff);
    179 	return (var_out);
    180 }
    181 
    182 /*___________________________________________________________________________
    183 |                                                                           |
    184 |   Function Name : shl                                                     |
    185 |                                                                           |
    186 |   Purpose :                                                               |
    187 |                                                                           |
    188 |   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
    189 |   the var2 LSB of the result. If var2 is negative, arithmetically shift   |
    190 |   var1 right by -var2 with sign extension. Saturate the result in case of |
    191 |   underflows or overflows.                                                |
    192 |                                                                           |
    193 |   Complexity weight : 1                                                   |
    194 |                                                                           |
    195 |   Inputs :                                                                |
    196 |                                                                           |
    197 |    var1                                                                   |
    198 |             16 bit short signed integer (Word16) whose value falls in the |
    199 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    200 |                                                                           |
    201 |    var2                                                                   |
    202 |             16 bit short signed integer (Word16) whose value falls in the |
    203 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    204 |                                                                           |
    205 |   Outputs :                                                               |
    206 |                                                                           |
    207 |    none                                                                   |
    208 |                                                                           |
    209 |   Return Value :                                                          |
    210 |                                                                           |
    211 |    var_out                                                                |
    212 |             16 bit short signed integer (Word16) whose value falls in the |
    213 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
    214 |___________________________________________________________________________|
    215 */
    216 
    217 static_vo Word16 shl (Word16 var1, Word16 var2)
    218 {
    219 	Word16 var_out;
    220 	Word32 result;
    221 	if (var2 < 0)
    222 	{
    223 		if (var2 < -16)
    224 			var2 = -16;
    225 		var_out = var1 >> ((Word16)-var2);
    226 	}
    227 	else
    228 	{
    229 		result = (Word32) var1 *((Word32) 1 << var2);
    230 		if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
    231 		{
    232 			var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
    233 		}
    234 		else
    235 		{
    236 			var_out = extract_l (result);
    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 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
    569 {
    570 	Word32 L_var_out;
    571 	L_var_out = L_var1 + L_var2;
    572 	if (((L_var1 ^ L_var2) & MIN_32) == 0)
    573 	{
    574 		if ((L_var_out ^ L_var1) & MIN_32)
    575 		{
    576 			L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
    577 		}
    578 	}
    579 	return (L_var_out);
    580 }
    581 
    582 /*___________________________________________________________________________
    583 |                                                                           |
    584 |   Function Name : L_sub                                                   |
    585 |                                                                           |
    586 |   Purpose :                                                               |
    587 |                                                                           |
    588 |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
    589 |   overflow control and saturation; the result is set at +2147483647 when  |
    590 |   overflow occurs or at -2147483648 when underflow occurs.                |
    591 |                                                                           |
    592 |   Complexity weight : 2                                                   |
    593 |                                                                           |
    594 |   Inputs :                                                                |
    595 |                                                                           |
    596 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
    597 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
    598 |                                                                           |
    599 |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
    600 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
    601 |                                                                           |
    602 |   Outputs :                                                               |
    603 |                                                                           |
    604 |    none                                                                   |
    605 |                                                                           |
    606 |   Return Value :                                                          |
    607 |                                                                           |
    608 |    L_var_out                                                              |
    609 |             32 bit long signed integer (Word32) whose value falls in the  |
    610 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
    611 |___________________________________________________________________________|
    612 */
    613 
    614 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
    615 {
    616 	Word32 L_var_out;
    617 	L_var_out = L_var1 - L_var2;
    618 	if (((L_var1 ^ L_var2) & MIN_32) != 0)
    619 	{
    620 		if ((L_var_out ^ L_var1) & MIN_32)
    621 		{
    622 			L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
    623 		}
    624 	}
    625 	return (L_var_out);
    626 }
    627 
    628 
    629 /*___________________________________________________________________________
    630 |                                                                           |
    631 |   Function Name : mult_r                                                  |
    632 |                                                                           |
    633 |   Purpose :                                                               |
    634 |                                                                           |
    635 |   Same as mult with rounding, i.e.:                                       |
    636 |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
    637 |     mult_r(-32768,-32768) = 32767.                                        |
    638 |                                                                           |
    639 |   Complexity weight : 2                                                   |
    640 |                                                                           |
    641 |   Inputs :                                                                |
    642 |                                                                           |
    643 |    var1                                                                   |
    644 |             16 bit short signed integer (Word16) whose value falls in the |
    645 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    646 |                                                                           |
    647 |    var2                                                                   |
    648 |             16 bit short signed integer (Word16) whose value falls in the |
    649 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    650 |                                                                           |
    651 |   Outputs :                                                               |
    652 |                                                                           |
    653 |    none                                                                   |
    654 |                                                                           |
    655 |   Return Value :                                                          |
    656 |                                                                           |
    657 |    var_out                                                                |
    658 |             16 bit short signed integer (Word16) whose value falls in the |
    659 |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
    660 |___________________________________________________________________________|
    661 */
    662 
    663 static_vo Word16 mult_r (Word16 var1, Word16 var2)
    664 {
    665 	Word16 var_out;
    666 	Word32 L_product_arr;
    667 	L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
    668 	L_product_arr += (Word32) 0x00004000L;      /* round */
    669 	L_product_arr &= (Word32) 0xffff8000L;
    670 	L_product_arr >>= 15;       /* shift */
    671 	if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
    672 	{
    673 		L_product_arr |= (Word32) 0xffff0000L;
    674 	}
    675 	var_out = saturate (L_product_arr);
    676 	return (var_out);
    677 }
    678 
    679 /*___________________________________________________________________________
    680 |                                                                           |
    681 |   Function Name : L_shl                                                   |
    682 |                                                                           |
    683 |   Purpose :                                                               |
    684 |                                                                           |
    685 |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
    686 |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
    687 |   shift L_var1 right by -var2 with sign extension. Saturate the result in |
    688 |   case of underflows or overflows.                                        |
    689 |                                                                           |
    690 |   Complexity weight : 2                                                   |
    691 |                                                                           |
    692 |   Inputs :                                                                |
    693 |                                                                           |
    694 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
    695 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
    696 |                                                                           |
    697 |    var2                                                                   |
    698 |             16 bit short signed integer (Word16) whose value falls in the |
    699 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    700 |                                                                           |
    701 |   Outputs :                                                               |
    702 |                                                                           |
    703 |    none                                                                   |
    704 |                                                                           |
    705 |   Return Value :                                                          |
    706 |                                                                           |
    707 |    L_var_out                                                              |
    708 |             32 bit long signed integer (Word32) whose value falls in the  |
    709 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
    710 |___________________________________________________________________________|
    711 */
    712 
    713 static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
    714 {
    715 	Word32 L_var_out = 0L;
    716 	if (var2 <= 0)
    717 	{
    718 		if (var2 < -32)
    719 			var2 = -32;
    720 		L_var_out = (L_var1 >> (Word16)-var2);
    721 	}
    722 	else
    723 	{
    724 		for (; var2 > 0; var2--)
    725 		{
    726 			if (L_var1 > (Word32) 0X3fffffffL)
    727 			{
    728 				L_var_out = MAX_32;
    729 				break;
    730 			}
    731 			else
    732 			{
    733 				if (L_var1 < (Word32) 0xc0000000L)
    734 				{
    735 					//Overflow = 1;
    736 					L_var_out = MIN_32;
    737 					break;
    738 				}
    739 			}
    740 			L_var1 *= 2;
    741 			L_var_out = L_var1;
    742 		}
    743 	}
    744 	return (L_var_out);
    745 }
    746 
    747 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
    748 {
    749 	Word32 L_var_out = 0L;
    750 
    751 	for (; var2 > 0; var2--)
    752 	{
    753 		if (L_var1 > (Word32) 0X3fffffffL)
    754 		{
    755 			L_var_out = MAX_32;
    756 			break;
    757 		}
    758 		else
    759 		{
    760 			if (L_var1 < (Word32) 0xc0000000L)
    761 			{
    762 				L_var_out = MIN_32;
    763 				break;
    764 			}
    765 		}
    766 		L_var1 <<=1 ;
    767 		L_var_out = L_var1;
    768 	}
    769 	return (L_var_out);
    770 }
    771 
    772 /*___________________________________________________________________________
    773 |                                                                           |
    774 |   Function Name : L_shr                                                   |
    775 |                                                                           |
    776 |   Purpose :                                                               |
    777 |                                                                           |
    778 |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
    779 |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
    780 |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
    781 |   in case of underflows or overflows.                                     |
    782 |                                                                           |
    783 |   Complexity weight : 2                                                   |
    784 |                                                                           |
    785 |   Inputs :                                                                |
    786 |                                                                           |
    787 |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
    788 |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
    789 |                                                                           |
    790 |    var2                                                                   |
    791 |             16 bit short signed integer (Word16) whose value falls in the |
    792 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    793 |                                                                           |
    794 |   Outputs :                                                               |
    795 |                                                                           |
    796 |    none                                                                   |
    797 |                                                                           |
    798 |   Return Value :                                                          |
    799 |                                                                           |
    800 |    L_var_out                                                              |
    801 |             32 bit long signed integer (Word32) whose value falls in the  |
    802 |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
    803 |___________________________________________________________________________|
    804 */
    805 
    806 static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
    807 {
    808 	Word32 L_var_out;
    809 	if (var2 < 0)
    810 	{
    811 		if (var2 < -32)
    812 			var2 = -32;
    813 		L_var_out = L_shl2(L_var1, (Word16)-var2);
    814 	}
    815 	else
    816 	{
    817 		if (var2 >= 31)
    818 		{
    819 			L_var_out = (L_var1 < 0L) ? -1 : 0;
    820 		}
    821 		else
    822 		{
    823 			if (L_var1 < 0)
    824 			{
    825 				L_var_out = ~((~L_var1) >> var2);
    826 			}
    827 			else
    828 			{
    829 				L_var_out = L_var1 >> var2;
    830 			}
    831 		}
    832 	}
    833 	return (L_var_out);
    834 }
    835 
    836 /*___________________________________________________________________________
    837 |                                                                           |
    838 |   Function Name : L_shr_r                                                 |
    839 |                                                                           |
    840 |   Purpose :                                                               |
    841 |                                                                           |
    842 |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
    843 |   case of underflows or overflows :                                       |
    844 |    - If var2 is greater than zero :                                       |
    845 |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
    846 |          is equal to zero                                                 |
    847 |                     then                                                  |
    848 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
    849 |                     else                                                  |
    850 |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
    851 |    - If var2 is less than or equal to zero :                              |
    852 |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
    853 |                                                                           |
    854 |   Complexity weight : 3                                                   |
    855 |                                                                           |
    856 |   Inputs :                                                                |
    857 |                                                                           |
    858 |    L_var1                                                                 |
    859 |             32 bit long signed integer (Word32) whose value falls in the  |
    860 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
    861 |                                                                           |
    862 |    var2                                                                   |
    863 |             16 bit short signed integer (Word16) whose value falls in the |
    864 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    865 |                                                                           |
    866 |   Outputs :                                                               |
    867 |                                                                           |
    868 |    none                                                                   |
    869 |                                                                           |
    870 |   Return Value :                                                          |
    871 |                                                                           |
    872 |    L_var_out                                                              |
    873 |             32 bit long signed integer (Word32) whose value falls in the  |
    874 |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
    875 |___________________________________________________________________________|
    876 */
    877 
    878 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
    879 {
    880 	Word32 L_var_out;
    881 	if (var2 > 31)
    882 	{
    883 		L_var_out = 0;
    884 	}
    885 	else
    886 	{
    887 		L_var_out = L_shr (L_var1, var2);
    888 		if (var2 > 0)
    889 		{
    890 			if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
    891 			{
    892 				L_var_out++;
    893 			}
    894 		}
    895 	}
    896 	return (L_var_out);
    897 }
    898 
    899 /*___________________________________________________________________________
    900 |                                                                           |
    901 |   Function Name : norm_s                                                  |
    902 |                                                                           |
    903 |   Purpose :                                                               |
    904 |                                                                           |
    905 |   Produces the number of left shift needed to normalize the 16 bit varia- |
    906 |   ble var1 for positive values on the interval with minimum of 16384 and  |
    907 |   maximum of 32767, and for negative values on the interval with minimum  |
    908 |   of -32768 and maximum of -16384; in order to normalize the result, the  |
    909 |   following operation must be done :                                      |
    910 |                    norm_var1 = shl(var1,norm_s(var1)).                    |
    911 |                                                                           |
    912 |   Complexity weight : 15                                                  |
    913 |                                                                           |
    914 |   Inputs :                                                                |
    915 |                                                                           |
    916 |    var1                                                                   |
    917 |             16 bit short signed integer (Word16) whose value falls in the |
    918 |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
    919 |                                                                           |
    920 |   Outputs :                                                               |
    921 |                                                                           |
    922 |    none                                                                   |
    923 |                                                                           |
    924 |   Return Value :                                                          |
    925 |                                                                           |
    926 |    var_out                                                                |
    927 |             16 bit short signed integer (Word16) whose value falls in the |
    928 |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
    929 |___________________________________________________________________________|
    930 */
    931 
    932 static_vo Word16 norm_s (Word16 var1)
    933 {
    934 	Word16 var_out = 0;
    935 	if (var1 == 0)
    936 	{
    937 		var_out = 0;
    938 	}
    939 	else
    940 	{
    941 		if (var1 == -1)
    942 		{
    943 			var_out = 15;
    944 		}
    945 		else
    946 		{
    947 			if (var1 < 0)
    948 			{
    949 				var1 = (Word16)~var1;
    950 			}
    951 			for (var_out = 0; var1 < 0x4000; var_out++)
    952 			{
    953 				var1 <<= 1;
    954 			}
    955 		}
    956 	}
    957 	return (var_out);
    958 }
    959 
    960 /*___________________________________________________________________________
    961 |                                                                           |
    962 |   Function Name : div_s                                                   |
    963 |                                                                           |
    964 |   Purpose :                                                               |
    965 |                                                                           |
    966 |   Produces a result which is the fractional integer division of var1  by  |
    967 |   var2; var1 and var2 must be positive and var2 must be greater or equal  |
    968 |   to var1; the result is positive (leading bit equal to 0) and truncated  |
    969 |   to 16 bits.                                                             |
    970 |   If var1 = var2 then div(var1,var2) = 32767.                             |
    971 |                                                                           |
    972 |   Complexity weight : 18                                                  |
    973 |                                                                           |
    974 |   Inputs :                                                                |
    975 |                                                                           |
    976 |    var1                                                                   |
    977 |             16 bit short signed integer (Word16) whose value falls in the |
    978 |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
    979 |                                                                           |
    980 |    var2                                                                   |
    981 |             16 bit short signed integer (Word16) whose value falls in the |
    982 |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
    983 |                                                                           |
    984 |   Outputs :                                                               |
    985 |                                                                           |
    986 |    none                                                                   |
    987 |                                                                           |
    988 |   Return Value :                                                          |
    989 |                                                                           |
    990 |    var_out                                                                |
    991 |             16 bit short signed integer (Word16) whose value falls in the |
    992 |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
    993 |             It's a Q15 value (point between b15 and b14).                 |
    994 |___________________________________________________________________________|
    995 */
    996 
    997 static_vo Word16 div_s (Word16 var1, Word16 var2)
    998 {
    999 	Word16 var_out = 0;
   1000 	Word16 iteration;
   1001 	Word32 L_num;
   1002 	Word32 L_denom;
   1003 	if ((var1 < 0) || (var2 < 0))
   1004 	{
   1005 		var_out = MAX_16;
   1006 		return var_out;
   1007 	}
   1008 	if (var2 == 0)
   1009 	{
   1010 		var_out = MAX_16;
   1011 		return var_out;
   1012 	}
   1013 	if (var1 == 0)
   1014 	{
   1015 		var_out = 0;
   1016 	}
   1017 	else
   1018 	{
   1019 		if (var1 == var2)
   1020 		{
   1021 			var_out = MAX_16;
   1022 		}
   1023 		else
   1024 		{
   1025 			L_num = L_deposit_l (var1);
   1026 			L_denom = L_deposit_l(var2);
   1027 			for (iteration = 0; iteration < 15; iteration++)
   1028 			{
   1029 				var_out <<= 1;
   1030 				L_num <<= 1;
   1031 				if (L_num >= L_denom)
   1032 				{
   1033 					L_num -= L_denom;
   1034 					var_out += 1;
   1035 				}
   1036 			}
   1037 		}
   1038 	}
   1039 	return (var_out);
   1040 }
   1041 
   1042 /*___________________________________________________________________________
   1043 |                                                                           |
   1044 |   Function Name : norm_l                                                  |
   1045 |                                                                           |
   1046 |   Purpose :                                                               |
   1047 |                                                                           |
   1048 |   Produces the number of left shifts needed to normalize the 32 bit varia-|
   1049 |   ble L_var1 for positive values on the interval with minimum of          |
   1050 |   1073741824 and maximum of 2147483647, and for negative values on the in-|
   1051 |   terval with minimum of -2147483648 and maximum of -1073741824; in order |
   1052 |   to normalize the result, the following operation must be done :         |
   1053 |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
   1054 |                                                                           |
   1055 |   Complexity weight : 30                                                  |
   1056 |                                                                           |
   1057 |   Inputs :                                                                |
   1058 |                                                                           |
   1059 |    L_var1                                                                 |
   1060 |             32 bit long signed integer (Word32) whose value falls in the  |
   1061 |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
   1062 |                                                                           |
   1063 |   Outputs :                                                               |
   1064 |                                                                           |
   1065 |    none                                                                   |
   1066 |                                                                           |
   1067 |   Return Value :                                                          |
   1068 |                                                                           |
   1069 |    var_out                                                                |
   1070 |             16 bit short signed integer (Word16) whose value falls in the |
   1071 |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
   1072 |___________________________________________________________________________|
   1073 */
   1074 
   1075 static_vo Word16 norm_l (Word32 L_var1)
   1076 {
   1077 	Word16 var_out = 0;
   1078 	if (L_var1 != 0)
   1079 	{
   1080 		var_out = 31;
   1081 		if (L_var1 != (Word32) 0xffffffffL)
   1082 		{
   1083 			L_var1 ^= (L_var1 >>31);
   1084 			for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
   1085 			{
   1086 				L_var1 <<= 1;
   1087 			}
   1088 		}
   1089 	}
   1090 	return (var_out);
   1091 }
   1092 
   1093 #endif //__BASIC_OP_H__
   1094 
   1095