1 /* This is a software fixed-point library. 2 Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25 /* This implements fixed-point arithmetic. 26 27 Contributed by Chao-ying Fu <fu@mips.com>. */ 28 29 /* To use this file, we need to define one of the following: 30 QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE, 31 TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE, 32 TA_MODE, UTA_MODE. 33 Then, all operators for this machine mode will be created. 34 35 Or, we need to define FROM_* TO_* for conversions from one mode to another 36 mode. The mode could be one of the following: 37 Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ 38 Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA 39 Signed integer: QI, HI, SI, DI, TI 40 Unsigned integer: UQI, UHI, USI, UDI, UTI 41 Floating-point: SF, DF 42 Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is 43 generated. */ 44 45 #include "tconfig.h" 46 #include "tsystem.h" 47 #include "coretypes.h" 48 #include "tm.h" 49 #include "libgcc_tm.h" 50 51 #ifndef MIN_UNITS_PER_WORD 52 #define MIN_UNITS_PER_WORD UNITS_PER_WORD 53 #endif 54 55 #include "fixed-bit.h" 56 57 #if defined(FIXED_ADD) && defined(L_add) 58 FIXED_C_TYPE 59 FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 60 { 61 FIXED_C_TYPE c; 62 INT_C_TYPE x, y, z; 63 memcpy (&x, &a, FIXED_SIZE); 64 memcpy (&y, &b, FIXED_SIZE); 65 z = x + y; 66 #if HAVE_PADDING_BITS 67 z = z << PADDING_BITS; 68 z = z >> PADDING_BITS; 69 #endif 70 memcpy (&c, &z, FIXED_SIZE); 71 return c; 72 } 73 #endif /* FIXED_ADD */ 74 75 #if defined(FIXED_SSADD) && defined(L_ssadd) 76 FIXED_C_TYPE 77 FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 78 { 79 FIXED_C_TYPE c; 80 INT_C_TYPE x, y, z; 81 memcpy (&x, &a, FIXED_SIZE); 82 memcpy (&y, &b, FIXED_SIZE); 83 z = x + y; 84 if ((((x ^ y) >> I_F_BITS) & 1) == 0) 85 { 86 if (((z ^ x) >> I_F_BITS) & 1) 87 { 88 z = 1; 89 z = z << I_F_BITS; 90 if (x >= 0) 91 z--; 92 } 93 } 94 #if HAVE_PADDING_BITS 95 z = z << PADDING_BITS; 96 z = z >> PADDING_BITS; 97 #endif 98 memcpy (&c, &z, FIXED_SIZE); 99 return c; 100 } 101 #endif /* FIXED_SSADD */ 102 103 #if defined(FIXED_USADD) && defined(L_usadd) 104 FIXED_C_TYPE 105 FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 106 { 107 FIXED_C_TYPE c; 108 INT_C_TYPE x, y, z; 109 memcpy (&x, &a, FIXED_SIZE); 110 memcpy (&y, &b, FIXED_SIZE); 111 z = x + y; 112 #if HAVE_PADDING_BITS 113 z = z << PADDING_BITS; 114 z = z >> PADDING_BITS; 115 #endif 116 if (z < x || z < y) /* max */ 117 { 118 z = -1; 119 #if HAVE_PADDING_BITS 120 z = z << PADDING_BITS; 121 z = z >> PADDING_BITS; 122 #endif 123 } 124 memcpy (&c, &z, FIXED_SIZE); 125 return c; 126 } 127 #endif /* FIXED_USADD */ 128 129 #if defined(FIXED_SUB) && defined(L_sub) 130 FIXED_C_TYPE 131 FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 132 { 133 FIXED_C_TYPE c; 134 INT_C_TYPE x, y, z; 135 memcpy (&x, &a, FIXED_SIZE); 136 memcpy (&y, &b, FIXED_SIZE); 137 z = x - y; 138 #if HAVE_PADDING_BITS 139 z = z << PADDING_BITS; 140 z = z >> PADDING_BITS; 141 #endif 142 memcpy (&c, &z, FIXED_SIZE); 143 return c; 144 } 145 #endif /* FIXED_SUB */ 146 147 #if defined(FIXED_SSSUB) && defined(L_sssub) 148 FIXED_C_TYPE 149 FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 150 { 151 FIXED_C_TYPE c; 152 INT_C_TYPE x, y, z; 153 memcpy (&x, &a, FIXED_SIZE); 154 memcpy (&y, &b, FIXED_SIZE); 155 z = x - y; 156 if (((x ^ y) >> I_F_BITS) & 1) 157 { 158 if (((z ^ x) >> I_F_BITS) & 1) 159 { 160 z = 1; 161 z = z << I_F_BITS; 162 if (x >= 0) 163 z--; 164 } 165 } 166 #if HAVE_PADDING_BITS 167 z = z << PADDING_BITS; 168 z = z >> PADDING_BITS; 169 #endif 170 memcpy (&c, &z, FIXED_SIZE); 171 return c; 172 } 173 #endif /* FIXED_SSSUB */ 174 175 #if defined(FIXED_USSUB) && defined(L_ussub) 176 FIXED_C_TYPE 177 FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 178 { 179 FIXED_C_TYPE c; 180 INT_C_TYPE x, y, z; 181 memcpy (&x, &a, FIXED_SIZE); 182 memcpy (&y, &b, FIXED_SIZE); 183 z = x - y; 184 if (x < y) 185 z = 0; 186 #if HAVE_PADDING_BITS 187 z = z << PADDING_BITS; 188 z = z >> PADDING_BITS; 189 #endif 190 memcpy (&c, &z, FIXED_SIZE); 191 return c; 192 } 193 #endif /* FIXED_USSUB */ 194 195 #if defined(FIXED_SATURATE1) && defined(L_saturate1) 196 void 197 FIXED_SATURATE1 (DINT_C_TYPE *a) 198 { 199 DINT_C_TYPE max, min; 200 max = (DINT_C_TYPE)1 << I_F_BITS; 201 max = max - 1; 202 #if MODE_UNSIGNED == 0 203 min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1); 204 min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS); 205 #else 206 min = 0; 207 #endif 208 if (*a > max) 209 *a = max; 210 else if (*a < min) 211 *a = min; 212 } 213 #endif /* FIXED_SATURATE1 */ 214 215 #if defined(FIXED_SATURATE2) && defined(L_saturate2) 216 void 217 FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low) 218 { 219 INT_C_TYPE r_max, s_max, r_min, s_min; 220 r_max = 0; 221 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS 222 s_max = (INT_C_TYPE)1 << I_F_BITS; 223 s_max = s_max - 1; 224 #else 225 s_max = -1; 226 #endif 227 #if MODE_UNSIGNED == 0 228 r_min = -1; 229 s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1); 230 s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS); 231 #else 232 r_min = 0; 233 s_min = 0; 234 #endif 235 236 if (*high > r_max 237 || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max)) 238 { 239 *high = r_max; 240 *low = s_max; 241 } 242 else if (*high < r_min || 243 (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min)) 244 { 245 *high = r_min; 246 *low = s_min; 247 } 248 } 249 #endif /* FIXED_SATURATE2 */ 250 251 #if defined(FIXED_MULHELPER) && defined(L_mulhelper) 252 FIXED_C_TYPE 253 FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp) 254 { 255 FIXED_C_TYPE c; 256 INT_C_TYPE x, y; 257 258 #if defined (DINT_C_TYPE) 259 INT_C_TYPE z; 260 DINT_C_TYPE dx, dy, dz; 261 memcpy (&x, &a, FIXED_SIZE); 262 memcpy (&y, &b, FIXED_SIZE); 263 dx = (DINT_C_TYPE) x; 264 dy = (DINT_C_TYPE) y; 265 dz = dx * dy; 266 /* Round the result by adding (1 << (FBITS -1)). */ 267 dz += ((DINT_C_TYPE) 1 << (FBITS - 1)); 268 dz = dz >> FBITS; 269 if (satp) 270 FIXED_SATURATE1 (&dz); 271 272 z = (INT_C_TYPE) dz; 273 #if HAVE_PADDING_BITS 274 z = z << PADDING_BITS; 275 z = z >> PADDING_BITS; 276 #endif 277 memcpy (&c, &z, FIXED_SIZE); 278 return c; 279 280 #else /* No DINT_C_TYPE */ 281 /* The result of multiplication expands to two INT_C_TYPE. */ 282 INTunion aa, bb; 283 INTunion a_high, a_low, b_high, b_low; 284 INTunion high_high, high_low, low_high, low_low; 285 INTunion r, s, temp1, temp2; 286 INT_C_TYPE carry = 0; 287 INT_C_TYPE z; 288 289 memcpy (&x, &a, FIXED_SIZE); 290 memcpy (&y, &b, FIXED_SIZE); 291 292 /* Decompose a and b. */ 293 aa.ll = x; 294 bb.ll = y; 295 296 a_high.s.low = aa.s.high; 297 a_high.s.high = 0; 298 a_low.s.low = aa.s.low; 299 a_low.s.high = 0; 300 b_high.s.low = bb.s.high; 301 b_high.s.high = 0; 302 b_low.s.low = bb.s.low; 303 b_low.s.high = 0; 304 305 /* Perform four multiplications. */ 306 low_low.ll = a_low.ll * b_low.ll; 307 low_high.ll = a_low.ll * b_high.ll; 308 high_low.ll = a_high.ll * b_low.ll; 309 high_high.ll = a_high.ll * b_high.ll; 310 311 /* Accumulate four results to {r, s}. */ 312 temp1.s.high = high_low.s.low; 313 temp1.s.low = 0; 314 s.ll = low_low.ll + temp1.ll; 315 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll 316 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll) 317 carry ++; /* Carry. */ 318 temp1.ll = s.ll; 319 temp2.s.high = low_high.s.low; 320 temp2.s.low = 0; 321 s.ll = temp1.ll + temp2.ll; 322 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll 323 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll) 324 carry ++; /* Carry. */ 325 326 temp1.s.low = high_low.s.high; 327 temp1.s.high = 0; 328 r.ll = high_high.ll + temp1.ll; 329 temp1.s.low = low_high.s.high; 330 temp1.s.high = 0; 331 r.ll = r.ll + temp1.ll + carry; 332 333 #if MODE_UNSIGNED == 0 334 /* For signed types, we need to add neg(y) to r, if x < 0. */ 335 if (x < 0) 336 r.ll = r.ll - y; 337 /* We need to add neg(x) to r, if y < 0. */ 338 if (y < 0) 339 r.ll = r.ll - x; 340 #endif 341 342 /* Round the result by adding (1 << (FBITS -1)). */ 343 temp1.ll = s.ll; 344 s.ll += ((INT_C_TYPE) 1 << (FBITS -1)); 345 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll 346 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1))) 347 r.ll += 1; 348 349 /* Shift right the result by FBITS. */ 350 #if FBITS == FIXED_WIDTH 351 /* This happens only for unsigned types without any padding bits. 352 So, it is safe to set r.ll to 0 as it is logically shifted right. */ 353 s.ll = r.ll; 354 r.ll = 0; 355 #else 356 s.ll = ((UINT_C_TYPE)s.ll) >> FBITS; 357 temp1.ll = r.ll << (FIXED_WIDTH - FBITS); 358 s.ll = s.ll | temp1.ll; 359 r.ll = r.ll >> FBITS; 360 #endif 361 362 if (satp) 363 FIXED_SATURATE2 (&r.ll, &s.ll); 364 365 z = (INT_C_TYPE) s.ll; 366 #if HAVE_PADDING_BITS 367 z = z << PADDING_BITS; 368 z = z >> PADDING_BITS; 369 #endif 370 memcpy (&c, &z, FIXED_SIZE); 371 return c; 372 #endif 373 } 374 #endif /* FIXED_MULHELPER */ 375 376 #if defined(FIXED_MUL) && defined(L_mul) 377 FIXED_C_TYPE 378 FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 379 { 380 return FIXED_MULHELPER (a, b, 0); 381 } 382 #endif /* FIXED_MUL */ 383 384 #if defined(FIXED_SSMUL) && defined(L_ssmul) 385 FIXED_C_TYPE 386 FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 387 { 388 return FIXED_MULHELPER (a, b, 1); 389 } 390 #endif /* FIXED_SSMUL */ 391 392 #if defined(FIXED_USMUL) && defined(L_usmul) 393 FIXED_C_TYPE 394 FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 395 { 396 return FIXED_MULHELPER (a, b, 1); 397 } 398 #endif /* FIXED_USMUL */ 399 400 #if defined(FIXED_DIVHELPER) && defined(L_divhelper) 401 FIXED_C_TYPE 402 FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp) 403 { 404 FIXED_C_TYPE c; 405 INT_C_TYPE x, y; 406 INT_C_TYPE z; 407 408 #if defined (DINT_C_TYPE) 409 DINT_C_TYPE dx, dy, dz; 410 memcpy (&x, &a, FIXED_SIZE); 411 memcpy (&y, &b, FIXED_SIZE); 412 dx = (DINT_C_TYPE) x; 413 dy = (DINT_C_TYPE) y; 414 dx = dx << FBITS; 415 dz = dx / dy; 416 if (satp) 417 FIXED_SATURATE1 (&dz); 418 z = (INT_C_TYPE) dz; 419 #if HAVE_PADDING_BITS 420 z = z << PADDING_BITS; 421 z = z >> PADDING_BITS; 422 #endif 423 memcpy (&c, &z, FIXED_SIZE); 424 return c; 425 426 #else /* No DINT_C_TYPE */ 427 INT_C_TYPE pos_a, pos_b, r, s; 428 INT_C_TYPE quo_r, quo_s, mod, temp; 429 word_type i; 430 #if MODE_UNSIGNED == 0 431 word_type num_of_neg = 0; 432 #endif 433 434 memcpy (&x, &a, FIXED_SIZE); 435 memcpy (&y, &b, FIXED_SIZE); 436 pos_a = x; 437 pos_b = y; 438 439 #if MODE_UNSIGNED == 0 440 /* If a < 0, negate a. */ 441 if (pos_a < 0) 442 { 443 pos_a = -pos_a; 444 num_of_neg ++; 445 } 446 /* If b < 0, negate b. */ 447 if (pos_b < 0) 448 { 449 pos_b = -pos_b; 450 num_of_neg ++; 451 } 452 #endif 453 454 /* Left shift pos_a to {r, s} by FBITS. */ 455 #if FBITS == FIXED_WIDTH 456 /* This happens only for unsigned types without any padding bits. */ 457 r = pos_a; 458 s = 0; 459 #else 460 s = pos_a << FBITS; 461 r = pos_a >> (FIXED_WIDTH - FBITS); 462 #endif 463 464 /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */ 465 quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b; 466 mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b; 467 quo_s = 0; 468 469 for (i = 0; i < FIXED_WIDTH; i++) 470 { 471 /* Record the leftmost bit of mod. */ 472 word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1; 473 /* Shift left mod by 1 bit. */ 474 mod = mod << 1; 475 /* Test the leftmost bit of s to add to mod. */ 476 if ((s >> (FIXED_WIDTH - 1)) & 1) 477 mod ++; 478 /* Shift left quo_s by 1 bit. */ 479 quo_s = quo_s << 1; 480 /* Try to calculate (mod - pos_b). */ 481 temp = mod - pos_b; 482 if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b) 483 { 484 quo_s ++; 485 mod = temp; 486 } 487 /* Shift left s by 1 bit. */ 488 s = s << 1; 489 } 490 491 #if MODE_UNSIGNED == 0 492 if (num_of_neg == 1) 493 { 494 quo_s = -quo_s; 495 if (quo_s == 0) 496 quo_r = -quo_r; 497 else 498 quo_r = ~quo_r; 499 } 500 #endif 501 if (satp) 502 FIXED_SATURATE2 (&quo_r, &quo_s); 503 z = quo_s; 504 #if HAVE_PADDING_BITS 505 z = z << PADDING_BITS; 506 z = z >> PADDING_BITS; 507 #endif 508 memcpy (&c, &z, FIXED_SIZE); 509 return c; 510 #endif 511 } 512 #endif /* FIXED_DIVHELPER */ 513 514 #if defined(FIXED_DIV) && defined(L_div) 515 FIXED_C_TYPE 516 FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 517 { 518 return FIXED_DIVHELPER (a, b, 0); 519 } 520 #endif /* FIXED_DIV */ 521 522 523 #if defined(FIXED_UDIV) && defined(L_udiv) 524 FIXED_C_TYPE 525 FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 526 { 527 return FIXED_DIVHELPER (a, b, 0); 528 } 529 #endif /* FIXED_UDIV */ 530 531 #if defined(FIXED_SSDIV) && defined(L_ssdiv) 532 FIXED_C_TYPE 533 FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 534 { 535 return FIXED_DIVHELPER (a, b, 1); 536 } 537 #endif /* FIXED_SSDIV */ 538 539 #if defined(FIXED_USDIV) && defined(L_usdiv) 540 FIXED_C_TYPE 541 FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 542 { 543 return FIXED_DIVHELPER (a, b, 1); 544 } 545 #endif /* FIXED_USDIV */ 546 547 #if defined(FIXED_NEG) && defined(L_neg) 548 FIXED_C_TYPE 549 FIXED_NEG (FIXED_C_TYPE a) 550 { 551 FIXED_C_TYPE c; 552 INT_C_TYPE x, z; 553 memcpy (&x, &a, FIXED_SIZE); 554 z = -x; 555 #if HAVE_PADDING_BITS 556 z = z << PADDING_BITS; 557 z = z >> PADDING_BITS; 558 #endif 559 memcpy (&c, &z, FIXED_SIZE); 560 return c; 561 } 562 #endif /* FIXED_NEG */ 563 564 #if defined(FIXED_SSNEG) && defined(L_ssneg) 565 FIXED_C_TYPE 566 FIXED_SSNEG (FIXED_C_TYPE a) 567 { 568 FIXED_C_TYPE c; 569 INT_C_TYPE x, y, z; 570 memcpy (&y, &a, FIXED_SIZE); 571 x = 0; 572 z = x - y; 573 if (((x ^ y) >> I_F_BITS) & 1) 574 { 575 if (((z ^ x) >> I_F_BITS) & 1) 576 { 577 z = 1; 578 z = z << I_F_BITS; 579 if (x >= 0) 580 z--; 581 } 582 } 583 #if HAVE_PADDING_BITS 584 z = z << PADDING_BITS; 585 z = z >> PADDING_BITS; 586 #endif 587 memcpy (&c, &z, FIXED_SIZE); 588 return c; 589 } 590 #endif /* FIXED_SSNEG */ 591 592 #if defined(FIXED_USNEG) && defined(L_usneg) 593 FIXED_C_TYPE 594 FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__))) 595 { 596 FIXED_C_TYPE c; 597 INT_C_TYPE z; 598 z = 0; 599 memcpy (&c, &z, FIXED_SIZE); 600 return c; 601 } 602 #endif /* FIXED_USNEG */ 603 604 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper) 605 FIXED_C_TYPE 606 FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp) 607 { 608 FIXED_C_TYPE c; 609 INT_C_TYPE x, z; 610 611 #if defined (DINT_C_TYPE) 612 DINT_C_TYPE dx, dz; 613 memcpy (&x, &a, FIXED_SIZE); 614 dx = (DINT_C_TYPE) x; 615 if (b >= FIXED_WIDTH) 616 dz = dx << FIXED_WIDTH; 617 else 618 dz = dx << b; 619 if (satp) 620 FIXED_SATURATE1 (&dz); 621 z = (INT_C_TYPE) dz; 622 #if HAVE_PADDING_BITS 623 z = z << PADDING_BITS; 624 z = z >> PADDING_BITS; 625 #endif 626 memcpy (&c, &z, FIXED_SIZE); 627 return c; 628 629 #else /* No DINT_C_TYPE */ 630 INT_C_TYPE r, s; 631 memcpy (&x, &a, FIXED_SIZE); 632 /* We need to shift left x by b bits to {r, s}. */ 633 if (b >= FIXED_WIDTH) 634 { 635 r = b; 636 s = 0; 637 } 638 else 639 { 640 s = x << b; 641 r = x >> (FIXED_WIDTH - b); 642 } 643 if (satp) 644 FIXED_SATURATE2 (&r, &s); 645 z = s; 646 #if HAVE_PADDING_BITS 647 z = z << PADDING_BITS; 648 z = z >> PADDING_BITS; 649 #endif 650 memcpy (&c, &z, FIXED_SIZE); 651 return c; 652 #endif 653 } 654 #endif /* FIXED_ASHLHELPER */ 655 656 #if defined(FIXED_ASHL) && defined(L_ashl) 657 FIXED_C_TYPE 658 FIXED_ASHL (FIXED_C_TYPE a, word_type b) 659 { 660 return FIXED_ASHLHELPER (a, b, 0); 661 } 662 #endif /* FIXED_ASHL */ 663 664 #if defined(FIXED_ASHR) && defined(L_ashr) 665 FIXED_C_TYPE 666 FIXED_ASHR (FIXED_C_TYPE a, word_type b) 667 { 668 FIXED_C_TYPE c; 669 INT_C_TYPE x, z; 670 memcpy (&x, &a, FIXED_SIZE); 671 z = x >> b; 672 #if HAVE_PADDING_BITS 673 z = z << PADDING_BITS; 674 z = z >> PADDING_BITS; 675 #endif 676 memcpy (&c, &z, FIXED_SIZE); 677 return c; 678 } 679 #endif /* FIXED_ASHR */ 680 681 #if defined(FIXED_LSHR) && defined(L_lshr) 682 FIXED_C_TYPE 683 FIXED_LSHR (FIXED_C_TYPE a, word_type b) 684 { 685 FIXED_C_TYPE c; 686 INT_C_TYPE x, z; 687 memcpy (&x, &a, FIXED_SIZE); 688 z = x >> b; 689 #if HAVE_PADDING_BITS 690 z = z << PADDING_BITS; 691 z = z >> PADDING_BITS; 692 #endif 693 memcpy (&c, &z, FIXED_SIZE); 694 return c; 695 } 696 #endif /* FIXED_LSHR */ 697 698 #if defined(FIXED_SSASHL) && defined(L_ssashl) 699 FIXED_C_TYPE 700 FIXED_SSASHL (FIXED_C_TYPE a, word_type b) 701 { 702 return FIXED_ASHLHELPER (a, b, 1); 703 } 704 #endif /* FIXED_SSASHL */ 705 706 #if defined(FIXED_USASHL) && defined(L_usashl) 707 FIXED_C_TYPE 708 FIXED_USASHL (FIXED_C_TYPE a, word_type b) 709 { 710 return FIXED_ASHLHELPER (a, b, 1); 711 } 712 #endif /* FIXED_USASHL */ 713 714 #if defined(FIXED_CMP) && defined(L_cmp) 715 word_type 716 FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b) 717 { 718 INT_C_TYPE x, y; 719 memcpy (&x, &a, FIXED_SIZE); 720 memcpy (&y, &b, FIXED_SIZE); 721 722 if (x < y) 723 return 0; 724 else if (x > y) 725 return 2; 726 727 return 1; 728 } 729 #endif /* FIXED_CMP */ 730 731 /* Fixed -> Fixed. */ 732 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4 733 TO_FIXED_C_TYPE 734 FRACT (FROM_FIXED_C_TYPE a) 735 { 736 TO_FIXED_C_TYPE c; 737 FROM_INT_C_TYPE x; 738 TO_INT_C_TYPE z; 739 int shift_amount; 740 memcpy (&x, &a, FROM_FIXED_SIZE); 741 #if TO_FBITS > FROM_FBITS /* Need left shift. */ 742 shift_amount = TO_FBITS - FROM_FBITS; 743 z = (TO_INT_C_TYPE) x; 744 z = z << shift_amount; 745 #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */ 746 shift_amount = FROM_FBITS - TO_FBITS; 747 x = x >> shift_amount; 748 z = (TO_INT_C_TYPE) x; 749 #endif /* TO_FBITS > FROM_FBITS */ 750 751 #if TO_HAVE_PADDING_BITS 752 z = z << TO_PADDING_BITS; 753 z = z >> TO_PADDING_BITS; 754 #endif 755 memcpy (&c, &z, TO_FIXED_SIZE); 756 return c; 757 } 758 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */ 759 760 /* Fixed -> Fixed with saturation. */ 761 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4 762 TO_FIXED_C_TYPE 763 SATFRACT (FROM_FIXED_C_TYPE a) 764 { 765 TO_FIXED_C_TYPE c; 766 TO_INT_C_TYPE z; 767 FROM_INT_C_TYPE x; 768 #if FROM_MODE_UNSIGNED == 0 769 BIG_SINT_C_TYPE high, low; 770 BIG_SINT_C_TYPE max_high, max_low; 771 BIG_SINT_C_TYPE min_high, min_low; 772 #else 773 BIG_UINT_C_TYPE high, low; 774 BIG_UINT_C_TYPE max_high, max_low; 775 BIG_UINT_C_TYPE min_high, min_low; 776 #endif 777 #if TO_FBITS > FROM_FBITS 778 BIG_UINT_C_TYPE utemp; 779 #endif 780 #if TO_MODE_UNSIGNED == 0 781 BIG_SINT_C_TYPE stemp; 782 #endif 783 #if TO_FBITS != FROM_FBITS 784 int shift_amount; 785 #endif 786 memcpy (&x, &a, FROM_FIXED_SIZE); 787 788 /* Step 1. We need to store x to {high, low}. */ 789 #if FROM_MODE_UNSIGNED == 0 790 low = (BIG_SINT_C_TYPE) x; 791 if (x < 0) 792 high = -1; 793 else 794 high = 0; 795 #else 796 low = (BIG_UINT_C_TYPE) x; 797 high = 0; 798 #endif 799 800 /* Step 2. We need to shift {high, low}. */ 801 #if TO_FBITS > FROM_FBITS /* Left shift. */ 802 shift_amount = TO_FBITS - FROM_FBITS; 803 utemp = (BIG_UINT_C_TYPE) low; 804 utemp = utemp >> (BIG_WIDTH - shift_amount); 805 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 806 low = low << shift_amount; 807 #elif TO_FBITS < FROM_FBITS /* Right shift. */ 808 shift_amount = FROM_FBITS - TO_FBITS; 809 low = low >> shift_amount; 810 #endif 811 812 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 813 max_high = 0; 814 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 815 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 816 max_low = max_low - 1; 817 #else 818 max_low = -1; 819 #endif 820 821 #if TO_MODE_UNSIGNED == 0 822 min_high = -1; 823 stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1); 824 stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS); 825 min_low = stemp; 826 #else 827 min_high = 0; 828 min_low = 0; 829 #endif 830 831 #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0 832 /* Signed -> Signed. */ 833 if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 834 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 835 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 836 low = max_low; /* Maximum. */ 837 else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high 838 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high 839 && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low)) 840 low = min_low; /* Minimum. */ 841 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1 842 /* Unigned -> Unsigned. */ 843 if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 844 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 845 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 846 low = max_low; /* Maximum. */ 847 #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1 848 /* Signed -> Unsigned. */ 849 if (x < 0) 850 low = 0; /* Minimum. */ 851 else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 852 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 853 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 854 low = max_low; /* Maximum. */ 855 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0 856 /* Unsigned -> Signed. */ 857 if ((BIG_SINT_C_TYPE) high < 0) 858 low = max_low; /* Maximum. */ 859 else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 860 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 861 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 862 low = max_low; /* Maximum. */ 863 #endif 864 865 /* Step 4. Store the result. */ 866 z = (TO_INT_C_TYPE) low; 867 #if TO_HAVE_PADDING_BITS 868 z = z << TO_PADDING_BITS; 869 z = z >> TO_PADDING_BITS; 870 #endif 871 memcpy (&c, &z, TO_FIXED_SIZE); 872 return c; 873 } 874 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */ 875 876 /* Fixed -> Int. */ 877 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1 878 TO_INT_C_TYPE 879 FRACT (FROM_FIXED_C_TYPE a) 880 { 881 FROM_INT_C_TYPE x; 882 TO_INT_C_TYPE z; 883 FROM_INT_C_TYPE i = 0; 884 memcpy (&x, &a, FROM_FIXED_SIZE); 885 886 #if FROM_MODE_UNSIGNED == 0 887 if (x < 0) 888 { 889 #if FROM_FIXED_WIDTH == FROM_FBITS 890 if (x != 0) 891 i = 1; 892 #else 893 if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0) 894 i = 1; 895 #endif 896 } 897 #endif 898 899 #if FROM_FIXED_WIDTH == FROM_FBITS 900 x = 0; 901 #else 902 x = x >> FROM_FBITS; 903 #endif 904 x = x + i; 905 z = (TO_INT_C_TYPE) x; 906 return z; 907 } 908 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */ 909 910 /* Fixed -> Unsigned int. */ 911 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2 912 TO_INT_C_TYPE 913 FRACTUNS (FROM_FIXED_C_TYPE a) 914 { 915 FROM_INT_C_TYPE x; 916 TO_INT_C_TYPE z; 917 FROM_INT_C_TYPE i = 0; 918 memcpy (&x, &a, FROM_FIXED_SIZE); 919 920 #if FROM_MODE_UNSIGNED == 0 921 if (x < 0) 922 { 923 #if FROM_FIXED_WIDTH == FROM_FBITS 924 if (x != 0) 925 i = 1; 926 #else 927 if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0) 928 i = 1; 929 #endif 930 } 931 #endif 932 933 #if FROM_FIXED_WIDTH == FROM_FBITS 934 x = 0; 935 #else 936 x = x >> FROM_FBITS; 937 #endif 938 x = x + i; 939 z = (TO_INT_C_TYPE) x; 940 return z; 941 } 942 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */ 943 944 /* Int -> Fixed. */ 945 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4 946 TO_FIXED_C_TYPE 947 FRACT (FROM_INT_C_TYPE a) 948 { 949 TO_FIXED_C_TYPE c; 950 TO_INT_C_TYPE z; 951 z = (TO_INT_C_TYPE) a; 952 #if TO_FIXED_WIDTH == TO_FBITS 953 z = 0; 954 #else 955 z = z << TO_FBITS; 956 #endif 957 #if TO_HAVE_PADDING_BITS 958 z = z << TO_PADDING_BITS; 959 z = z >> TO_PADDING_BITS; 960 #endif 961 memcpy (&c, &z, TO_FIXED_SIZE); 962 return c; 963 } 964 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */ 965 966 /* Signed int -> Fixed with saturation. */ 967 #if defined(SATFRACT) && defined(L_satfract) &&FROM_TYPE == 1 && TO_TYPE == 4 968 TO_FIXED_C_TYPE 969 SATFRACT (FROM_INT_C_TYPE a) 970 { 971 TO_FIXED_C_TYPE c; 972 TO_INT_C_TYPE z; 973 FROM_INT_C_TYPE x = a; 974 BIG_SINT_C_TYPE high, low; 975 BIG_SINT_C_TYPE max_high, max_low; 976 BIG_SINT_C_TYPE min_high, min_low; 977 #if TO_MODE_UNSIGNED == 0 978 BIG_SINT_C_TYPE stemp; 979 #endif 980 #if BIG_WIDTH != TO_FBITS 981 BIG_UINT_C_TYPE utemp; 982 int shift_amount; 983 #endif 984 985 /* Step 1. We need to store x to {high, low}. */ 986 low = (BIG_SINT_C_TYPE) x; 987 if (x < 0) 988 high = -1; 989 else 990 high = 0; 991 992 /* Step 2. We need to left shift {high, low}. */ 993 #if BIG_WIDTH == TO_FBITS 994 high = low; 995 low = 0; 996 #else 997 shift_amount = TO_FBITS; 998 utemp = (BIG_UINT_C_TYPE) low; 999 utemp = utemp >> (BIG_WIDTH - shift_amount); 1000 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 1001 low = low << shift_amount; 1002 #endif 1003 1004 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 1005 max_high = 0; 1006 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1007 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 1008 max_low = max_low - 1; 1009 #else 1010 max_low = -1; 1011 #endif 1012 1013 #if TO_MODE_UNSIGNED == 0 1014 min_high = -1; 1015 stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1); 1016 stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS); 1017 min_low = stemp; 1018 #else 1019 min_high = 0; 1020 min_low = 0; 1021 #endif 1022 1023 #if TO_MODE_UNSIGNED == 0 1024 /* Signed -> Signed. */ 1025 if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 1026 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 1027 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1028 low = max_low; /* Maximum. */ 1029 else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high 1030 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high 1031 && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low)) 1032 low = min_low; /* Minimum. */ 1033 #else 1034 /* Signed -> Unsigned. */ 1035 if (x < 0) 1036 low = 0; /* Minimum. */ 1037 else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 1038 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 1039 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1040 low = max_low; /* Maximum. */ 1041 #endif 1042 1043 /* Step 4. Store the result. */ 1044 z = (TO_INT_C_TYPE) low; 1045 #if TO_HAVE_PADDING_BITS 1046 z = z << TO_PADDING_BITS; 1047 z = z >> TO_PADDING_BITS; 1048 #endif 1049 memcpy (&c, &z, TO_FIXED_SIZE); 1050 return c; 1051 } 1052 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */ 1053 1054 /* Unsigned int -> Fixed. */ 1055 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4 1056 TO_FIXED_C_TYPE 1057 FRACTUNS (FROM_INT_C_TYPE a) 1058 { 1059 TO_FIXED_C_TYPE c; 1060 TO_INT_C_TYPE z; 1061 z = (TO_INT_C_TYPE) a; 1062 #if TO_FIXED_WIDTH == TO_FBITS 1063 z = 0; 1064 #else 1065 z = z << TO_FBITS; 1066 #endif 1067 #if TO_HAVE_PADDING_BITS 1068 z = z << TO_PADDING_BITS; 1069 z = z >> TO_PADDING_BITS; 1070 #endif 1071 memcpy (&c, &z, TO_FIXED_SIZE); 1072 return c; 1073 } 1074 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */ 1075 1076 /* Unsigned int -> Fixed with saturation. */ 1077 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4 1078 TO_FIXED_C_TYPE 1079 SATFRACTUNS (FROM_INT_C_TYPE a) 1080 { 1081 TO_FIXED_C_TYPE c; 1082 TO_INT_C_TYPE z; 1083 FROM_INT_C_TYPE x = a; 1084 BIG_UINT_C_TYPE high, low; 1085 BIG_UINT_C_TYPE max_high, max_low; 1086 #if BIG_WIDTH != TO_FBITS 1087 BIG_UINT_C_TYPE utemp; 1088 int shift_amount; 1089 #endif 1090 1091 /* Step 1. We need to store x to {high, low}. */ 1092 low = (BIG_UINT_C_TYPE) x; 1093 high = 0; 1094 1095 /* Step 2. We need to left shift {high, low}. */ 1096 #if BIG_WIDTH == TO_FBITS 1097 high = low; 1098 low = 0; 1099 #else 1100 shift_amount = TO_FBITS; 1101 utemp = (BIG_UINT_C_TYPE) low; 1102 utemp = utemp >> (BIG_WIDTH - shift_amount); 1103 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 1104 low = low << shift_amount; 1105 #endif 1106 1107 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 1108 max_high = 0; 1109 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1110 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 1111 max_low = max_low - 1; 1112 #else 1113 max_low = -1; 1114 #endif 1115 1116 #if TO_MODE_UNSIGNED == 1 1117 /* Unigned -> Unsigned. */ 1118 if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 1119 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 1120 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1121 low = max_low; /* Maximum. */ 1122 #else 1123 /* Unsigned -> Signed. */ 1124 if ((BIG_SINT_C_TYPE) high < 0) 1125 low = max_low; /* Maximum. */ 1126 else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 1127 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 1128 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1129 low = max_low; /* Maximum. */ 1130 #endif 1131 1132 /* Step 4. Store the result. */ 1133 z = (TO_INT_C_TYPE) low; 1134 #if TO_HAVE_PADDING_BITS 1135 z = z << TO_PADDING_BITS; 1136 z = z >> TO_PADDING_BITS; 1137 #endif 1138 memcpy (&c, &z, TO_FIXED_SIZE); 1139 return c; 1140 } 1141 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */ 1142 1143 /* Fixed -> Float. */ 1144 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3 1145 TO_FLOAT_C_TYPE 1146 FRACT (FROM_FIXED_C_TYPE a) 1147 { 1148 FROM_INT_C_TYPE x; 1149 TO_FLOAT_C_TYPE z; 1150 memcpy (&x, &a, FROM_FIXED_SIZE); 1151 z = (TO_FLOAT_C_TYPE) x; 1152 z = z / BASE; 1153 return z; 1154 } 1155 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */ 1156 1157 /* Float -> Fixed. */ 1158 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4 1159 TO_FIXED_C_TYPE 1160 FRACT (FROM_FLOAT_C_TYPE a) 1161 { 1162 FROM_FLOAT_C_TYPE temp; 1163 TO_INT_C_TYPE z; 1164 TO_FIXED_C_TYPE c; 1165 1166 temp = a * BASE; 1167 z = (TO_INT_C_TYPE) temp; 1168 #if TO_HAVE_PADDING_BITS 1169 z = z << TO_PADDING_BITS; 1170 z = z >> TO_PADDING_BITS; 1171 #endif 1172 memcpy (&c, &z, TO_FIXED_SIZE); 1173 return c; 1174 } 1175 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */ 1176 1177 /* Float -> Fixed with saturation. */ 1178 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4 1179 TO_FIXED_C_TYPE 1180 SATFRACT (FROM_FLOAT_C_TYPE a) 1181 { 1182 FROM_FLOAT_C_TYPE temp; 1183 TO_INT_C_TYPE z; 1184 TO_FIXED_C_TYPE c; 1185 1186 if (a >= FIXED_MAX) 1187 { 1188 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1189 z = (TO_INT_C_TYPE)1 << TO_I_F_BITS; 1190 z = z - 1; 1191 #else 1192 z = -1; 1193 #endif 1194 } 1195 else if (a <= FIXED_MIN) 1196 { 1197 #if TO_MODE_UNSIGNED == 0 1198 z = (TO_INT_C_TYPE)1 << TO_I_F_BITS; 1199 #else 1200 z = 0; 1201 #endif 1202 } 1203 else 1204 { 1205 temp = a * BASE; 1206 z = (TO_INT_C_TYPE) temp; 1207 } 1208 1209 #if TO_HAVE_PADDING_BITS 1210 z = z << TO_PADDING_BITS; 1211 z = z >> TO_PADDING_BITS; 1212 #endif 1213 memcpy (&c, &z, TO_FIXED_SIZE); 1214 return c; 1215 } 1216 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */ 1217 1218