00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define EXCESS 126
00058 #define SIGNBIT 0x80000000
00059 #define HIDDEN (1 << 23)
00060 #define SIGN(fp) ((fp) & SIGNBIT)
00061 #define EXP(fp) (((fp) >> 23) & 0xFF)
00062 #define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
00063 #define PACK(s,e,m) ((s) | ((e) << 23) | (m))
00064
00065
00066 #define EXCESSD 1022
00067 #define HIDDEND (1 << 20)
00068 #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
00069 #define SIGND(fp) ((fp.l.upper) & SIGNBIT)
00070 #define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
00071 (fp.l.lower >> 22))
00072 #define HIDDEND_LL ((long long)1 << 52)
00073 #define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
00074 #define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
00075
00076
00077 union double_long {
00078 double d;
00079 #ifdef SWAP
00080 struct {
00081 #ifdef KEY
00082 int upper;
00083 unsigned int lower;
00084 #else
00085 unsigned long lower;
00086 long upper;
00087 #endif
00088 } l;
00089 #else
00090 struct {
00091 #ifdef KEY
00092 unsigned int lower;
00093 int upper;
00094 #else
00095 long upper;
00096 unsigned long lower;
00097 #endif
00098 } l;
00099 #endif
00100 long long ll;
00101 };
00102
00103 union float_long
00104 {
00105 float f;
00106 long l;
00107 };
00108
00109
00110 float
00111 __addsf3 (float a1, float a2)
00112 {
00113 long mant1, mant2;
00114 union float_long fl1, fl2;
00115 int exp1, exp2;
00116 int sign = 0;
00117
00118 fl1.f = a1;
00119 fl2.f = a2;
00120
00121
00122 if (!fl1.l) {
00123 fl1.f = fl2.f;
00124 goto test_done;
00125 }
00126 if (!fl2.l)
00127 goto test_done;
00128
00129 exp1 = EXP (fl1.l);
00130 exp2 = EXP (fl2.l);
00131
00132 if (exp1 > exp2 + 25)
00133 goto test_done;
00134 if (exp2 > exp1 + 25) {
00135 fl1.f = fl2.f;
00136 goto test_done;
00137 }
00138
00139
00140 mant1 = MANT (fl1.l) << 6;
00141 mant2 = MANT (fl2.l) << 6;
00142
00143 if (SIGN (fl1.l))
00144 mant1 = -mant1;
00145 if (SIGN (fl2.l))
00146 mant2 = -mant2;
00147
00148 if (exp1 > exp2)
00149 {
00150 mant2 >>= exp1 - exp2;
00151 }
00152 else
00153 {
00154 mant1 >>= exp2 - exp1;
00155 exp1 = exp2;
00156 }
00157 mant1 += mant2;
00158
00159 if (mant1 < 0)
00160 {
00161 mant1 = -mant1;
00162 sign = SIGNBIT;
00163 }
00164 else if (!mant1) {
00165 fl1.f = 0;
00166 goto test_done;
00167 }
00168
00169
00170 while (!(mant1 & 0xE0000000))
00171 {
00172 mant1 <<= 1;
00173 exp1--;
00174 }
00175
00176
00177 if (mant1 & (1 << 30))
00178 {
00179 mant1 >>= 1;
00180 exp1++;
00181 }
00182
00183
00184 mant1 += (mant1 & 0x40) ? 0x20 : 0x1F;
00185
00186
00187 if (mant1 & (1 << 30))
00188 {
00189 mant1 >>= 1;
00190 exp1++;
00191 }
00192
00193
00194 mant1 >>= 6;
00195
00196
00197 mant1 &= ~HIDDEN;
00198
00199
00200 fl1.l = PACK (sign, exp1, mant1);
00201 test_done:
00202 return (fl1.f);
00203 }
00204
00205
00206 float
00207 __subsf3 (float a1, float a2)
00208 {
00209 union float_long fl1, fl2;
00210
00211 fl1.f = a1;
00212 fl2.f = a2;
00213
00214
00215 if (!fl2.l)
00216 return (fl1.f);
00217 if (!fl1.l)
00218 return (-fl2.f);
00219
00220
00221 fl2.l ^= SIGNBIT;
00222 return __addsf3 (a1, fl2.f);
00223 }
00224
00225
00226 long
00227 __cmpsf2 (float a1, float a2)
00228 {
00229 union float_long fl1, fl2;
00230
00231 fl1.f = a1;
00232 fl2.f = a2;
00233
00234 if (SIGN (fl1.l) && SIGN (fl2.l))
00235 {
00236 fl1.l ^= SIGNBIT;
00237 fl2.l ^= SIGNBIT;
00238 }
00239 if (fl1.l < fl2.l)
00240 return (-1);
00241 if (fl1.l > fl2.l)
00242 return (1);
00243 return (0);
00244 }
00245
00246
00247 float
00248 __mulsf3 (float a1, float a2)
00249 {
00250 union float_long fl1, fl2;
00251 unsigned long result;
00252 int exp;
00253 int sign;
00254
00255 fl1.f = a1;
00256 fl2.f = a2;
00257
00258 if (!fl1.l || !fl2.l) {
00259 fl1.f = 0;
00260 goto test_done;
00261 }
00262
00263
00264 sign = SIGN (fl1.l) ^ SIGN (fl2.l);
00265 exp = EXP (fl1.l) - EXCESS;
00266 exp += EXP (fl2.l);
00267
00268 fl1.l = MANT (fl1.l);
00269 fl2.l = MANT (fl2.l);
00270
00271
00272 result = (fl1.l >> 8) * (fl2.l >> 8);
00273 result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8;
00274 result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8;
00275
00276 result >>= 2;
00277 if (result & 0x20000000)
00278 {
00279
00280 result += 0x20;
00281 result >>= 6;
00282 }
00283 else
00284 {
00285
00286 result += 0x10;
00287 result >>= 5;
00288 exp--;
00289 }
00290 if (result & (HIDDEN<<1)) {
00291 result >>= 1;
00292 exp++;
00293 }
00294
00295 result &= ~HIDDEN;
00296
00297
00298 fl1.l = PACK (sign, exp, result);
00299 test_done:
00300 return (fl1.f);
00301 }
00302
00303
00304 float
00305 __divsf3 (float a1, float a2)
00306 {
00307 union float_long fl1, fl2;
00308 int result;
00309 int mask;
00310 int exp, sign;
00311
00312 fl1.f = a1;
00313 fl2.f = a2;
00314
00315
00316 exp = EXP (fl1.l) - EXP (fl2.l) + EXCESS;
00317
00318
00319 sign = SIGN (fl1.l) ^ SIGN (fl2.l);
00320
00321
00322 if (!fl2.l)
00323
00324 return (sign ? 0xFFFFFFFF : 0x7FFFFFFF);
00325
00326
00327 if (!fl1.l)
00328 return (0);
00329
00330
00331 fl1.l = MANT (fl1.l);
00332 fl2.l = MANT (fl2.l);
00333
00334
00335 if (fl1.l < fl2.l)
00336 {
00337 fl1.l <<= 1;
00338 exp--;
00339 }
00340
00341
00342 mask = 0x1000000;
00343 result = 0;
00344 while (mask)
00345 {
00346 if (fl1.l >= fl2.l)
00347 {
00348 result |= mask;
00349 fl1.l -= fl2.l;
00350 }
00351 fl1.l <<= 1;
00352 mask >>= 1;
00353 }
00354
00355
00356 result += 1;
00357
00358
00359 exp++;
00360 result >>= 1;
00361
00362 result &= ~HIDDEN;
00363
00364
00365 fl1.l = PACK (sign, exp, result);
00366 return (fl1.f);
00367 }
00368
00369
00370 double
00371 __floatsidf (long a1)
00372 {
00373 int sign = 0, exp = 31 + EXCESSD;
00374 union double_long dl;
00375
00376 if (!a1)
00377 {
00378 dl.l.upper = dl.l.lower = 0;
00379 return (dl.d);
00380 }
00381
00382 if (a1 < 0)
00383 {
00384 sign = SIGNBIT;
00385 a1 = -a1;
00386 }
00387
00388 while (a1 < 0x1000000)
00389 {
00390 a1 <<= 4;
00391 exp -= 4;
00392 }
00393
00394 while (a1 < 0x40000000)
00395 {
00396 a1 <<= 1;
00397 exp--;
00398 }
00399
00400
00401 dl.l.upper = sign;
00402 dl.l.upper |= exp << 20;
00403 dl.l.upper |= (a1 >> 10) & ~HIDDEND;
00404 dl.l.lower = a1 << 22;
00405
00406 return (dl.d);
00407 }
00408
00409 double
00410 __floatdidf (long long a1)
00411 {
00412 int exp = 63 + EXCESSD;
00413 union double_long dl;
00414
00415 dl.l.upper = dl.l.lower = 0;
00416 if (a1 == 0)
00417 return (dl.d);
00418
00419 if (a1 < 0) {
00420 dl.l.upper = SIGNBIT;
00421 a1 = -a1;
00422 }
00423
00424 while (a1 < (long long)1<<54) {
00425 a1 <<= 8;
00426 exp -= 8;
00427 }
00428 while (a1 < (long long)1<<62) {
00429 a1 <<= 1;
00430 exp -= 1;
00431 }
00432
00433
00434 dl.ll |= (a1 >> 10) & ~HIDDEND_LL;
00435 dl.l.upper |= exp << 20;
00436
00437 return (dl.d);
00438 }
00439
00440 float
00441 __floatsisf (long a1)
00442 {
00443 (float)__floatsidf(a1);
00444 }
00445
00446 float
00447 __floatdisf (long long a1)
00448 {
00449 (float)__floatdidf(a1);
00450 }
00451
00452
00453 float
00454 __negsf2 (float a1)
00455 {
00456 union float_long fl1;
00457
00458 fl1.f = a1;
00459 if (!fl1.l)
00460 return (0);
00461
00462 fl1.l ^= SIGNBIT;
00463 return (fl1.f);
00464 }
00465
00466
00467 double
00468 __negdf2 (double a1)
00469 {
00470 union double_long dl1;
00471
00472 dl1.d = a1;
00473
00474 if (!dl1.l.upper && !dl1.l.lower)
00475 return (dl1.d);
00476
00477 dl1.l.upper ^= SIGNBIT;
00478 return (dl1.d);
00479 }
00480
00481
00482 double
00483 __extendsfdf2 (float a1)
00484 {
00485 union float_long fl1;
00486 union double_long dl;
00487 int exp;
00488
00489 fl1.f = a1;
00490
00491 if (!fl1.l)
00492 {
00493 dl.l.upper = dl.l.lower = 0;
00494 return (dl.d);
00495 }
00496
00497 dl.l.upper = SIGN (fl1.l);
00498 exp = EXP (fl1.l) - EXCESS + EXCESSD;
00499 dl.l.upper |= exp << 20;
00500 dl.l.upper |= (MANT (fl1.l) & ~HIDDEN) >> 3;
00501 dl.l.lower = MANT (fl1.l) << 29;
00502
00503 return (dl.d);
00504 }
00505
00506
00507 float
00508 __truncdfsf2 (double a1)
00509 {
00510 int exp;
00511 long mant;
00512 union float_long fl;
00513 union double_long dl1;
00514
00515 dl1.d = a1;
00516
00517 if (!dl1.l.upper && !dl1.l.lower)
00518 return (float)(0);
00519
00520 exp = EXPD (dl1) - EXCESSD + EXCESS;
00521
00522
00523 mant = MANTD (dl1) >> 6;
00524
00525
00526 mant += 1;
00527 mant >>= 1;
00528
00529
00530 if (mant & 0xFE000000)
00531 {
00532 mant >>= 1;
00533 exp++;
00534 }
00535
00536 mant &= ~HIDDEN;
00537
00538
00539 fl.l = PACK (SIGND (dl1), exp, mant);
00540 return (fl.f);
00541 }
00542
00543
00544 long
00545 __cmpdf2 (double a1, double a2)
00546 {
00547 union double_long dl1, dl2;
00548
00549 dl1.d = a1;
00550 dl2.d = a2;
00551
00552 if (SIGND (dl1) && SIGND (dl2))
00553 {
00554 dl1.l.upper ^= SIGNBIT;
00555 dl2.l.upper ^= SIGNBIT;
00556 }
00557 if (dl1.l.upper < dl2.l.upper)
00558 return (-1);
00559 if (dl1.l.upper > dl2.l.upper)
00560 return (1);
00561 if (dl1.l.lower < dl2.l.lower)
00562 return (-1);
00563 if (dl1.l.lower > dl2.l.lower)
00564 return (1);
00565 return (0);
00566 }
00567
00568
00569 long
00570 __fixdfsi (double a1)
00571 {
00572 union double_long dl1;
00573 int exp;
00574 long l;
00575
00576 dl1.d = a1;
00577
00578 if (!dl1.l.upper && !dl1.l.lower)
00579 return (0);
00580
00581 exp = EXPD (dl1) - EXCESSD - 31;
00582 l = MANTD (dl1);
00583
00584 if (exp > 0)
00585 return SIGND(dl1) ? (1<<31) : ((1ul<<31)-1);
00586
00587
00588 if (exp < 0 && exp > -32 && l)
00589 l >>= -exp;
00590 else
00591 return (0);
00592
00593 return (SIGND (dl1) ? -l : l);
00594 }
00595
00596
00597 long long
00598 __fixdfdi (double a1)
00599 {
00600 union double_long dl1;
00601 int exp;
00602 long long l;
00603
00604 dl1.d = a1;
00605
00606 if (!dl1.l.upper && !dl1.l.lower)
00607 return (0);
00608
00609 exp = EXPD (dl1) - EXCESSD - 64;
00610 l = MANTD_LL(dl1);
00611
00612 if (exp > 0) {
00613 l = (long long)1<<63;
00614 if (!SIGND(dl1))
00615 l--;
00616 return l;
00617 }
00618
00619
00620 if (exp < 0 && exp > -64 && l)
00621 l >>= -exp;
00622 else
00623 return (0);
00624
00625 return (SIGND (dl1) ? -l : l);
00626 }
00627
00628
00629 unsigned long
00630 __fixunsdfsi (double a1)
00631 {
00632 union double_long dl1;
00633 int exp;
00634 unsigned long l;
00635
00636 dl1.d = a1;
00637
00638 if (!dl1.l.upper && !dl1.l.lower)
00639 return (0);
00640
00641 exp = EXPD (dl1) - EXCESSD - 32;
00642 l = (((((dl1.l.upper) & 0xFFFFF) | HIDDEND) << 11) | (dl1.l.lower >> 21));
00643
00644 if (exp > 0)
00645 return (0xFFFFFFFFul);
00646
00647
00648 if (exp < 0 && exp > -32 && l)
00649 l >>= -exp;
00650 else
00651 return (0);
00652
00653 return (l);
00654 }
00655
00656
00657 unsigned long long
00658 __fixunsdfdi (double a1)
00659 {
00660 union double_long dl1;
00661 int exp;
00662 unsigned long long l;
00663
00664 dl1.d = a1;
00665
00666 if (dl1.ll == 0)
00667 return (0);
00668
00669 exp = EXPD (dl1) - EXCESSD - 64;
00670
00671 l = dl1.ll;
00672
00673 if (exp > 0)
00674 return (unsigned long long)-1;
00675
00676
00677 if (exp < 0 && exp > -64 && l)
00678 l >>= -exp;
00679 else
00680 return (0);
00681
00682 return (l);
00683 }
00684
00685
00686 double
00687 __adddf3 (double a1, double a2)
00688 {
00689 long long mant1, mant2;
00690 union double_long fl1, fl2;
00691 int exp1, exp2;
00692 int sign = 0;
00693
00694 fl1.d = a1;
00695 fl2.d = a2;
00696
00697
00698 if (!fl2.ll)
00699 goto test_done;
00700 if (!fl1.ll) {
00701 fl1.d = fl2.d;
00702 goto test_done;
00703 }
00704
00705 exp1 = EXPD(fl1);
00706 exp2 = EXPD(fl2);
00707
00708 if (exp1 > exp2 + 54)
00709 goto test_done;
00710 if (exp2 > exp1 + 54) {
00711 fl1.d = fl2.d;
00712 goto test_done;
00713 }
00714
00715
00716 mant1 = MANTD_LL(fl1) << 9;
00717 mant2 = MANTD_LL(fl2) << 9;
00718
00719 if (SIGND(fl1))
00720 mant1 = -mant1;
00721 if (SIGND(fl2))
00722 mant2 = -mant2;
00723
00724 if (exp1 > exp2)
00725 mant2 >>= exp1 - exp2;
00726 else {
00727 mant1 >>= exp2 - exp1;
00728 exp1 = exp2;
00729 }
00730 mant1 += mant2;
00731
00732 if (mant1 < 0) {
00733 mant1 = -mant1;
00734 sign = SIGNBIT;
00735 } else if (!mant1) {
00736 fl1.d = 0;
00737 goto test_done;
00738 }
00739
00740
00741 while (!(mant1 & ((long long)7<<61))) {
00742 mant1 <<= 1;
00743 exp1--;
00744 }
00745
00746
00747 if (mant1 & ((long long)3<<62)) {
00748 mant1 >>= 1;
00749 exp1++;
00750 }
00751
00752
00753 mant1 += (mant1 & (1<<9)) ? (1<<8) : ((1<<8)-1);
00754
00755
00756 if (mant1 & ((long long)3<<62)) {
00757 mant1 >>= 1;
00758 exp1++;
00759 }
00760
00761
00762 mant1 >>= 9;
00763
00764
00765 mant1 &= ~HIDDEND_LL;
00766
00767
00768 fl1.ll = PACKD_LL(sign,exp1,mant1);
00769
00770 test_done:
00771 return (fl1.d);
00772 }
00773
00774
00775 double
00776 __subdf3 (double a1, double a2)
00777 {
00778 union double_long fl1, fl2;
00779
00780 fl1.d = a1;
00781 fl2.d = a2;
00782
00783
00784 if (!fl2.ll)
00785 return (fl1.d);
00786
00787 fl2.l.upper ^= SIGNBIT;
00788 if (!fl1.ll)
00789 return (fl2.d);
00790 return __adddf3 (a1, fl2.d);
00791 }
00792
00793
00794 double
00795 __muldf3 (double a1, double a2)
00796 {
00797 union double_long fl1, fl2;
00798 unsigned long long result;
00799 int exp;
00800 int sign;
00801
00802 fl1.d = a1;
00803 fl2.d = a2;
00804
00805 if (!fl1.ll || !fl2.ll) {
00806 fl1.d = 0;
00807 goto test_done;
00808 }
00809
00810
00811 sign = SIGND(fl1) ^ SIGND(fl2);
00812 exp = EXPD(fl1) - EXCESSD;
00813 exp += EXPD(fl2);
00814
00815 fl1.ll = MANTD_LL(fl1);
00816 fl2.ll = MANTD_LL(fl2);
00817
00818
00819 result = (fl1.ll >> 21) * (fl2.ll >> 21);
00820 result += ((fl1.ll & 0x1FFFFF) * (fl2.ll >> 21)) >> 21;
00821 result += ((fl2.ll & 0x1FFFFF) * (fl1.ll >> 21)) >> 21;
00822
00823 result >>= 2;
00824 if (result & ((long long)1<<61)) {
00825
00826 result += 1<<8;
00827 result >>= 9;
00828 } else {
00829
00830 result += 1<<7;
00831 result >>= 8;
00832 exp--;
00833 }
00834 if (result & (HIDDEND_LL<<1)) {
00835 result >>= 1;
00836 exp++;
00837 }
00838
00839 result &= ~HIDDEND_LL;
00840
00841
00842 fl1.ll = PACKD_LL(sign,exp,result);
00843 test_done:
00844 return (fl1.d);
00845 }
00846
00847
00848 double
00849 __divdf3 (double a1, double a2)
00850 {
00851 union double_long fl1, fl2;
00852 long long mask,result;
00853 int exp, sign;
00854
00855 fl1.d = a1;
00856 fl2.d = a2;
00857
00858
00859 exp = EXPD(fl1) - EXPD(fl2) + EXCESSD;
00860
00861
00862 sign = SIGND(fl1) ^ SIGND(fl2);
00863
00864
00865 if (fl1.ll == 0) {
00866
00867 if (fl2.ll == 0)
00868 fl1.ll = ((unsigned long long)1<<63)-1;
00869 else
00870 fl1.ll = 0;
00871 goto test_done;
00872 }
00873
00874
00875 if (fl2.ll == 0) {
00876 fl1.ll = PACKD_LL(SIGND(fl1),2047,0);
00877 goto test_done;
00878 }
00879
00880
00881
00882 fl1.ll = MANTD_LL(fl1);
00883 fl2.ll = MANTD_LL(fl2);
00884
00885
00886 if (fl1.ll < fl2.ll) {
00887 fl1.ll <<= 1;
00888 exp--;
00889 }
00890
00891
00892 mask = (long long)1<<53;
00893 result = 0;
00894 while (mask) {
00895 if (fl1.ll >= fl2.ll)
00896 {
00897 result |= mask;
00898 fl1.ll -= fl2.ll;
00899 }
00900 fl1.ll <<= 1;
00901 mask >>= 1;
00902 }
00903
00904
00905 result += 1;
00906
00907
00908 exp++;
00909 result >>= 1;
00910
00911 result &= ~HIDDEND_LL;
00912
00913
00914 fl1.ll = PACKD_LL(sign, exp, result);
00915
00916 test_done:
00917 return (fl1.d);
00918 }
00919
00920 int
00921 __gtdf2 (double a1, double a2)
00922 {
00923 return __cmpdf2 ((float) a1, (float) a2) > 0;
00924 }
00925
00926 int
00927 __gedf2 (double a1, double a2)
00928 {
00929 return (__cmpdf2 ((float) a1, (float) a2) >= 0) - 1;
00930 }
00931
00932 int
00933 __ltdf2 (double a1, double a2)
00934 {
00935 return - (__cmpdf2 ((float) a1, (float) a2) < 0);
00936 }
00937
00938 int
00939 __ledf2 (double a1, double a2)
00940 {
00941 return __cmpdf2 ((float) a1, (float) a2) > 0;
00942 }
00943
00944 int
00945 __eqdf2 (double a1, double a2)
00946 {
00947 return *(long long *) &a1 == *(long long *) &a2;
00948 }
00949
00950 int
00951 __nedf2 (double a1, double a2)
00952 {
00953 return *(long long *) &a1 != *(long long *) &a2;
00954 }