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