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