1/* 2** libgcc support for software floating point. 3** Copyright (C) 1991 by Pipeline Associates, Inc. All rights reserved. 4** Permission is granted to do *anything* you want with this file, 5** commercial or otherwise, provided this message remains intact. So there! 6** I would appreciate receiving any updates/patches/changes that anyone 7** makes, and am willing to be the repository for said changes (am I 8** making a big mistake?). 9 10Warning! Only single-precision is actually implemented. This file 11won't really be much use until double-precision is supported. 12 13However, once that is done, this file might eventually become a 14replacement for libgcc1.c. It might also make possible 15cross-compilation for an IEEE target machine from a non-IEEE 16host such as a VAX. 17 18If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu. 19 20--> Double precision floating support added by James Carlson on 20 April 1998. 21 22** 23** Pat Wood 24** Pipeline Associates, Inc. 25** pipeline!phw@motown.com or 26** sun!pipeline!phw or 27** uunet!motown!pipeline!phw 28** 29** 05/01/91 -- V1.0 -- first release to gcc mailing lists 30** 05/04/91 -- V1.1 -- added float and double prototypes and return values 31** -- fixed problems with adding and subtracting zero 32** -- fixed rounding in truncdfsf2 33** -- fixed SWAP define and tested on 386 34*/ 35 36/* 37** The following are routines that replace the libgcc soft floating point 38** routines that are called automatically when -msoft-float is selected. 39** The support single and double precision IEEE format, with provisions 40** for byte-swapped machines (tested on 386). Some of the double-precision 41** routines work at full precision, but most of the hard ones simply punt 42** and call the single precision routines, producing a loss of accuracy. 43** long long support is not assumed or included. 44** Overall accuracy is close to IEEE (actually 68882) for single-precision 45** arithmetic. I think there may still be a 1 in 1000 chance of a bit 46** being rounded the wrong way during a multiply. I'm not fussy enough to 47** bother with it, but if anyone is, knock yourself out. 48** 49** Efficiency has only been addressed where it was obvious that something 50** would make a big difference. Anyone who wants to do this right for 51** best speed should go in and rewrite in assembler. 52** 53** I have tested this only on a 68030 workstation and 386/ix integrated 54** in with -msoft-float. 55*/ 56 57/* the following deal with IEEE single-precision numbers */ 58#define EXCESS 126 59#define SIGNBIT 0x80000000 60#define HIDDEN (1 << 23) 61#define SIGN(fp) ((fp) & SIGNBIT) 62#define EXP(fp) (((fp) >> 23) & 0xFF) 63#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN) 64#define PACK(s,e,m) ((s) | ((e) << 23) | (m)) 65 66/* the following deal with IEEE double-precision numbers */ 67#define EXCESSD 1022 68#define HIDDEND (1 << 20) 69#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 70#define SIGND(fp) ((fp.l.upper) & SIGNBIT) 71#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ 72 (fp.l.lower >> 22)) 73#define HIDDEND_LL ((long long)1 << 52) 74#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 75#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m)) 76 77/* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */ 78union double_long { 79 double d; 80#ifdef SWAP 81 struct { 82 unsigned long lower; 83 long upper; 84 } l; 85#else 86 struct { 87 long upper; 88 unsigned long lower; 89 } l; 90#endif 91 long long ll; 92}; 93 94union float_long 95 { 96 float f; 97 long l; 98 }; 99 100/* add two floats */ 101float 102__addsf3 (float a1, float a2) 103{ 104 register long mant1, mant2; 105 register union float_long fl1, fl2; 106 register int exp1, exp2; 107 int sign = 0; 108 109 fl1.f = a1; 110 fl2.f = a2; 111 112 /* check for zero args */ 113 if (!fl1.l) { 114 fl1.f = fl2.f; 115 goto test_done; 116 } 117 if (!fl2.l) 118 goto test_done; 119 120 exp1 = EXP (fl1.l); 121 exp2 = EXP (fl2.l); 122 123 if (exp1 > exp2 + 25) 124 goto test_done; 125 if (exp2 > exp1 + 25) { 126 fl1.f = fl2.f; 127 goto test_done; 128 } 129 130 /* do everything in excess precision so's we can round later */ 131 mant1 = MANT (fl1.l) << 6; 132 mant2 = MANT (fl2.l) << 6; 133 134 if (SIGN (fl1.l)) 135 mant1 = -mant1; 136 if (SIGN (fl2.l)) 137 mant2 = -mant2; 138 139 if (exp1 > exp2) 140 { 141 mant2 >>= exp1 - exp2; 142 } 143 else 144 { 145 mant1 >>= exp2 - exp1; 146 exp1 = exp2; 147 } 148 mant1 += mant2; 149 150 if (mant1 < 0) 151 { 152 mant1 = -mant1; 153 sign = SIGNBIT; 154 } 155 else if (!mant1) { 156 fl1.f = 0; 157 goto test_done; 158 } 159 160 /* normalize up */ 161 while (!(mant1 & 0xE0000000)) 162 { 163 mant1 <<= 1; 164 exp1--; 165 } 166 167 /* normalize down? */ 168 if (mant1 & (1 << 30)) 169 { 170 mant1 >>= 1; 171 exp1++; 172 } 173 174 /* round to even */ 175 mant1 += (mant1 & 0x40) ? 0x20 : 0x1F; 176 177 /* normalize down? */ 178 if (mant1 & (1 << 30)) 179 { 180 mant1 >>= 1; 181 exp1++; 182 } 183 184 /* lose extra precision */ 185 mant1 >>= 6; 186 187 /* turn off hidden bit */ 188 mant1 &= ~HIDDEN; 189 190 /* pack up and go home */ 191 fl1.l = PACK (sign, exp1, mant1); 192test_done: 193 return (fl1.f); 194} 195 196/* subtract two floats */ 197float 198__subsf3 (float a1, float a2) 199{ 200 register union float_long fl1, fl2; 201 202 fl1.f = a1; 203 fl2.f = a2; 204 205 /* check for zero args */ 206 if (!fl2.l) 207 return (fl1.f); 208 if (!fl1.l) 209 return (-fl2.f); 210 211 /* twiddle sign bit and add */ 212 fl2.l ^= SIGNBIT; 213 return __addsf3 (a1, fl2.f); 214} 215 216/* compare two floats */ 217long 218__cmpsf2 (float a1, float a2) 219{ 220 register union float_long fl1, fl2; 221 222 fl1.f = a1; 223 fl2.f = a2; 224 225 if (SIGN (fl1.l) && SIGN (fl2.l)) 226 { 227 fl1.l ^= SIGNBIT; 228 fl2.l ^= SIGNBIT; 229 } 230 if (fl1.l < fl2.l) 231 return (-1); 232 if (fl1.l > fl2.l) 233 return (1); 234 return (0); 235} 236 237/* multiply two floats */ 238float 239__mulsf3 (float a1, float a2) 240{ 241 register union float_long fl1, fl2; 242 register unsigned long result; 243 register int exp; 244 int sign; 245 246 fl1.f = a1; 247 fl2.f = a2; 248 249 if (!fl1.l || !fl2.l) { 250 fl1.f = 0; 251 goto test_done; 252 } 253 254 /* compute sign and exponent */ 255 sign = SIGN (fl1.l) ^ SIGN (fl2.l); 256 exp = EXP (fl1.l) - EXCESS; 257 exp += EXP (fl2.l); 258 259 fl1.l = MANT (fl1.l); 260 fl2.l = MANT (fl2.l); 261 262 /* the multiply is done as one 16x16 multiply and two 16x8 multiples */ 263 result = (fl1.l >> 8) * (fl2.l >> 8); 264 result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8; 265 result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8; 266 267 result >>= 2; 268 if (result & 0x20000000) 269 { 270 /* round */ 271 result += 0x20; 272 result >>= 6; 273 } 274 else 275 { 276 /* round */ 277 result += 0x10; 278 result >>= 5; 279 exp--; 280 } 281 if (result & (HIDDEN<<1)) { 282 result >>= 1; 283 exp++; 284 } 285 286 result &= ~HIDDEN; 287 288 /* pack up and go home */ 289 fl1.l = PACK (sign, exp, result); 290test_done: 291 return (fl1.f); 292} 293 294/* divide two floats */ 295float 296__divsf3 (float a1, float a2) 297{ 298 register union float_long fl1, fl2; 299 register int result; 300 register int mask; 301 register int exp, sign; 302 303 fl1.f = a1; 304 fl2.f = a2; 305 306 /* subtract exponents */ 307 exp = EXP (fl1.l) - EXP (fl2.l) + EXCESS; 308 309 /* compute sign */ 310 sign = SIGN (fl1.l) ^ SIGN (fl2.l); 311 312 /* divide by zero??? */ 313 if (!fl2.l) 314 /* return NaN or -NaN */ 315 return (sign ? 0xFFFFFFFF : 0x7FFFFFFF); 316 317 /* numerator zero??? */ 318 if (!fl1.l) 319 return (0); 320 321 /* now get mantissas */ 322 fl1.l = MANT (fl1.l); 323 fl2.l = MANT (fl2.l); 324 325 /* this assures we have 25 bits of precision in the end */ 326 if (fl1.l < fl2.l) 327 { 328 fl1.l <<= 1; 329 exp--; 330 } 331 332 /* now we perform repeated subtraction of fl2.l from fl1.l */ 333 mask = 0x1000000; 334 result = 0; 335 while (mask) 336 { 337 if (fl1.l >= fl2.l) 338 { 339 result |= mask; 340 fl1.l -= fl2.l; 341 } 342 fl1.l <<= 1; 343 mask >>= 1; 344 } 345 346 /* round */ 347 result += 1; 348 349 /* normalize down */ 350 exp++; 351 result >>= 1; 352 353 result &= ~HIDDEN; 354 355 /* pack up and go home */ 356 fl1.l = PACK (sign, exp, result); 357 return (fl1.f); 358} 359 360/* convert int to double */ 361double 362__floatsidf (register long a1) 363{ 364 register int sign = 0, exp = 31 + EXCESSD; 365 union double_long dl; 366 367 if (!a1) 368 { 369 dl.l.upper = dl.l.lower = 0; 370 return (dl.d); 371 } 372 373 if (a1 < 0) 374 { 375 sign = SIGNBIT; 376 a1 = -a1; 377 } 378 379 while (a1 < 0x1000000) 380 { 381 a1 <<= 4; 382 exp -= 4; 383 } 384 385 while (a1 < 0x40000000) 386 { 387 a1 <<= 1; 388 exp--; 389 } 390 391 /* pack up and go home */ 392 dl.l.upper = sign; 393 dl.l.upper |= exp << 20; 394 dl.l.upper |= (a1 >> 10) & ~HIDDEND; 395 dl.l.lower = a1 << 22; 396 397 return (dl.d); 398} 399 400double 401__floatdidf (register long long a1) 402{ 403 register int exp = 63 + EXCESSD; 404 union double_long dl; 405 406 dl.l.upper = dl.l.lower = 0; 407 if (a1 == 0) 408 return (dl.d); 409 410 if (a1 < 0) { 411 dl.l.upper = SIGNBIT; 412 a1 = -a1; 413 } 414 415 while (a1 < (long long)1<<54) { 416 a1 <<= 8; 417 exp -= 8; 418 } 419 while (a1 < (long long)1<<62) { 420 a1 <<= 1; 421 exp -= 1; 422 } 423 424 /* pack up and go home */ 425 dl.ll |= (a1 >> 10) & ~HIDDEND_LL; 426 dl.l.upper |= exp << 20; 427 428 return (dl.d); 429} 430 431float 432__floatsisf (register long a1) 433{ 434 (float)__floatsidf(a1); 435} 436 437float 438__floatdisf (register long long a1) 439{ 440 (float)__floatdidf(a1); 441} 442 443/* negate a float */ 444float 445__negsf2 (float a1) 446{ 447 register union float_long fl1; 448 449 fl1.f = a1; 450 if (!fl1.l) 451 return (0); 452 453 fl1.l ^= SIGNBIT; 454 return (fl1.f); 455} 456 457/* negate a double */ 458double 459__negdf2 (double a1) 460{ 461 register union double_long dl1; 462 463 dl1.d = a1; 464 465 if (!dl1.l.upper && !dl1.l.lower) 466 return (dl1.d); 467 468 dl1.l.upper ^= SIGNBIT; 469 return (dl1.d); 470} 471 472/* convert float to double */ 473double 474__extendsfdf2 (float a1) 475{ 476 register union float_long fl1; 477 register union double_long dl; 478 register int exp; 479 480 fl1.f = a1; 481 482 if (!fl1.l) 483 { 484 dl.l.upper = dl.l.lower = 0; 485 return (dl.d); 486 } 487 488 dl.l.upper = SIGN (fl1.l); 489 exp = EXP (fl1.l) - EXCESS + EXCESSD; 490 dl.l.upper |= exp << 20; 491 dl.l.upper |= (MANT (fl1.l) & ~HIDDEN) >> 3; 492 dl.l.lower = MANT (fl1.l) << 29; 493 494 return (dl.d); 495} 496 497/* convert double to float */ 498float 499__truncdfsf2 (double a1) 500{ 501 register int exp; 502 register long mant; 503 register union float_long fl; 504 register union double_long dl1; 505 506 dl1.d = a1; 507 508 if (!dl1.l.upper && !dl1.l.lower) 509 return (float)(0); 510 511 exp = EXPD (dl1) - EXCESSD + EXCESS; 512 513 /* shift double mantissa 6 bits so we can round */ 514 mant = MANTD (dl1) >> 6; 515 516 /* now round and shift down */ 517 mant += 1; 518 mant >>= 1; 519 520 /* did the round overflow? */ 521 if (mant & 0xFE000000) 522 { 523 mant >>= 1; 524 exp++; 525 } 526 527 mant &= ~HIDDEN; 528 529 /* pack up and go home */ 530 fl.l = PACK (SIGND (dl1), exp, mant); 531 return (fl.f); 532} 533 534/* compare two doubles */ 535long 536__cmpdf2 (double a1, double a2) 537{ 538 register union double_long dl1, dl2; 539 540 dl1.d = a1; 541 dl2.d = a2; 542 543 if (SIGND (dl1) && SIGND (dl2)) 544 { 545 dl1.l.upper ^= SIGNBIT; 546 dl2.l.upper ^= SIGNBIT; 547 } 548 if (dl1.l.upper < dl2.l.upper) 549 return (-1); 550 if (dl1.l.upper > dl2.l.upper) 551 return (1); 552 if (dl1.l.lower < dl2.l.lower) 553 return (-1); 554 if (dl1.l.lower > dl2.l.lower) 555 return (1); 556 return (0); 557} 558 559/* convert double to int */ 560long 561__fixdfsi (double a1) 562{ 563 register union double_long dl1; 564 register int exp; 565 register long l; 566 567 dl1.d = a1; 568 569 if (!dl1.l.upper && !dl1.l.lower) 570 return (0); 571 572 exp = EXPD (dl1) - EXCESSD - 31; 573 l = MANTD (dl1); 574 575 if (exp > 0) 576 return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1); 577 578 /* shift down until exp = 0 or l = 0 */ 579 if (exp < 0 && exp > -32 && l) 580 l >>= -exp; 581 else 582 return (0); 583 584 return (SIGND (dl1) ? -l : l); 585} 586 587/* convert double to int */ 588long long 589__fixdfdi (double a1) 590{ 591 register union double_long dl1; 592 register int exp; 593 register long long l; 594 595 dl1.d = a1; 596 597 if (!dl1.l.upper && !dl1.l.lower) 598 return (0); 599 600 exp = EXPD (dl1) - EXCESSD - 64; 601 l = MANTD_LL(dl1); 602 603 if (exp > 0) { 604 l = (long long)1<<63; 605 if (!SIGND(dl1)) 606 l--; 607 return l; 608 } 609 610 /* shift down until exp = 0 or l = 0 */ 611 if (exp < 0 && exp > -64 && l) 612 l >>= -exp; 613 else 614 return (0); 615 616 return (SIGND (dl1) ? -l : l); 617} 618 619/* convert double to unsigned int */ 620unsigned long 621__fixunsdfsi (double a1) 622{ 623 register union double_long dl1; 624 register int exp; 625 register unsigned long l; 626 627 dl1.d = a1; 628 629 if (!dl1.l.upper && !dl1.l.lower) 630 return (0); 631 632 exp = EXPD (dl1) - EXCESSD - 32; 633 l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21)); 634 635 if (exp > 0) 636 return (0xFFFFFFFFul); /* largest integer */ 637 638 /* shift down until exp = 0 or l = 0 */ 639 if (exp < 0 && exp > -32 && l) 640 l >>= -exp; 641 else 642 return (0); 643 644 return (l); 645} 646 647/* convert double to unsigned int */ 648unsigned long long 649__fixunsdfdi (double a1) 650{ 651 register union double_long dl1; 652 register int exp; 653 register unsigned long long l; 654 655 dl1.d = a1; 656 657 if (dl1.ll == 0) 658 return (0); 659 660 exp = EXPD (dl1) - EXCESSD - 64; 661 662 l = dl1.ll; 663 664 if (exp > 0) 665 return (unsigned long long)-1; 666 667 /* shift down until exp = 0 or l = 0 */ 668 if (exp < 0 && exp > -64 && l) 669 l >>= -exp; 670 else 671 return (0); 672 673 return (l); 674} 675 676/* addtwo doubles */ 677double 678__adddf3 (double a1, double a2) 679{ 680 register long long mant1, mant2; 681 register union double_long fl1, fl2; 682 register int exp1, exp2; 683 int sign = 0; 684 685 fl1.d = a1; 686 fl2.d = a2; 687 688 /* check for zero args */ 689 if (!fl2.ll) 690 goto test_done; 691 if (!fl1.ll) { 692 fl1.d = fl2.d; 693 goto test_done; 694 } 695 696 exp1 = EXPD(fl1); 697 exp2 = EXPD(fl2); 698 699 if (exp1 > exp2 + 54) 700 goto test_done; 701 if (exp2 > exp1 + 54) { 702 fl1.d = fl2.d; 703 goto test_done; 704 } 705 706 /* do everything in excess precision so's we can round later */ 707 mant1 = MANTD_LL(fl1) << 9; 708 mant2 = MANTD_LL(fl2) << 9; 709 710 if (SIGND(fl1)) 711 mant1 = -mant1; 712 if (SIGND(fl2)) 713 mant2 = -mant2; 714 715 if (exp1 > exp2) 716 mant2 >>= exp1 - exp2; 717 else { 718 mant1 >>= exp2 - exp1; 719 exp1 = exp2; 720 } 721 mant1 += mant2; 722 723 if (mant1 < 0) { 724 mant1 = -mant1; 725 sign = SIGNBIT; 726 } else if (!mant1) { 727 fl1.d = 0; 728 goto test_done; 729 } 730 731 /* normalize up */ 732 while (!(mant1 & ((long long)7<<61))) { 733 mant1 <<= 1; 734 exp1--; 735 } 736 737 /* normalize down? */ 738 if (mant1 & ((long long)3<<62)) { 739 mant1 >>= 1; 740 exp1++; 741 } 742 743 /* round to even */ 744 mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1); 745 746 /* normalize down? */ 747 if (mant1 & ((long long)3<<62)) { 748 mant1 >>= 1; 749 exp1++; 750 } 751 752 /* lose extra precision */ 753 mant1 >>= 9; 754 755 /* turn off hidden bit */ 756 mant1 &= ~HIDDEND_LL; 757 758 /* pack up and go home */ 759 fl1.ll = PACKD_LL(sign,exp1,mant1); 760 761test_done: 762 return (fl1.d); 763} 764 765/* subtract two doubles */ 766double 767__subdf3 (double a1, double a2) 768{ 769 register union double_long fl1, fl2; 770 771 fl1.d = a1; 772 fl2.d = a2; 773 774 /* check for zero args */ 775 if (!fl2.ll) 776 return (fl1.d); 777 /* twiddle sign bit and add */ 778 fl2.l.upper ^= SIGNBIT; 779 if (!fl1.ll) 780 return (fl2.d); 781 return __adddf3 (a1, fl2.d); 782} 783 784/* multiply two doubles */ 785double 786__muldf3 (double a1, double a2) 787{ 788 register union double_long fl1, fl2; 789 register unsigned long long result; 790 register int exp; 791 int sign; 792 793 fl1.d = a1; 794 fl2.d = a2; 795 796 if (!fl1.ll || !fl2.ll) { 797 fl1.d = 0; 798 goto test_done; 799 } 800 801 /* compute sign and exponent */ 802 sign = SIGND(fl1) ^ SIGND(fl2); 803 exp = EXPD(fl1) - EXCESSD; 804 exp += EXPD(fl2); 805 806 fl1.ll = MANTD_LL(fl1); 807 fl2.ll = MANTD_LL(fl2); 808 809 /* the multiply is done as one 31x31 multiply and two 31x21 multiples */ 810 result = (fl1.ll >> 21) * (fl2.ll >> 21); 811 result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21; 812 result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21; 813 814 result >>= 2; 815 if (result & ((long long)1<<61)) { 816 /* round */ 817 result += 1<<8; 818 result >>= 9; 819 } else { 820 /* round */ 821 result += 1<<7; 822 result >>= 8; 823 exp--; 824 } 825 if (result & (HIDDEND_LL<<1)) { 826 result >>= 1; 827 exp++; 828 } 829 830 result &= ~HIDDEND_LL; 831 832 /* pack up and go home */ 833 fl1.ll = PACKD_LL(sign,exp,result); 834test_done: 835 return (fl1.d); 836} 837 838/* divide two doubles */ 839double 840__divdf3 (double a1, double a2) 841{ 842 register union double_long fl1, fl2; 843 register long long mask,result; 844 register int exp, sign; 845 846 fl1.d = a1; 847 fl2.d = a2; 848 849 /* subtract exponents */ 850 exp = EXPD(fl1) - EXPD(fl2) + EXCESSD; 851 852 /* compute sign */ 853 sign = SIGND(fl1) ^ SIGND(fl2); 854 855 /* numerator zero??? */ 856 if (fl1.ll == 0) { 857 /* divide by zero??? */ 858 if (fl2.ll == 0) 859 fl1.ll = ((unsigned long long)1<<63)-1; /* NaN */ 860 else 861 fl1.ll = 0; 862 goto test_done; 863 } 864 865 /* return +Inf or -Inf */ 866 if (fl2.ll == 0) { 867 fl1.ll = PACKD_LL(SIGND(fl1),2047,0); 868 goto test_done; 869 } 870 871 872 /* now get mantissas */ 873 fl1.ll = MANTD_LL(fl1); 874 fl2.ll = MANTD_LL(fl2); 875 876 /* this assures we have 54 bits of precision in the end */ 877 if (fl1.ll < fl2.ll) { 878 fl1.ll <<= 1; 879 exp--; 880 } 881 882 /* now we perform repeated subtraction of fl2.ll from fl1.ll */ 883 mask = (long long)1<<53; 884 result = 0; 885 while (mask) { 886 if (fl1.ll >= fl2.ll) 887 { 888 result |= mask; 889 fl1.ll -= fl2.ll; 890 } 891 fl1.ll <<= 1; 892 mask >>= 1; 893 } 894 895 /* round */ 896 result += 1; 897 898 /* normalize down */ 899 exp++; 900 result >>= 1; 901 902 result &= ~HIDDEND_LL; 903 904 /* pack up and go home */ 905 fl1.ll = PACKD_LL(sign, exp, result); 906 907test_done: 908 return (fl1.d); 909} 910 911int 912__gtdf2 (double a1, double a2) 913{ 914 return __cmpdf2 ((float) a1, (float) a2) > 0; 915} 916 917int 918__gedf2 (double a1, double a2) 919{ 920 return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1; 921} 922 923int 924__ltdf2 (double a1, double a2) 925{ 926 return - (__cmpdf2 ((float) a1, (float) a2) < 0); 927} 928 929int 930__ledf2 (double a1, double a2) 931{ 932 return __cmpdf2 ((float) a1, (float) a2) > 0; 933} 934 935int 936__eqdf2 (double a1, double a2) 937{ 938 return *(long long *) &a1 == *(long long *) &a2; 939} 940 941int 942__nedf2 (double a1, double a2) 943{ 944 return *(long long *) &a1 != *(long long *) &a2; 945} 946