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*/ 68static_vo Word16 add (Word16 var1, Word16 var2); /* Short add,1 */ 69static_vo Word16 sub (Word16 var1, Word16 var2); /* Short sub,1 */ 70static_vo Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ 71static_vo Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ 72static_vo Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ 73static_vo Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ 74static_vo Word16 voround (Word32 L_var1); /* Round, 1 */ 75static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ 76static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ 77static_vo Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */ 78static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */ 79static_vo Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */ 80static_vo Word32 L_shl2(Word32 L_var1, Word16 var2); /* var2 > 0*/ 81static_vo Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */ 82static_vo Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2*/ 83static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */ 84static_vo Word16 norm_s (Word16 var1); /* Short norm, 15 */ 85static_vo Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ 86static_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*/ 126static_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 169static_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 213static_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 273static_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 338static_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 385static_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 431static_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 477static_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 523static_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 564static_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 610static_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 659static_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 709static_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 743static_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 802static_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 874static_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 928static_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 993static_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 1071static_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