FreeCalypso > hg > gsm-codec-lib
comparison libgsmhr1/mathhalf.c @ 500:66fb1fd032e6
libgsmhr1/mathhalf.[ch]: import original
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Wed, 19 Jun 2024 00:51:26 +0000 |
| parents | |
| children | b0333fa167c3 |
comparison
equal
deleted
inserted
replaced
| 499:446a4a2955ba | 500:66fb1fd032e6 |
|---|---|
| 1 /*************************************************************************** | |
| 2 * | |
| 3 * File Name: mathhalf.c | |
| 4 * | |
| 5 * Purpose: Contains functions which implement the primitive | |
| 6 * arithmetic operations. | |
| 7 * | |
| 8 * The functions in this file are listed below. Some of them are | |
| 9 * defined in terms of other basic operations. One of the | |
| 10 * routines, saturate() is static. This is not a basic | |
| 11 * operation, and is not referenced outside the scope of this | |
| 12 * file. | |
| 13 * | |
| 14 * | |
| 15 * abs_s() | |
| 16 * add() | |
| 17 * divide_s() | |
| 18 * extract_h() | |
| 19 * extract_l() | |
| 20 * L_abs() | |
| 21 * L_add() | |
| 22 * L_deposit_h() | |
| 23 * L_deposit_l() | |
| 24 * L_mac() | |
| 25 * L_msu() | |
| 26 * L_mult() | |
| 27 * L_negate() | |
| 28 * L_shift_r() | |
| 29 * L_shl() | |
| 30 * L_shr() | |
| 31 * L_sub() | |
| 32 * mac_r() | |
| 33 * msu_r() | |
| 34 * mult() | |
| 35 * mult_r() | |
| 36 * negate() | |
| 37 * norm_l() | |
| 38 * norm_s() | |
| 39 * round() | |
| 40 * saturate() | |
| 41 * shift_r() | |
| 42 * shl() | |
| 43 * shr() | |
| 44 * sub() | |
| 45 * | |
| 46 **************************************************************************/ | |
| 47 | |
| 48 /*_________________________________________________________________________ | |
| 49 | | | |
| 50 | Include Files | | |
| 51 |_________________________________________________________________________| | |
| 52 */ | |
| 53 | |
| 54 #include "typedefs.h" | |
| 55 #include "mathhalf.h" | |
| 56 | |
| 57 /*************************************************************************** | |
| 58 * | |
| 59 * FUNCTION NAME: saturate | |
| 60 * | |
| 61 * PURPOSE: | |
| 62 * | |
| 63 * Limit the 32 bit input to the range of a 16 bit word. | |
| 64 * | |
| 65 * | |
| 66 * INPUTS: | |
| 67 * | |
| 68 * L_var1 | |
| 69 * 32 bit long signed integer (Longword) whose value | |
| 70 * falls in the range | |
| 71 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 72 * | |
| 73 * OUTPUTS: | |
| 74 * | |
| 75 * none | |
| 76 * | |
| 77 * RETURN VALUE: | |
| 78 * | |
| 79 * swOut | |
| 80 * 16 bit short signed integer (Shortword) whose value | |
| 81 * falls in the range | |
| 82 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 83 * | |
| 84 * KEYWORDS: saturation, limiting, limit, saturate, 16 bits | |
| 85 * | |
| 86 *************************************************************************/ | |
| 87 | |
| 88 static Shortword saturate(Longword L_var1) | |
| 89 { | |
| 90 Shortword swOut; | |
| 91 | |
| 92 if (L_var1 > SW_MAX) | |
| 93 { | |
| 94 swOut = SW_MAX; | |
| 95 } | |
| 96 else if (L_var1 < SW_MIN) | |
| 97 { | |
| 98 swOut = SW_MIN; | |
| 99 } | |
| 100 else | |
| 101 swOut = (Shortword) L_var1; /* automatic type conversion */ | |
| 102 return (swOut); | |
| 103 } | |
| 104 | |
| 105 /*************************************************************************** | |
| 106 * | |
| 107 * FUNCTION NAME: abs_s | |
| 108 * | |
| 109 * PURPOSE: | |
| 110 * | |
| 111 * Take the absolute value of the 16 bit input. An input of | |
| 112 * -0x8000 results in a return value of 0x7fff. | |
| 113 * | |
| 114 * INPUTS: | |
| 115 * | |
| 116 * var1 | |
| 117 * 16 bit short signed integer (Shortword) whose value | |
| 118 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 119 * | |
| 120 * OUTPUTS: | |
| 121 * | |
| 122 * none | |
| 123 * | |
| 124 * RETURN VALUE: | |
| 125 * | |
| 126 * swOut | |
| 127 * 16 bit short signed integer (Shortword) whose value | |
| 128 * falls in the range | |
| 129 * 0x0000 0000 <= swOut <= 0x0000 7fff. | |
| 130 * | |
| 131 * IMPLEMENTATION: | |
| 132 * | |
| 133 * Take the absolute value of the 16 bit input. An input of | |
| 134 * -0x8000 results in a return value of 0x7fff. | |
| 135 * | |
| 136 * KEYWORDS: absolute value, abs | |
| 137 * | |
| 138 *************************************************************************/ | |
| 139 | |
| 140 Shortword abs_s(Shortword var1) | |
| 141 { | |
| 142 Shortword swOut; | |
| 143 | |
| 144 if (var1 == SW_MIN) | |
| 145 { | |
| 146 swOut = SW_MAX; | |
| 147 } | |
| 148 else | |
| 149 { | |
| 150 if (var1 < 0) | |
| 151 swOut = -var1; | |
| 152 else | |
| 153 swOut = var1; | |
| 154 } | |
| 155 return (swOut); | |
| 156 } | |
| 157 | |
| 158 /*************************************************************************** | |
| 159 * | |
| 160 * FUNCTION NAME: add | |
| 161 * | |
| 162 * PURPOSE: | |
| 163 * | |
| 164 * Perform the addition of the two 16 bit input variable with | |
| 165 * saturation. | |
| 166 * | |
| 167 * INPUTS: | |
| 168 * | |
| 169 * var1 | |
| 170 * 16 bit short signed integer (Shortword) whose value | |
| 171 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 172 * var2 | |
| 173 * 16 bit short signed integer (Shortword) whose value | |
| 174 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 175 * | |
| 176 * OUTPUTS: | |
| 177 * | |
| 178 * none | |
| 179 * | |
| 180 * RETURN VALUE: | |
| 181 * | |
| 182 * swOut | |
| 183 * 16 bit short signed integer (Shortword) whose value | |
| 184 * falls in the range | |
| 185 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 186 * | |
| 187 * IMPLEMENTATION: | |
| 188 * | |
| 189 * Perform the addition of the two 16 bit input variable with | |
| 190 * saturation. | |
| 191 * | |
| 192 * swOut = var1 + var2 | |
| 193 * | |
| 194 * swOut is set to 0x7fff if the operation results in an | |
| 195 * overflow. swOut is set to 0x8000 if the operation results | |
| 196 * in an underflow. | |
| 197 * | |
| 198 * KEYWORDS: add, addition | |
| 199 * | |
| 200 *************************************************************************/ | |
| 201 | |
| 202 Shortword add(Shortword var1, Shortword var2) | |
| 203 { | |
| 204 Longword L_sum; | |
| 205 Shortword swOut; | |
| 206 | |
| 207 L_sum = (Longword) var1 + var2; | |
| 208 swOut = saturate(L_sum); | |
| 209 return (swOut); | |
| 210 } | |
| 211 | |
| 212 /*************************************************************************** | |
| 213 * | |
| 214 * FUNCTION NAME: divide_s | |
| 215 * | |
| 216 * PURPOSE: | |
| 217 * | |
| 218 * Divide var1 by var2. Note that both must be positive, and | |
| 219 * var1 >= var2. The output is set to 0 if invalid input is | |
| 220 * provided. | |
| 221 * | |
| 222 * INPUTS: | |
| 223 * | |
| 224 * var1 | |
| 225 * 16 bit short signed integer (Shortword) whose value | |
| 226 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 227 * var2 | |
| 228 * 16 bit short signed integer (Shortword) whose value | |
| 229 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 230 * | |
| 231 * OUTPUTS: | |
| 232 * | |
| 233 * none | |
| 234 * | |
| 235 * RETURN VALUE: | |
| 236 * | |
| 237 * swOut | |
| 238 * 16 bit short signed integer (Shortword) whose value | |
| 239 * falls in the range | |
| 240 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 241 * | |
| 242 * IMPLEMENTATION: | |
| 243 * | |
| 244 * In the case where var1==var2 the function returns 0x7fff. The output | |
| 245 * is undefined for invalid inputs. This implementation returns zero | |
| 246 * and issues a warning via stdio if invalid input is presented. | |
| 247 * | |
| 248 * KEYWORDS: divide | |
| 249 * | |
| 250 *************************************************************************/ | |
| 251 | |
| 252 Shortword divide_s(Shortword var1, Shortword var2) | |
| 253 { | |
| 254 Longword L_div; | |
| 255 Shortword swOut; | |
| 256 | |
| 257 if (var1 < 0 || var2 < 0 || var1 > var2) | |
| 258 { | |
| 259 /* undefined output for invalid input into divide_s */ | |
| 260 return (0); | |
| 261 } | |
| 262 | |
| 263 if (var1 == var2) | |
| 264 return (0x7fff); | |
| 265 | |
| 266 L_div = ((0x00008000L * (Longword) var1) / (Longword) var2); | |
| 267 swOut = saturate(L_div); | |
| 268 return (swOut); | |
| 269 } | |
| 270 | |
| 271 /*************************************************************************** | |
| 272 * | |
| 273 * FUNCTION NAME: extract_h | |
| 274 * | |
| 275 * PURPOSE: | |
| 276 * | |
| 277 * Extract the 16 MS bits of a 32 bit Longword. Return the 16 bit | |
| 278 * number as a Shortword. This is used as a "truncation" of a fractional | |
| 279 * number. | |
| 280 * | |
| 281 * INPUTS: | |
| 282 * | |
| 283 * L_var1 | |
| 284 * 32 bit long signed integer (Longword) whose value | |
| 285 * falls in the range | |
| 286 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 287 * | |
| 288 * OUTPUTS: | |
| 289 * | |
| 290 * none | |
| 291 * | |
| 292 * RETURN VALUE: | |
| 293 * | |
| 294 * swOut | |
| 295 * 16 bit short signed integer (Shortword) whose value | |
| 296 * falls in the range | |
| 297 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 298 * | |
| 299 * IMPLEMENTATION: | |
| 300 * | |
| 301 * KEYWORDS: assign, truncate | |
| 302 * | |
| 303 *************************************************************************/ | |
| 304 | |
| 305 Shortword extract_h(Longword L_var1) | |
| 306 { | |
| 307 Shortword var2; | |
| 308 | |
| 309 var2 = (Shortword) (0x0000ffffL & (L_var1 >> 16)); | |
| 310 return (var2); | |
| 311 } | |
| 312 | |
| 313 /*************************************************************************** | |
| 314 * | |
| 315 * FUNCTION NAME: extract_l | |
| 316 * | |
| 317 * PURPOSE: | |
| 318 * | |
| 319 * Extract the 16 LS bits of a 32 bit Longword. Return the 16 bit | |
| 320 * number as a Shortword. The upper portion of the input Longword | |
| 321 * has no impact whatsoever on the output. | |
| 322 * | |
| 323 * INPUTS: | |
| 324 * | |
| 325 * L_var1 | |
| 326 * 32 bit long signed integer (Longword) whose value | |
| 327 * falls in the range | |
| 328 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 329 * | |
| 330 * OUTPUTS: | |
| 331 * | |
| 332 * none | |
| 333 * | |
| 334 * RETURN VALUE: | |
| 335 * | |
| 336 * swOut | |
| 337 * 16 bit short signed integer (Shortword) whose value | |
| 338 * falls in the range | |
| 339 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 340 * | |
| 341 * | |
| 342 * KEYWORDS: extract, assign | |
| 343 * | |
| 344 *************************************************************************/ | |
| 345 | |
| 346 Shortword extract_l(Longword L_var1) | |
| 347 { | |
| 348 Shortword var2; | |
| 349 | |
| 350 var2 = (Shortword) (0x0000ffffL & L_var1); | |
| 351 return (var2); | |
| 352 } | |
| 353 | |
| 354 /*************************************************************************** | |
| 355 * | |
| 356 * FUNCTION NAME: L_abs | |
| 357 * | |
| 358 * PURPOSE: | |
| 359 * | |
| 360 * Take the absolute value of the 32 bit input. An input of | |
| 361 * -0x8000 0000 results in a return value of 0x7fff ffff. | |
| 362 * | |
| 363 * INPUTS: | |
| 364 * | |
| 365 * L_var1 | |
| 366 * 32 bit long signed integer (Longword) whose value | |
| 367 * falls in the range | |
| 368 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 369 * | |
| 370 * OUTPUTS: | |
| 371 * | |
| 372 * none | |
| 373 * | |
| 374 * RETURN VALUE: | |
| 375 * | |
| 376 * L_Out | |
| 377 * 32 bit long signed integer (Longword) whose value | |
| 378 * falls in the range | |
| 379 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 380 * | |
| 381 * | |
| 382 * | |
| 383 * KEYWORDS: absolute value, abs | |
| 384 * | |
| 385 *************************************************************************/ | |
| 386 Longword L_abs(Longword L_var1) | |
| 387 { | |
| 388 Longword L_Out; | |
| 389 | |
| 390 if (L_var1 == LW_MIN) | |
| 391 { | |
| 392 L_Out = LW_MAX; | |
| 393 } | |
| 394 else | |
| 395 { | |
| 396 if (L_var1 < 0) | |
| 397 L_Out = -L_var1; | |
| 398 else | |
| 399 L_Out = L_var1; | |
| 400 } | |
| 401 return (L_Out); | |
| 402 } | |
| 403 | |
| 404 /*************************************************************************** | |
| 405 * | |
| 406 * FUNCTION NAME: L_add | |
| 407 * | |
| 408 * PURPOSE: | |
| 409 * | |
| 410 * Perform the addition of the two 32 bit input variables with | |
| 411 * saturation. | |
| 412 * | |
| 413 * INPUTS: | |
| 414 * | |
| 415 * L_var1 | |
| 416 * 32 bit long signed integer (Longword) whose value | |
| 417 * falls in the range | |
| 418 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 419 * L_var2 | |
| 420 * 32 bit long signed integer (Longword) whose value | |
| 421 * falls in the range | |
| 422 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 423 * | |
| 424 * OUTPUTS: | |
| 425 * | |
| 426 * none | |
| 427 * | |
| 428 * RETURN VALUE: | |
| 429 * | |
| 430 * L_Out | |
| 431 * 32 bit long signed integer (Longword) whose value | |
| 432 * falls in the range | |
| 433 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 434 * | |
| 435 * IMPLEMENTATION: | |
| 436 * | |
| 437 * Perform the addition of the two 32 bit input variables with | |
| 438 * saturation. | |
| 439 * | |
| 440 * L_Out = L_var1 + L_var2 | |
| 441 * | |
| 442 * L_Out is set to 0x7fff ffff if the operation results in an | |
| 443 * overflow. L_Out is set to 0x8000 0000 if the operation | |
| 444 * results in an underflow. | |
| 445 * | |
| 446 * KEYWORDS: add, addition | |
| 447 * | |
| 448 *************************************************************************/ | |
| 449 Longword L_add(Longword L_var1, Longword L_var2) | |
| 450 { | |
| 451 | |
| 452 Longword L_Sum, | |
| 453 L_SumLow, | |
| 454 L_SumHigh; | |
| 455 | |
| 456 L_Sum = L_var1 + L_var2; | |
| 457 | |
| 458 if ((L_var1 > 0 && L_var2 > 0) || (L_var1 < 0 && L_var2 < 0)) | |
| 459 { | |
| 460 | |
| 461 /* an overflow is possible */ | |
| 462 | |
| 463 L_SumLow = (L_var1 & 0xffff) + (L_var2 & 0xffff); | |
| 464 L_SumHigh = ((L_var1 >> 16) & 0xffff) + ((L_var2 >> 16) & 0xffff); | |
| 465 if (L_SumLow & 0x10000) | |
| 466 { | |
| 467 /* carry into high word is set */ | |
| 468 L_SumHigh += 1; | |
| 469 } | |
| 470 | |
| 471 /* update sum only if there is an overflow or underflow */ | |
| 472 /*------------------------------------------------------*/ | |
| 473 | |
| 474 if ((0x10000 & L_SumHigh) && !(0x8000 & L_SumHigh)) | |
| 475 L_Sum = LW_MIN; /* underflow */ | |
| 476 else if (!(0x10000 & L_SumHigh) && (0x8000 & L_SumHigh)) | |
| 477 L_Sum = LW_MAX; /* overflow */ | |
| 478 } | |
| 479 | |
| 480 return (L_Sum); | |
| 481 | |
| 482 } | |
| 483 | |
| 484 /*************************************************************************** | |
| 485 * | |
| 486 * FUNCTION NAME: L_deposit_h | |
| 487 * | |
| 488 * PURPOSE: | |
| 489 * | |
| 490 * Put the 16 bit input into the 16 MSB's of the output Longword. The | |
| 491 * LS 16 bits are zeroed. | |
| 492 * | |
| 493 * INPUTS: | |
| 494 * | |
| 495 * var1 | |
| 496 * 16 bit short signed integer (Shortword) whose value | |
| 497 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 498 * | |
| 499 * OUTPUTS: | |
| 500 * | |
| 501 * none | |
| 502 * | |
| 503 * RETURN VALUE: | |
| 504 * | |
| 505 * L_Out | |
| 506 * 32 bit long signed integer (Longword) whose value | |
| 507 * falls in the range | |
| 508 * 0x8000 0000 <= L_var1 <= 0x7fff 0000. | |
| 509 * | |
| 510 * | |
| 511 * KEYWORDS: deposit, assign, fractional assign | |
| 512 * | |
| 513 *************************************************************************/ | |
| 514 | |
| 515 Longword L_deposit_h(Shortword var1) | |
| 516 { | |
| 517 Longword L_var2; | |
| 518 | |
| 519 L_var2 = (Longword) var1 << 16; | |
| 520 return (L_var2); | |
| 521 } | |
| 522 | |
| 523 /*************************************************************************** | |
| 524 * | |
| 525 * FUNCTION NAME: L_deposit_l | |
| 526 * | |
| 527 * PURPOSE: | |
| 528 * | |
| 529 * Put the 16 bit input into the 16 LSB's of the output Longword with | |
| 530 * sign extension i.e. the top 16 bits are set to either 0 or 0xffff. | |
| 531 * | |
| 532 * INPUTS: | |
| 533 * | |
| 534 * var1 | |
| 535 * 16 bit short signed integer (Shortword) whose value | |
| 536 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 537 * | |
| 538 * OUTPUTS: | |
| 539 * | |
| 540 * none | |
| 541 * | |
| 542 * RETURN VALUE: | |
| 543 * | |
| 544 * L_Out | |
| 545 * 32 bit long signed integer (Longword) whose value | |
| 546 * falls in the range | |
| 547 * 0xffff 8000 <= L_var1 <= 0x0000 7fff. | |
| 548 * | |
| 549 * KEYWORDS: deposit, assign | |
| 550 * | |
| 551 *************************************************************************/ | |
| 552 | |
| 553 Longword L_deposit_l(Shortword var1) | |
| 554 { | |
| 555 Longword L_Out; | |
| 556 | |
| 557 L_Out = var1; | |
| 558 return (L_Out); | |
| 559 } | |
| 560 | |
| 561 /*************************************************************************** | |
| 562 * | |
| 563 * FUNCTION NAME: L_mac | |
| 564 * | |
| 565 * PURPOSE: | |
| 566 * | |
| 567 * Multiply accumulate. Fractionally multiply two 16 bit | |
| 568 * numbers together with saturation. Add that result to the | |
| 569 * 32 bit input with saturation. Return the 32 bit result. | |
| 570 * | |
| 571 * INPUTS: | |
| 572 * | |
| 573 * var1 | |
| 574 * 16 bit short signed integer (Shortword) whose value | |
| 575 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 576 * var2 | |
| 577 * 16 bit short signed integer (Shortword) whose value | |
| 578 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 579 * L_var3 | |
| 580 * 32 bit long signed integer (Longword) whose value | |
| 581 * falls in the range | |
| 582 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 583 * | |
| 584 * OUTPUTS: | |
| 585 * | |
| 586 * none | |
| 587 * | |
| 588 * RETURN VALUE: | |
| 589 * | |
| 590 * L_Out | |
| 591 * 32 bit long signed integer (Longword) whose value | |
| 592 * falls in the range | |
| 593 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 594 * | |
| 595 * IMPLEMENTATION: | |
| 596 * | |
| 597 * Fractionally multiply two 16 bit numbers together with | |
| 598 * saturation. The only numbers which will cause saturation on | |
| 599 * the multiply are 0x8000 * 0x8000. | |
| 600 * | |
| 601 * Add that result to the 32 bit input with saturation. | |
| 602 * Return the 32 bit result. | |
| 603 * | |
| 604 * Please note that this is not a true multiply accumulate as | |
| 605 * most processors would implement it. The 0x8000*0x8000 | |
| 606 * causes and overflow for this instruction. On most | |
| 607 * processors this would cause an overflow only if the 32 bit | |
| 608 * input added to it were positive or zero. | |
| 609 * | |
| 610 * KEYWORDS: mac, multiply accumulate | |
| 611 * | |
| 612 *************************************************************************/ | |
| 613 | |
| 614 Longword L_mac(Longword L_var3, Shortword var1, Shortword var2) | |
| 615 { | |
| 616 return (L_add(L_var3, L_mult(var1, var2))); | |
| 617 } | |
| 618 | |
| 619 /*************************************************************************** | |
| 620 * | |
| 621 * FUNCTION NAME: L_msu | |
| 622 * | |
| 623 * PURPOSE: | |
| 624 * | |
| 625 * Multiply and subtract. Fractionally multiply two 16 bit | |
| 626 * numbers together with saturation. Subtract that result from | |
| 627 * the 32 bit input with saturation. Return the 32 bit result. | |
| 628 * | |
| 629 * INPUTS: | |
| 630 * | |
| 631 * var1 | |
| 632 * 16 bit short signed integer (Shortword) whose value | |
| 633 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 634 * var2 | |
| 635 * 16 bit short signed integer (Shortword) whose value | |
| 636 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 637 * L_var3 | |
| 638 * 32 bit long signed integer (Longword) whose value | |
| 639 * falls in the range | |
| 640 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 641 * | |
| 642 * OUTPUTS: | |
| 643 * | |
| 644 * none | |
| 645 * | |
| 646 * RETURN VALUE: | |
| 647 * | |
| 648 * L_Out | |
| 649 * 32 bit long signed integer (Longword) whose value | |
| 650 * falls in the range | |
| 651 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 652 * | |
| 653 * IMPLEMENTATION: | |
| 654 * | |
| 655 * Fractionally multiply two 16 bit numbers together with | |
| 656 * saturation. The only numbers which will cause saturation on | |
| 657 * the multiply are 0x8000 * 0x8000. | |
| 658 * | |
| 659 * Subtract that result from the 32 bit input with saturation. | |
| 660 * Return the 32 bit result. | |
| 661 * | |
| 662 * Please note that this is not a true multiply accumulate as | |
| 663 * most processors would implement it. The 0x8000*0x8000 | |
| 664 * causes and overflow for this instruction. On most | |
| 665 * processors this would cause an overflow only if the 32 bit | |
| 666 * input added to it were negative or zero. | |
| 667 * | |
| 668 * KEYWORDS: mac, multiply accumulate, msu | |
| 669 * | |
| 670 *************************************************************************/ | |
| 671 | |
| 672 Longword L_msu(Longword L_var3, Shortword var1, Shortword var2) | |
| 673 { | |
| 674 return (L_sub(L_var3, L_mult(var1, var2))); | |
| 675 } | |
| 676 | |
| 677 /*************************************************************************** | |
| 678 * | |
| 679 * FUNCTION NAME: L_mult | |
| 680 * | |
| 681 * PURPOSE: | |
| 682 * | |
| 683 * Perform a fractional multipy of the two 16 bit input numbers | |
| 684 * with saturation. Output a 32 bit number. | |
| 685 * | |
| 686 * INPUTS: | |
| 687 * | |
| 688 * var1 | |
| 689 * 16 bit short signed integer (Shortword) whose value | |
| 690 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 691 * var2 | |
| 692 * 16 bit short signed integer (Shortword) whose value | |
| 693 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 694 * | |
| 695 * OUTPUTS: | |
| 696 * | |
| 697 * none | |
| 698 * | |
| 699 * RETURN VALUE: | |
| 700 * | |
| 701 * L_Out | |
| 702 * 32 bit long signed integer (Longword) whose value | |
| 703 * falls in the range | |
| 704 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 705 * | |
| 706 * IMPLEMENTATION: | |
| 707 * | |
| 708 * Multiply the two the two 16 bit input numbers. If the | |
| 709 * result is within this range, left shift the result by one | |
| 710 * and output the 32 bit number. The only possible overflow | |
| 711 * occurs when var1==var2==-0x8000. In this case output | |
| 712 * 0x7fff ffff. | |
| 713 * | |
| 714 * KEYWORDS: multiply, mult, mpy | |
| 715 * | |
| 716 *************************************************************************/ | |
| 717 | |
| 718 Longword L_mult(Shortword var1, Shortword var2) | |
| 719 { | |
| 720 Longword L_product; | |
| 721 | |
| 722 if (var1 == SW_MIN && var2 == SW_MIN) | |
| 723 L_product = LW_MAX; /* overflow */ | |
| 724 else | |
| 725 { | |
| 726 L_product = (Longword) var1 *var2; /* integer multiply */ | |
| 727 | |
| 728 L_product = L_product << 1; | |
| 729 } | |
| 730 return (L_product); | |
| 731 } | |
| 732 | |
| 733 /*************************************************************************** | |
| 734 * | |
| 735 * FUNCTION NAME: L_negate | |
| 736 * | |
| 737 * PURPOSE: | |
| 738 * | |
| 739 * Negate the 32 bit input. 0x8000 0000's negated value is | |
| 740 * 0x7fff ffff. | |
| 741 * | |
| 742 * INPUTS: | |
| 743 * | |
| 744 * L_var1 | |
| 745 * 32 bit long signed integer (Longword) whose value | |
| 746 * falls in the range | |
| 747 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 748 * | |
| 749 * OUTPUTS: | |
| 750 * | |
| 751 * none | |
| 752 * | |
| 753 * RETURN VALUE: | |
| 754 * | |
| 755 * L_Out | |
| 756 * 32 bit long signed integer (Longword) whose value | |
| 757 * falls in the range | |
| 758 * 0x8000 0001 <= L_var1 <= 0x7fff ffff. | |
| 759 * | |
| 760 * KEYWORDS: negate, negative | |
| 761 * | |
| 762 *************************************************************************/ | |
| 763 | |
| 764 Longword L_negate(Longword L_var1) | |
| 765 { | |
| 766 Longword L_Out; | |
| 767 | |
| 768 if (L_var1 == LW_MIN) | |
| 769 L_Out = LW_MAX; | |
| 770 else | |
| 771 L_Out = -L_var1; | |
| 772 return (L_Out); | |
| 773 } | |
| 774 | |
| 775 /*************************************************************************** | |
| 776 * | |
| 777 * FUNCTION NAME: L_shift_r | |
| 778 * | |
| 779 * PURPOSE: | |
| 780 * | |
| 781 * Shift and round. Perform a shift right. After shifting, use | |
| 782 * the last bit shifted out of the LSB to round the result up | |
| 783 * or down. | |
| 784 * | |
| 785 * INPUTS: | |
| 786 * | |
| 787 * L_var1 | |
| 788 * 32 bit long signed integer (Longword) whose value | |
| 789 * falls in the range | |
| 790 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 791 * var2 | |
| 792 * 16 bit short signed integer (Shortword) whose value | |
| 793 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 794 * | |
| 795 * OUTPUTS: | |
| 796 * | |
| 797 * none | |
| 798 * | |
| 799 * RETURN VALUE: | |
| 800 * | |
| 801 * L_var1 | |
| 802 * 32 bit long signed integer (Longword) whose value | |
| 803 * falls in the range | |
| 804 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 805 * | |
| 806 * | |
| 807 * IMPLEMENTATION: | |
| 808 * | |
| 809 * Shift and round. Perform a shift right. After shifting, use | |
| 810 * the last bit shifted out of the LSB to round the result up | |
| 811 * or down. This is just like shift_r above except that the | |
| 812 * input/output is 32 bits as opposed to 16. | |
| 813 * | |
| 814 * if var2 is positve perform a arithmetic left shift | |
| 815 * with saturation (see L_shl() above). | |
| 816 * | |
| 817 * If var2 is zero simply return L_var1. | |
| 818 * | |
| 819 * If var2 is negative perform a arithmetic right shift (L_shr) | |
| 820 * of L_var1 by (-var2)+1. Add the LS bit of the result to | |
| 821 * L_var1 shifted right (L_shr) by -var2. | |
| 822 * | |
| 823 * Note that there is no constraint on var2, so if var2 is | |
| 824 * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff. | |
| 825 * This is the reason the L_shl function is used. | |
| 826 * | |
| 827 * | |
| 828 * KEYWORDS: | |
| 829 * | |
| 830 *************************************************************************/ | |
| 831 | |
| 832 Longword L_shift_r(Longword L_var1, Shortword var2) | |
| 833 { | |
| 834 Longword L_Out, | |
| 835 L_rnd; | |
| 836 | |
| 837 if (var2 < -31) | |
| 838 { | |
| 839 L_Out = 0; | |
| 840 } | |
| 841 else if (var2 < 0) | |
| 842 { | |
| 843 /* right shift */ | |
| 844 L_rnd = L_shl(L_var1, var2 + 1) & 0x1; | |
| 845 L_Out = L_add(L_shl(L_var1, var2), L_rnd); | |
| 846 } | |
| 847 else | |
| 848 L_Out = L_shl(L_var1, var2); | |
| 849 | |
| 850 return (L_Out); | |
| 851 } | |
| 852 | |
| 853 /*************************************************************************** | |
| 854 * | |
| 855 * FUNCTION NAME: L_shl | |
| 856 * | |
| 857 * PURPOSE: | |
| 858 * | |
| 859 * Arithmetic shift left (or right). | |
| 860 * Arithmetically shift the input left by var2. If var2 is | |
| 861 * negative then an arithmetic shift right (L_shr) of L_var1 by | |
| 862 * -var2 is performed. | |
| 863 * | |
| 864 * INPUTS: | |
| 865 * | |
| 866 * var2 | |
| 867 * 16 bit short signed integer (Shortword) whose value | |
| 868 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 869 * L_var1 | |
| 870 * 32 bit long signed integer (Longword) whose value | |
| 871 * falls in the range | |
| 872 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 873 * OUTPUTS: | |
| 874 * | |
| 875 * none | |
| 876 * | |
| 877 * RETURN VALUE: | |
| 878 * | |
| 879 * L_Out | |
| 880 * 32 bit long signed integer (Longword) whose value | |
| 881 * falls in the range | |
| 882 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 883 * | |
| 884 * | |
| 885 * IMPLEMENTATION: | |
| 886 * | |
| 887 * Arithmetically shift the 32 bit input left by var2. This | |
| 888 * operation maintains the sign of the input number. If var2 is | |
| 889 * negative then an arithmetic shift right (L_shr) of L_var1 by | |
| 890 * -var2 is performed. See description of L_shr for details. | |
| 891 * | |
| 892 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
| 893 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
| 894 * operator for negative numbers. | |
| 895 * | |
| 896 * KEYWORDS: shift, arithmetic shift left, | |
| 897 * | |
| 898 *************************************************************************/ | |
| 899 | |
| 900 Longword L_shl(Longword L_var1, Shortword var2) | |
| 901 { | |
| 902 | |
| 903 Longword L_Mask, | |
| 904 L_Out; | |
| 905 int i, | |
| 906 iOverflow = 0; | |
| 907 | |
| 908 if (var2 == 0 || L_var1 == 0) | |
| 909 { | |
| 910 L_Out = L_var1; | |
| 911 } | |
| 912 else if (var2 < 0) | |
| 913 { | |
| 914 if (var2 <= -31) | |
| 915 { | |
| 916 if (L_var1 > 0) | |
| 917 L_Out = 0; | |
| 918 else | |
| 919 L_Out = 0xffffffffL; | |
| 920 } | |
| 921 else | |
| 922 L_Out = L_shr(L_var1, -var2); | |
| 923 } | |
| 924 else | |
| 925 { | |
| 926 | |
| 927 if (var2 >= 31) | |
| 928 iOverflow = 1; | |
| 929 | |
| 930 else | |
| 931 { | |
| 932 | |
| 933 if (L_var1 < 0) | |
| 934 L_Mask = LW_SIGN; /* sign bit mask */ | |
| 935 else | |
| 936 L_Mask = 0x0; | |
| 937 L_Out = L_var1; | |
| 938 for (i = 0; i < var2 && !iOverflow; i++) | |
| 939 { | |
| 940 /* check the sign bit */ | |
| 941 L_Out = (L_Out & 0x7fffffffL) << 1; | |
| 942 if ((L_Mask ^ L_Out) & LW_SIGN) | |
| 943 iOverflow = 1; | |
| 944 } | |
| 945 } | |
| 946 | |
| 947 if (iOverflow) | |
| 948 { | |
| 949 /* saturate */ | |
| 950 if (L_var1 > 0) | |
| 951 L_Out = LW_MAX; | |
| 952 else | |
| 953 L_Out = LW_MIN; | |
| 954 } | |
| 955 } | |
| 956 | |
| 957 return (L_Out); | |
| 958 } | |
| 959 | |
| 960 /*************************************************************************** | |
| 961 * | |
| 962 * FUNCTION NAME: L_shr | |
| 963 * | |
| 964 * PURPOSE: | |
| 965 * | |
| 966 * Arithmetic shift right (or left). | |
| 967 * Arithmetically shift the input right by var2. If var2 is | |
| 968 * negative then an arithmetic shift left (shl) of var1 by | |
| 969 * -var2 is performed. | |
| 970 * | |
| 971 * INPUTS: | |
| 972 * | |
| 973 * var2 | |
| 974 * 16 bit short signed integer (Shortword) whose value | |
| 975 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 976 * L_var1 | |
| 977 * 32 bit long signed integer (Longword) whose value | |
| 978 * falls in the range | |
| 979 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 980 * OUTPUTS: | |
| 981 * | |
| 982 * none | |
| 983 * | |
| 984 * RETURN VALUE: | |
| 985 * | |
| 986 * L_Out | |
| 987 * 32 bit long signed integer (Longword) whose value | |
| 988 * falls in the range | |
| 989 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 990 * | |
| 991 * | |
| 992 * IMPLEMENTATION: | |
| 993 * | |
| 994 * Arithmetically shift the input right by var2. This | |
| 995 * operation maintains the sign of the input number. If var2 is | |
| 996 * negative then an arithmetic shift left (shl) of L_var1 by | |
| 997 * -var2 is performed. See description of L_shl for details. | |
| 998 * | |
| 999 * The input is a 32 bit number, as is the output. | |
| 1000 * | |
| 1001 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
| 1002 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
| 1003 * operator for negative numbers. | |
| 1004 * | |
| 1005 * KEYWORDS: shift, arithmetic shift right, | |
| 1006 * | |
| 1007 *************************************************************************/ | |
| 1008 | |
| 1009 Longword L_shr(Longword L_var1, Shortword var2) | |
| 1010 { | |
| 1011 | |
| 1012 Longword L_Mask, | |
| 1013 L_Out; | |
| 1014 | |
| 1015 if (var2 == 0 || L_var1 == 0) | |
| 1016 { | |
| 1017 L_Out = L_var1; | |
| 1018 } | |
| 1019 else if (var2 < 0) | |
| 1020 { | |
| 1021 /* perform a left shift */ | |
| 1022 /*----------------------*/ | |
| 1023 if (var2 <= -31) | |
| 1024 { | |
| 1025 /* saturate */ | |
| 1026 if (L_var1 > 0) | |
| 1027 L_Out = LW_MAX; | |
| 1028 else | |
| 1029 L_Out = LW_MIN; | |
| 1030 } | |
| 1031 else | |
| 1032 L_Out = L_shl(L_var1, -var2); | |
| 1033 } | |
| 1034 else | |
| 1035 { | |
| 1036 | |
| 1037 if (var2 >= 31) | |
| 1038 { | |
| 1039 if (L_var1 > 0) | |
| 1040 L_Out = 0; | |
| 1041 else | |
| 1042 L_Out = 0xffffffffL; | |
| 1043 } | |
| 1044 else | |
| 1045 { | |
| 1046 L_Mask = 0; | |
| 1047 | |
| 1048 if (L_var1 < 0) | |
| 1049 { | |
| 1050 L_Mask = ~L_Mask << (32 - var2); | |
| 1051 } | |
| 1052 | |
| 1053 L_var1 >>= var2; | |
| 1054 L_Out = L_Mask | L_var1; | |
| 1055 } | |
| 1056 } | |
| 1057 return (L_Out); | |
| 1058 } | |
| 1059 | |
| 1060 /*************************************************************************** | |
| 1061 * | |
| 1062 * FUNCTION NAME: L_sub | |
| 1063 * | |
| 1064 * PURPOSE: | |
| 1065 * | |
| 1066 * Perform the subtraction of the two 32 bit input variables with | |
| 1067 * saturation. | |
| 1068 * | |
| 1069 * INPUTS: | |
| 1070 * | |
| 1071 * L_var1 | |
| 1072 * 32 bit long signed integer (Longword) whose value | |
| 1073 * falls in the range | |
| 1074 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 1075 * L_var2 | |
| 1076 * 32 bit long signed integer (Longword) whose value | |
| 1077 * falls in the range | |
| 1078 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 1079 * | |
| 1080 * OUTPUTS: | |
| 1081 * | |
| 1082 * none | |
| 1083 * | |
| 1084 * RETURN VALUE: | |
| 1085 * | |
| 1086 * L_Out | |
| 1087 * 32 bit long signed integer (Longword) whose value | |
| 1088 * falls in the range | |
| 1089 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 1090 * | |
| 1091 * IMPLEMENTATION: | |
| 1092 * | |
| 1093 * Perform the subtraction of the two 32 bit input variables with | |
| 1094 * saturation. | |
| 1095 * | |
| 1096 * L_Out = L_var1 - L_var2 | |
| 1097 * | |
| 1098 * L_Out is set to 0x7fff ffff if the operation results in an | |
| 1099 * overflow. L_Out is set to 0x8000 0000 if the operation | |
| 1100 * results in an underflow. | |
| 1101 * | |
| 1102 * KEYWORDS: sub, subtraction | |
| 1103 * | |
| 1104 *************************************************************************/ | |
| 1105 Longword L_sub(Longword L_var1, Longword L_var2) | |
| 1106 { | |
| 1107 Longword L_Sum; | |
| 1108 | |
| 1109 /* check for overflow */ | |
| 1110 if ((L_var1 > 0 && L_var2 < 0) || (L_var1 < 0 && L_var2 > 0)) | |
| 1111 { | |
| 1112 if (L_var2 == LW_MIN) | |
| 1113 { | |
| 1114 L_Sum = L_add(L_var1, LW_MAX); | |
| 1115 L_Sum = L_add(L_Sum, 1); | |
| 1116 } | |
| 1117 else | |
| 1118 L_Sum = L_add(L_var1, -L_var2); | |
| 1119 } | |
| 1120 else | |
| 1121 { /* no overflow possible */ | |
| 1122 L_Sum = L_var1 - L_var2; | |
| 1123 } | |
| 1124 return (L_Sum); | |
| 1125 } | |
| 1126 | |
| 1127 /*************************************************************************** | |
| 1128 * | |
| 1129 * FUNCTION NAME:mac_r | |
| 1130 * | |
| 1131 * PURPOSE: | |
| 1132 * | |
| 1133 * Multiply accumulate and round. Fractionally multiply two 16 | |
| 1134 * bit numbers together with saturation. Add that result to | |
| 1135 * the 32 bit input with saturation. Finally round the result | |
| 1136 * into a 16 bit number. | |
| 1137 * | |
| 1138 * | |
| 1139 * INPUTS: | |
| 1140 * | |
| 1141 * var1 | |
| 1142 * 16 bit short signed integer (Shortword) whose value | |
| 1143 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1144 * var2 | |
| 1145 * 16 bit short signed integer (Shortword) whose value | |
| 1146 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1147 * L_var3 | |
| 1148 * 32 bit long signed integer (Longword) whose value | |
| 1149 * falls in the range | |
| 1150 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 1151 * | |
| 1152 * OUTPUTS: | |
| 1153 * | |
| 1154 * none | |
| 1155 * | |
| 1156 * RETURN VALUE: | |
| 1157 * | |
| 1158 * swOut | |
| 1159 * 16 bit short signed integer (Shortword) whose value | |
| 1160 * falls in the range | |
| 1161 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1162 * | |
| 1163 * IMPLEMENTATION: | |
| 1164 * | |
| 1165 * Fractionally multiply two 16 bit numbers together with | |
| 1166 * saturation. The only numbers which will cause saturation on | |
| 1167 * the multiply are 0x8000 * 0x8000. | |
| 1168 * | |
| 1169 * Add that result to the 32 bit input with saturation. | |
| 1170 * Round the 32 bit result by adding 0x0000 8000 to the input. | |
| 1171 * The result may overflow due to the add. If so, the result | |
| 1172 * is saturated. The 32 bit rounded number is then shifted | |
| 1173 * down 16 bits and returned as a Shortword. | |
| 1174 * | |
| 1175 * Please note that this is not a true multiply accumulate as | |
| 1176 * most processors would implement it. The 0x8000*0x8000 | |
| 1177 * causes and overflow for this instruction. On most | |
| 1178 * processors this would cause an overflow only if the 32 bit | |
| 1179 * input added to it were positive or zero. | |
| 1180 * | |
| 1181 * KEYWORDS: mac, multiply accumulate, macr | |
| 1182 * | |
| 1183 *************************************************************************/ | |
| 1184 | |
| 1185 Shortword mac_r(Longword L_var3, Shortword var1, Shortword var2) | |
| 1186 { | |
| 1187 return (round(L_add(L_var3, L_mult(var1, var2)))); | |
| 1188 } | |
| 1189 | |
| 1190 /*************************************************************************** | |
| 1191 * | |
| 1192 * FUNCTION NAME: msu_r | |
| 1193 * | |
| 1194 * PURPOSE: | |
| 1195 * | |
| 1196 * Multiply subtract and round. Fractionally multiply two 16 | |
| 1197 * bit numbers together with saturation. Subtract that result from | |
| 1198 * the 32 bit input with saturation. Finally round the result | |
| 1199 * into a 16 bit number. | |
| 1200 * | |
| 1201 * | |
| 1202 * INPUTS: | |
| 1203 * | |
| 1204 * var1 | |
| 1205 * 16 bit short signed integer (Shortword) whose value | |
| 1206 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1207 * var2 | |
| 1208 * 16 bit short signed integer (Shortword) whose value | |
| 1209 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1210 * L_var3 | |
| 1211 * 32 bit long signed integer (Longword) whose value | |
| 1212 * falls in the range | |
| 1213 * 0x8000 0000 <= L_var2 <= 0x7fff ffff. | |
| 1214 * | |
| 1215 * OUTPUTS: | |
| 1216 * | |
| 1217 * none | |
| 1218 * | |
| 1219 * RETURN VALUE: | |
| 1220 * | |
| 1221 * swOut | |
| 1222 * 16 bit short signed integer (Shortword) whose value | |
| 1223 * falls in the range | |
| 1224 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1225 * | |
| 1226 * IMPLEMENTATION: | |
| 1227 * | |
| 1228 * Fractionally multiply two 16 bit numbers together with | |
| 1229 * saturation. The only numbers which will cause saturation on | |
| 1230 * the multiply are 0x8000 * 0x8000. | |
| 1231 * | |
| 1232 * Subtract that result from the 32 bit input with saturation. | |
| 1233 * Round the 32 bit result by adding 0x0000 8000 to the input. | |
| 1234 * The result may overflow due to the add. If so, the result | |
| 1235 * is saturated. The 32 bit rounded number is then shifted | |
| 1236 * down 16 bits and returned as a Shortword. | |
| 1237 * | |
| 1238 * Please note that this is not a true multiply accumulate as | |
| 1239 * most processors would implement it. The 0x8000*0x8000 | |
| 1240 * causes and overflow for this instruction. On most | |
| 1241 * processors this would cause an overflow only if the 32 bit | |
| 1242 * input added to it were positive or zero. | |
| 1243 * | |
| 1244 * KEYWORDS: mac, multiply accumulate, macr | |
| 1245 * | |
| 1246 *************************************************************************/ | |
| 1247 | |
| 1248 Shortword msu_r(Longword L_var3, Shortword var1, Shortword var2) | |
| 1249 { | |
| 1250 return (round(L_sub(L_var3, L_mult(var1, var2)))); | |
| 1251 } | |
| 1252 | |
| 1253 /*************************************************************************** | |
| 1254 * | |
| 1255 * FUNCTION NAME: mult | |
| 1256 * | |
| 1257 * PURPOSE: | |
| 1258 * | |
| 1259 * Perform a fractional multipy of the two 16 bit input numbers | |
| 1260 * with saturation and truncation. | |
| 1261 * | |
| 1262 * INPUTS: | |
| 1263 * | |
| 1264 * var1 | |
| 1265 * 16 bit short signed integer (Shortword) whose value | |
| 1266 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1267 * var2 | |
| 1268 * 16 bit short signed integer (Shortword) whose value | |
| 1269 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1270 * | |
| 1271 * OUTPUTS: | |
| 1272 * | |
| 1273 * none | |
| 1274 * | |
| 1275 * RETURN VALUE: | |
| 1276 * | |
| 1277 * swOut | |
| 1278 * 16 bit short signed integer (Shortword) whose value | |
| 1279 * falls in the range | |
| 1280 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1281 * | |
| 1282 * IMPLEMENTATION: | |
| 1283 * | |
| 1284 * Perform a fractional multipy of the two 16 bit input | |
| 1285 * numbers. If var1 == var2 == -0x8000, output 0x7fff. | |
| 1286 * Otherwise output var1*var2 >> 15. The output is a | |
| 1287 * 16 bit number. | |
| 1288 * | |
| 1289 * KEYWORDS: mult, mulitply, mpy | |
| 1290 * | |
| 1291 *************************************************************************/ | |
| 1292 | |
| 1293 Shortword mult(Shortword var1, Shortword var2) | |
| 1294 { | |
| 1295 Longword L_product; | |
| 1296 Shortword swOut; | |
| 1297 | |
| 1298 L_product = L_mult(var1, var2); | |
| 1299 swOut = extract_h(L_product); | |
| 1300 return (swOut); | |
| 1301 } | |
| 1302 | |
| 1303 /*************************************************************************** | |
| 1304 * | |
| 1305 * FUNCTION NAME: mult_r | |
| 1306 * | |
| 1307 * PURPOSE: | |
| 1308 * | |
| 1309 * Perform a fractional multipy and round of the two 16 bit | |
| 1310 * input numbers with saturation. | |
| 1311 * | |
| 1312 * INPUTS: | |
| 1313 * | |
| 1314 * var1 | |
| 1315 * 16 bit short signed integer (Shortword) whose value | |
| 1316 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1317 * var2 | |
| 1318 * 16 bit short signed integer (Shortword) whose value | |
| 1319 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1320 * | |
| 1321 * OUTPUTS: | |
| 1322 * | |
| 1323 * none | |
| 1324 * | |
| 1325 * RETURN VALUE: | |
| 1326 * | |
| 1327 * swOut | |
| 1328 * 16 bit short signed integer (Shortword) whose value | |
| 1329 * falls in the range | |
| 1330 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1331 * | |
| 1332 * IMPLEMENTATION: | |
| 1333 * | |
| 1334 * This routine is defined as the concatenation of the multiply | |
| 1335 * operation and the round operation. | |
| 1336 * | |
| 1337 * The fractional multiply (L_mult) produces a saturated 32 bit | |
| 1338 * output. This is followed by a an add of 0x0000 8000 to the | |
| 1339 * 32 bit result. The result may overflow due to the add. If | |
| 1340 * so, the result is saturated. The 32 bit rounded number is | |
| 1341 * then shifted down 16 bits and returned as a Shortword. | |
| 1342 * | |
| 1343 * | |
| 1344 * KEYWORDS: multiply and round, round, mult_r, mpyr | |
| 1345 * | |
| 1346 *************************************************************************/ | |
| 1347 | |
| 1348 | |
| 1349 Shortword mult_r(Shortword var1, Shortword var2) | |
| 1350 { | |
| 1351 Shortword swOut; | |
| 1352 | |
| 1353 swOut = round(L_mult(var1, var2)); | |
| 1354 return (swOut); | |
| 1355 } | |
| 1356 | |
| 1357 /*************************************************************************** | |
| 1358 * | |
| 1359 * FUNCTION NAME: negate | |
| 1360 * | |
| 1361 * PURPOSE: | |
| 1362 * | |
| 1363 * Negate the 16 bit input. 0x8000's negated value is 0x7fff. | |
| 1364 * | |
| 1365 * INPUTS: | |
| 1366 * | |
| 1367 * var1 | |
| 1368 * 16 bit short signed integer (Shortword) whose value | |
| 1369 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1370 * | |
| 1371 * OUTPUTS: | |
| 1372 * | |
| 1373 * none | |
| 1374 * | |
| 1375 * RETURN VALUE: | |
| 1376 * | |
| 1377 * swOut | |
| 1378 * 16 bit short signed integer (Shortword) whose value | |
| 1379 * falls in the range | |
| 1380 * 0xffff 8001 <= swOut <= 0x0000 7fff. | |
| 1381 * | |
| 1382 * KEYWORDS: negate, negative, invert | |
| 1383 * | |
| 1384 *************************************************************************/ | |
| 1385 | |
| 1386 Shortword negate(Shortword var1) | |
| 1387 { | |
| 1388 Shortword swOut; | |
| 1389 | |
| 1390 if (var1 == SW_MIN) | |
| 1391 swOut = SW_MAX; | |
| 1392 else | |
| 1393 swOut = -var1; | |
| 1394 return (swOut); | |
| 1395 } | |
| 1396 | |
| 1397 /*************************************************************************** | |
| 1398 * | |
| 1399 * FUNCTION NAME: norm_l | |
| 1400 * | |
| 1401 * PURPOSE: | |
| 1402 * | |
| 1403 * Get normalize shift count: | |
| 1404 * | |
| 1405 * A 32 bit number is input (possiblly unnormalized). Output | |
| 1406 * the positive (or zero) shift count required to normalize the | |
| 1407 * input. | |
| 1408 * | |
| 1409 * INPUTS: | |
| 1410 * | |
| 1411 * L_var1 | |
| 1412 * 32 bit long signed integer (Longword) whose value | |
| 1413 * falls in the range | |
| 1414 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 1415 * | |
| 1416 * OUTPUTS: | |
| 1417 * | |
| 1418 * none | |
| 1419 * | |
| 1420 * RETURN VALUE: | |
| 1421 * | |
| 1422 * swOut | |
| 1423 * 16 bit short signed integer (Shortword) whose value | |
| 1424 * falls in the range | |
| 1425 * 0 <= swOut <= 31 | |
| 1426 * | |
| 1427 * | |
| 1428 * | |
| 1429 * IMPLEMENTATION: | |
| 1430 * | |
| 1431 * Get normalize shift count: | |
| 1432 * | |
| 1433 * A 32 bit number is input (possiblly unnormalized). Output | |
| 1434 * the positive (or zero) shift count required to normalize the | |
| 1435 * input. | |
| 1436 * | |
| 1437 * If zero in input, return 0 as the shift count. | |
| 1438 * | |
| 1439 * For non-zero numbers, count the number of left shift | |
| 1440 * required to get the number to fall into the range: | |
| 1441 * | |
| 1442 * 0x4000 0000 >= normlzd number >= 0x7fff ffff (positive number) | |
| 1443 * or | |
| 1444 * 0x8000 0000 <= normlzd number < 0xc000 0000 (negative number) | |
| 1445 * | |
| 1446 * Return the number of shifts. | |
| 1447 * | |
| 1448 * This instruction corresponds exactly to the Full-Rate "norm" | |
| 1449 * instruction. | |
| 1450 * | |
| 1451 * KEYWORDS: norm, normalization | |
| 1452 * | |
| 1453 *************************************************************************/ | |
| 1454 | |
| 1455 Shortword norm_l(Longword L_var1) | |
| 1456 { | |
| 1457 | |
| 1458 Shortword swShiftCnt; | |
| 1459 | |
| 1460 if (L_var1 != 0) | |
| 1461 { | |
| 1462 if (!(L_var1 & LW_SIGN)) | |
| 1463 { | |
| 1464 | |
| 1465 /* positive input */ | |
| 1466 for (swShiftCnt = 0; !(L_var1 <= LW_MAX && L_var1 >= 0x40000000L); | |
| 1467 swShiftCnt++) | |
| 1468 { | |
| 1469 L_var1 = L_var1 << 1; | |
| 1470 } | |
| 1471 | |
| 1472 } | |
| 1473 else | |
| 1474 { | |
| 1475 /* negative input */ | |
| 1476 for (swShiftCnt = 0; | |
| 1477 !(L_var1 >= LW_MIN && L_var1 < (Longword) 0xc0000000L); | |
| 1478 swShiftCnt++) | |
| 1479 { | |
| 1480 L_var1 = L_var1 << 1; | |
| 1481 } | |
| 1482 } | |
| 1483 } | |
| 1484 else | |
| 1485 { | |
| 1486 swShiftCnt = 0; | |
| 1487 } | |
| 1488 return (swShiftCnt); | |
| 1489 } | |
| 1490 | |
| 1491 /*************************************************************************** | |
| 1492 * | |
| 1493 * FUNCTION NAME: norm_s | |
| 1494 * | |
| 1495 * PURPOSE: | |
| 1496 * | |
| 1497 * Get normalize shift count: | |
| 1498 * | |
| 1499 * A 16 bit number is input (possiblly unnormalized). Output | |
| 1500 * the positive (or zero) shift count required to normalize the | |
| 1501 * input. | |
| 1502 * | |
| 1503 * INPUTS: | |
| 1504 * | |
| 1505 * var1 | |
| 1506 * 16 bit short signed integer (Shortword) whose value | |
| 1507 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1508 * | |
| 1509 * OUTPUTS: | |
| 1510 * | |
| 1511 * none | |
| 1512 * | |
| 1513 * RETURN VALUE: | |
| 1514 * swOut | |
| 1515 * 16 bit short signed integer (Shortword) whose value | |
| 1516 * falls in the range | |
| 1517 * 0 <= swOut <= 15 | |
| 1518 * | |
| 1519 * | |
| 1520 * | |
| 1521 * IMPLEMENTATION: | |
| 1522 * | |
| 1523 * Get normalize shift count: | |
| 1524 * | |
| 1525 * A 16 bit number is input (possiblly unnormalized). Output | |
| 1526 * the positive (or zero) shift count required to normalize the | |
| 1527 * input. | |
| 1528 * | |
| 1529 * If zero in input, return 0 as the shift count. | |
| 1530 * | |
| 1531 * For non-zero numbers, count the number of left shift | |
| 1532 * required to get the number to fall into the range: | |
| 1533 * | |
| 1534 * 0x4000 >= normlzd number >= 0x7fff (positive number) | |
| 1535 * or | |
| 1536 * 0x8000 <= normlzd number < 0xc000 (negative number) | |
| 1537 * | |
| 1538 * Return the number of shifts. | |
| 1539 * | |
| 1540 * This instruction corresponds exactly to the Full-Rate "norm" | |
| 1541 * instruction. | |
| 1542 * | |
| 1543 * KEYWORDS: norm, normalization | |
| 1544 * | |
| 1545 *************************************************************************/ | |
| 1546 | |
| 1547 Shortword norm_s(Shortword var1) | |
| 1548 { | |
| 1549 | |
| 1550 short swShiftCnt; | |
| 1551 Longword L_var1; | |
| 1552 | |
| 1553 L_var1 = L_deposit_h(var1); | |
| 1554 swShiftCnt = norm_l(L_var1); | |
| 1555 return (swShiftCnt); | |
| 1556 } | |
| 1557 | |
| 1558 /*************************************************************************** | |
| 1559 * | |
| 1560 * FUNCTION NAME: round | |
| 1561 * | |
| 1562 * PURPOSE: | |
| 1563 * | |
| 1564 * Round the 32 bit Longword into a 16 bit shortword with saturation. | |
| 1565 * | |
| 1566 * INPUTS: | |
| 1567 * | |
| 1568 * L_var1 | |
| 1569 * 32 bit long signed integer (Longword) whose value | |
| 1570 * falls in the range | |
| 1571 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
| 1572 * OUTPUTS: | |
| 1573 * | |
| 1574 * none | |
| 1575 * | |
| 1576 * RETURN VALUE: | |
| 1577 * | |
| 1578 * swOut | |
| 1579 * 16 bit short signed integer (Shortword) whose value | |
| 1580 * falls in the range | |
| 1581 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1582 * | |
| 1583 * IMPLEMENTATION: | |
| 1584 * | |
| 1585 * Perform a two's complement round on the input Longword with | |
| 1586 * saturation. | |
| 1587 * | |
| 1588 * This is equivalent to adding 0x0000 8000 to the input. The | |
| 1589 * result may overflow due to the add. If so, the result is | |
| 1590 * saturated. The 32 bit rounded number is then shifted down | |
| 1591 * 16 bits and returned as a Shortword. | |
| 1592 * | |
| 1593 * | |
| 1594 * KEYWORDS: round | |
| 1595 * | |
| 1596 *************************************************************************/ | |
| 1597 | |
| 1598 Shortword round(Longword L_var1) | |
| 1599 { | |
| 1600 Longword L_Prod; | |
| 1601 | |
| 1602 L_Prod = L_add(L_var1, 0x00008000L); /* round MSP */ | |
| 1603 return (extract_h(L_Prod)); | |
| 1604 } | |
| 1605 | |
| 1606 /*************************************************************************** | |
| 1607 * | |
| 1608 * FUNCTION NAME: shift_r | |
| 1609 * | |
| 1610 * PURPOSE: | |
| 1611 * | |
| 1612 * Shift and round. Perform a shift right. After shifting, use | |
| 1613 * the last bit shifted out of the LSB to round the result up | |
| 1614 * or down. | |
| 1615 * | |
| 1616 * INPUTS: | |
| 1617 * | |
| 1618 * var1 | |
| 1619 * 16 bit short signed integer (Shortword) whose value | |
| 1620 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1621 * var2 | |
| 1622 * 16 bit short signed integer (Shortword) whose value | |
| 1623 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1624 * | |
| 1625 * OUTPUTS: | |
| 1626 * | |
| 1627 * none | |
| 1628 * | |
| 1629 * RETURN VALUE: | |
| 1630 * | |
| 1631 * swOut | |
| 1632 * 16 bit short signed integer (Shortword) whose value | |
| 1633 * falls in the range | |
| 1634 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1635 * | |
| 1636 * | |
| 1637 * IMPLEMENTATION: | |
| 1638 * | |
| 1639 * Shift and round. Perform a shift right. After shifting, use | |
| 1640 * the last bit shifted out of the LSB to round the result up | |
| 1641 * or down. | |
| 1642 * | |
| 1643 * If var2 is positive perform a arithmetic left shift | |
| 1644 * with saturation (see shl() above). | |
| 1645 * | |
| 1646 * If var2 is zero simply return var1. | |
| 1647 * | |
| 1648 * If var2 is negative perform a arithmetic right shift (shr) | |
| 1649 * of var1 by (-var2)+1. Add the LS bit of the result to var1 | |
| 1650 * shifted right (shr) by -var2. | |
| 1651 * | |
| 1652 * Note that there is no constraint on var2, so if var2 is | |
| 1653 * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff. | |
| 1654 * This is the reason the shl function is used. | |
| 1655 * | |
| 1656 * | |
| 1657 * KEYWORDS: | |
| 1658 * | |
| 1659 *************************************************************************/ | |
| 1660 | |
| 1661 Shortword shift_r(Shortword var1, Shortword var2) | |
| 1662 { | |
| 1663 Shortword swOut, | |
| 1664 swRnd; | |
| 1665 | |
| 1666 if (var2 >= 0) | |
| 1667 swOut = shl(var1, var2); | |
| 1668 else | |
| 1669 { | |
| 1670 | |
| 1671 /* right shift */ | |
| 1672 | |
| 1673 if (var2 < -15) | |
| 1674 { | |
| 1675 | |
| 1676 swOut = 0; | |
| 1677 | |
| 1678 } | |
| 1679 else | |
| 1680 { | |
| 1681 | |
| 1682 swRnd = shl(var1, var2 + 1) & 0x1; | |
| 1683 swOut = add(shl(var1, var2), swRnd); | |
| 1684 | |
| 1685 } | |
| 1686 } | |
| 1687 return (swOut); | |
| 1688 } | |
| 1689 | |
| 1690 /*************************************************************************** | |
| 1691 * | |
| 1692 * FUNCTION NAME: shl | |
| 1693 * | |
| 1694 * PURPOSE: | |
| 1695 * | |
| 1696 * Arithmetically shift the input left by var2. | |
| 1697 * | |
| 1698 * | |
| 1699 * INPUTS: | |
| 1700 * | |
| 1701 * var1 | |
| 1702 * 16 bit short signed integer (Shortword) whose value | |
| 1703 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1704 * var2 | |
| 1705 * 16 bit short signed integer (Shortword) whose value | |
| 1706 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1707 * | |
| 1708 * OUTPUTS: | |
| 1709 * | |
| 1710 * none | |
| 1711 * | |
| 1712 * RETURN VALUE: | |
| 1713 * | |
| 1714 * swOut | |
| 1715 * 16 bit short signed integer (Shortword) whose value | |
| 1716 * falls in the range | |
| 1717 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1718 * | |
| 1719 * IMPLEMENTATION: | |
| 1720 * | |
| 1721 * If Arithmetically shift the input left by var2. If var2 is | |
| 1722 * negative then an arithmetic shift right (shr) of var1 by | |
| 1723 * -var2 is performed. See description of shr for details. | |
| 1724 * When an arithmetic shift left is performed the var2 LS bits | |
| 1725 * are zero filled. | |
| 1726 * | |
| 1727 * The only exception is if the left shift causes an overflow | |
| 1728 * or underflow. In this case the LS bits are not modified. | |
| 1729 * The number returned is 0x8000 in the case of an underflow or | |
| 1730 * 0x7fff in the case of an overflow. | |
| 1731 * | |
| 1732 * The shl is equivalent to the Full-Rate GSM "<< n" operation. | |
| 1733 * Note that ANSI-C does not guarantee operation of the C ">>" | |
| 1734 * or "<<" operator for negative numbers - it is not specified | |
| 1735 * whether this shift is an arithmetic or logical shift. | |
| 1736 * | |
| 1737 * KEYWORDS: asl, arithmetic shift left, shift | |
| 1738 * | |
| 1739 *************************************************************************/ | |
| 1740 | |
| 1741 Shortword shl(Shortword var1, Shortword var2) | |
| 1742 { | |
| 1743 Shortword swOut; | |
| 1744 Longword L_Out; | |
| 1745 | |
| 1746 if (var2 == 0 || var1 == 0) | |
| 1747 { | |
| 1748 swOut = var1; | |
| 1749 } | |
| 1750 else if (var2 < 0) | |
| 1751 { | |
| 1752 | |
| 1753 /* perform a right shift */ | |
| 1754 /*-----------------------*/ | |
| 1755 | |
| 1756 if (var2 <= -15) | |
| 1757 { | |
| 1758 if (var1 < 0) | |
| 1759 swOut = (Shortword) 0xffff; | |
| 1760 else | |
| 1761 swOut = 0x0; | |
| 1762 } | |
| 1763 else | |
| 1764 swOut = shr(var1, -var2); | |
| 1765 | |
| 1766 } | |
| 1767 else | |
| 1768 { | |
| 1769 /* var2 > 0 */ | |
| 1770 if (var2 >= 15) | |
| 1771 { | |
| 1772 /* saturate */ | |
| 1773 if (var1 > 0) | |
| 1774 swOut = SW_MAX; | |
| 1775 else | |
| 1776 swOut = SW_MIN; | |
| 1777 } | |
| 1778 else | |
| 1779 { | |
| 1780 | |
| 1781 L_Out = (Longword) var1 *(1 << var2); | |
| 1782 | |
| 1783 swOut = (Shortword) L_Out; /* copy low portion to swOut, overflow | |
| 1784 * could have hpnd */ | |
| 1785 if (swOut != L_Out) | |
| 1786 { | |
| 1787 /* overflow */ | |
| 1788 if (var1 > 0) | |
| 1789 swOut = SW_MAX; /* saturate */ | |
| 1790 else | |
| 1791 swOut = SW_MIN; /* saturate */ | |
| 1792 } | |
| 1793 } | |
| 1794 } | |
| 1795 return (swOut); | |
| 1796 } | |
| 1797 | |
| 1798 /*************************************************************************** | |
| 1799 * | |
| 1800 * FUNCTION NAME: shr | |
| 1801 * | |
| 1802 * PURPOSE: | |
| 1803 * | |
| 1804 * Arithmetic shift right (or left). | |
| 1805 * Arithmetically shift the input right by var2. If var2 is | |
| 1806 * negative then an arithmetic shift left (shl) of var1 by | |
| 1807 * -var2 is performed. | |
| 1808 * | |
| 1809 * INPUTS: | |
| 1810 * | |
| 1811 * var1 | |
| 1812 * 16 bit short signed integer (Shortword) whose value | |
| 1813 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1814 * var2 | |
| 1815 * 16 bit short signed integer (Shortword) whose value | |
| 1816 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1817 * | |
| 1818 * OUTPUTS: | |
| 1819 * | |
| 1820 * none | |
| 1821 * | |
| 1822 * RETURN VALUE: | |
| 1823 * | |
| 1824 * swOut | |
| 1825 * 16 bit short signed integer (Shortword) whose value | |
| 1826 * falls in the range | |
| 1827 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1828 * | |
| 1829 * IMPLEMENTATION: | |
| 1830 * | |
| 1831 * Arithmetically shift the input right by var2. This | |
| 1832 * operation maintains the sign of the input number. If var2 is | |
| 1833 * negative then an arithmetic shift left (shl) of var1 by | |
| 1834 * -var2 is performed. See description of shl for details. | |
| 1835 * | |
| 1836 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
| 1837 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
| 1838 * operator for negative numbers. | |
| 1839 * | |
| 1840 * KEYWORDS: shift, arithmetic shift right, | |
| 1841 * | |
| 1842 *************************************************************************/ | |
| 1843 | |
| 1844 Shortword shr(Shortword var1, Shortword var2) | |
| 1845 { | |
| 1846 | |
| 1847 Shortword swMask, | |
| 1848 swOut; | |
| 1849 | |
| 1850 if (var2 == 0 || var1 == 0) | |
| 1851 swOut = var1; | |
| 1852 | |
| 1853 else if (var2 < 0) | |
| 1854 { | |
| 1855 /* perform an arithmetic left shift */ | |
| 1856 /*----------------------------------*/ | |
| 1857 if (var2 <= -15) | |
| 1858 { | |
| 1859 /* saturate */ | |
| 1860 if (var1 > 0) | |
| 1861 swOut = SW_MAX; | |
| 1862 else | |
| 1863 swOut = SW_MIN; | |
| 1864 } | |
| 1865 else | |
| 1866 swOut = shl(var1, -var2); | |
| 1867 } | |
| 1868 | |
| 1869 else | |
| 1870 { | |
| 1871 | |
| 1872 /* positive shift count */ | |
| 1873 /*----------------------*/ | |
| 1874 | |
| 1875 if (var2 >= 15) | |
| 1876 { | |
| 1877 if (var1 < 0) | |
| 1878 swOut = (Shortword) 0xffff; | |
| 1879 else | |
| 1880 swOut = 0x0; | |
| 1881 } | |
| 1882 else | |
| 1883 { | |
| 1884 /* take care of sign extension */ | |
| 1885 /*-----------------------------*/ | |
| 1886 | |
| 1887 swMask = 0; | |
| 1888 if (var1 < 0) | |
| 1889 { | |
| 1890 swMask = ~swMask << (16 - var2); | |
| 1891 } | |
| 1892 | |
| 1893 var1 >>= var2; | |
| 1894 swOut = swMask | var1; | |
| 1895 | |
| 1896 } | |
| 1897 } | |
| 1898 return (swOut); | |
| 1899 } | |
| 1900 | |
| 1901 /*************************************************************************** | |
| 1902 * | |
| 1903 * FUNCTION NAME: sub | |
| 1904 * | |
| 1905 * PURPOSE: | |
| 1906 * | |
| 1907 * Perform the subtraction of the two 16 bit input variable with | |
| 1908 * saturation. | |
| 1909 * | |
| 1910 * INPUTS: | |
| 1911 * | |
| 1912 * var1 | |
| 1913 * 16 bit short signed integer (Shortword) whose value | |
| 1914 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
| 1915 * var2 | |
| 1916 * 16 bit short signed integer (Shortword) whose value | |
| 1917 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
| 1918 * | |
| 1919 * OUTPUTS: | |
| 1920 * | |
| 1921 * none | |
| 1922 * | |
| 1923 * RETURN VALUE: | |
| 1924 * | |
| 1925 * swOut | |
| 1926 * 16 bit short signed integer (Shortword) whose value | |
| 1927 * falls in the range | |
| 1928 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
| 1929 * | |
| 1930 * IMPLEMENTATION: | |
| 1931 * | |
| 1932 * Perform the subtraction of the two 16 bit input variable with | |
| 1933 * saturation. | |
| 1934 * | |
| 1935 * swOut = var1 - var2 | |
| 1936 * | |
| 1937 * swOut is set to 0x7fff if the operation results in an | |
| 1938 * overflow. swOut is set to 0x8000 if the operation results | |
| 1939 * in an underflow. | |
| 1940 * | |
| 1941 * KEYWORDS: sub, subtraction | |
| 1942 * | |
| 1943 *************************************************************************/ | |
| 1944 Shortword sub(Shortword var1, Shortword var2) | |
| 1945 { | |
| 1946 Longword L_diff; | |
| 1947 Shortword swOut; | |
| 1948 | |
| 1949 L_diff = (Longword) var1 - var2; | |
| 1950 swOut = saturate(L_diff); | |
| 1951 | |
| 1952 return (swOut); | |
| 1953 } |
