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