basic_op.h revision a93d5b263f3f374c5d3081297f504504203000da
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*/ 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 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 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 568__attribute__((no_sanitize("integer"))) 569static_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"))) 616static_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 665static_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 715static_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 749static_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 <<=1 ; 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 808static_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 880static_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 934static_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 999static_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 1077static_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