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