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