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 #include "tconfig.h"
00037 #include "tsystem.h"
00038
00039
00040 #ifdef abort
00041 #undef abort
00042 #endif
00043
00044 #include "libgcc2.h"
00045
00046 #ifdef DECLARE_LIBRARY_RENAMES
00047 DECLARE_LIBRARY_RENAMES
00048 #endif
00049
00050 #if defined (L_negdi2)
00051 DWtype
00052 __negdi2 (DWtype u)
00053 {
00054 DWunion w;
00055 DWunion uu;
00056
00057 uu.ll = u;
00058
00059 w.s.low = -uu.s.low;
00060 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
00061
00062 return w.ll;
00063 }
00064 #endif
00065
00066 #ifdef L_addvsi3
00067 Wtype
00068 __addvsi3 (Wtype a, Wtype b)
00069 {
00070 Wtype w;
00071
00072 w = a + b;
00073
00074 if (b >= 0 ? w < a : w > a)
00075 abort ();
00076
00077 return w;
00078 }
00079 #endif
00080
00081 #ifdef L_addvdi3
00082 DWtype
00083 __addvdi3 (DWtype a, DWtype b)
00084 {
00085 DWtype w;
00086
00087 w = a + b;
00088
00089 if (b >= 0 ? w < a : w > a)
00090 abort ();
00091
00092 return w;
00093 }
00094 #endif
00095
00096 #ifdef L_subvsi3
00097 Wtype
00098 __subvsi3 (Wtype a, Wtype b)
00099 {
00100 #ifdef L_addvsi3
00101 return __addvsi3 (a, (-b));
00102 #else
00103 DWtype w;
00104
00105 w = a - b;
00106
00107 if (b >= 0 ? w > a : w < a)
00108 abort ();
00109
00110 return w;
00111 #endif
00112 }
00113 #endif
00114
00115 #ifdef L_subvdi3
00116 DWtype
00117 __subvdi3 (DWtype a, DWtype b)
00118 {
00119 #ifdef L_addvdi3
00120 return (a, (-b));
00121 #else
00122 DWtype w;
00123
00124 w = a - b;
00125
00126 if (b >= 0 ? w > a : w < a)
00127 abort ();
00128
00129 return w;
00130 #endif
00131 }
00132 #endif
00133
00134 #ifdef L_mulvsi3
00135 Wtype
00136 __mulvsi3 (Wtype a, Wtype b)
00137 {
00138 DWtype w;
00139
00140 w = a * b;
00141
00142 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
00143 abort ();
00144
00145 return w;
00146 }
00147 #endif
00148
00149 #ifdef L_negvsi2
00150 Wtype
00151 __negvsi2 (Wtype a)
00152 {
00153 Wtype w;
00154
00155 w = -a;
00156
00157 if (a >= 0 ? w > 0 : w < 0)
00158 abort ();
00159
00160 return w;
00161 }
00162 #endif
00163
00164 #ifdef L_negvdi2
00165 DWtype
00166 __negvdi2 (DWtype a)
00167 {
00168 DWtype w;
00169
00170 w = -a;
00171
00172 if (a >= 0 ? w > 0 : w < 0)
00173 abort ();
00174
00175 return w;
00176 }
00177 #endif
00178
00179 #ifdef L_absvsi2
00180 Wtype
00181 __absvsi2 (Wtype a)
00182 {
00183 Wtype w = a;
00184
00185 if (a < 0)
00186 #ifdef L_negvsi2
00187 w = __negvsi2 (a);
00188 #else
00189 w = -a;
00190
00191 if (w < 0)
00192 abort ();
00193 #endif
00194
00195 return w;
00196 }
00197 #endif
00198
00199 #ifdef L_absvdi2
00200 DWtype
00201 __absvdi2 (DWtype a)
00202 {
00203 DWtype w = a;
00204
00205 if (a < 0)
00206 #ifdef L_negvsi2
00207 w = __negvsi2 (a);
00208 #else
00209 w = -a;
00210
00211 if (w < 0)
00212 abort ();
00213 #endif
00214
00215 return w;
00216 }
00217 #endif
00218
00219 #ifdef L_mulvdi3
00220 DWtype
00221 __mulvdi3 (DWtype u, DWtype v)
00222 {
00223 DWtype w;
00224
00225 w = u * v;
00226
00227 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
00228 abort ();
00229
00230 return w;
00231 }
00232 #endif
00233
00234
00235
00236
00237 #ifdef L_lshrdi3
00238 DWtype
00239 __lshrdi3 (DWtype u, word_type b)
00240 {
00241 DWunion w;
00242 word_type bm;
00243 DWunion uu;
00244
00245 if (b == 0)
00246 return u;
00247
00248 uu.ll = u;
00249
00250 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
00251 if (bm <= 0)
00252 {
00253 w.s.high = 0;
00254 w.s.low = (UWtype) uu.s.high >> -bm;
00255 }
00256 else
00257 {
00258 UWtype carries = (UWtype) uu.s.high << bm;
00259
00260 w.s.high = (UWtype) uu.s.high >> b;
00261 w.s.low = ((UWtype) uu.s.low >> b) | carries;
00262 }
00263
00264 return w.ll;
00265 }
00266 #endif
00267
00268 #ifdef L_ashldi3
00269 DWtype
00270 __ashldi3 (DWtype u, word_type b)
00271 {
00272 DWunion w;
00273 word_type bm;
00274 DWunion uu;
00275
00276 if (b == 0)
00277 return u;
00278
00279 uu.ll = u;
00280
00281 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
00282 if (bm <= 0)
00283 {
00284 w.s.low = 0;
00285 w.s.high = (UWtype) uu.s.low << -bm;
00286 }
00287 else
00288 {
00289 UWtype carries = (UWtype) uu.s.low >> bm;
00290
00291 w.s.low = (UWtype) uu.s.low << b;
00292 w.s.high = ((UWtype) uu.s.high << b) | carries;
00293 }
00294
00295 return w.ll;
00296 }
00297 #endif
00298
00299 #ifdef L_ashrdi3
00300 DWtype
00301 __ashrdi3 (DWtype u, word_type b)
00302 {
00303 DWunion w;
00304 word_type bm;
00305 DWunion uu;
00306
00307 if (b == 0)
00308 return u;
00309
00310 uu.ll = u;
00311
00312 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
00313 if (bm <= 0)
00314 {
00315
00316 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
00317 w.s.low = uu.s.high >> -bm;
00318 }
00319 else
00320 {
00321 UWtype carries = (UWtype) uu.s.high << bm;
00322
00323 w.s.high = uu.s.high >> b;
00324 w.s.low = ((UWtype) uu.s.low >> b) | carries;
00325 }
00326
00327 return w.ll;
00328 }
00329 #endif
00330
00331 #ifdef L_ffsdi2
00332 DWtype
00333 __ffsdi2 (DWtype u)
00334 {
00335 DWunion uu;
00336 UWtype word, count, add;
00337
00338 uu.ll = u;
00339 if (uu.s.low != 0)
00340 word = uu.s.low, add = 0;
00341 else if (uu.s.high != 0)
00342 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
00343 else
00344 return 0;
00345
00346 count_trailing_zeros (count, word);
00347 return count + add + 1;
00348 }
00349 #endif
00350
00351 #ifdef L_muldi3
00352 DWtype
00353 __muldi3 (DWtype u, DWtype v)
00354 {
00355 DWunion w;
00356 DWunion uu, vv;
00357
00358 uu.ll = u,
00359 vv.ll = v;
00360
00361 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
00362 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
00363 + (UWtype) uu.s.high * (UWtype) vv.s.low);
00364
00365 return w.ll;
00366 }
00367 #endif
00368
00369 #if (defined (L_udivdi3) || defined (L_divdi3) || \
00370 defined (L_umoddi3) || defined (L_moddi3))
00371 #if defined (sdiv_qrnnd)
00372 #define L_udiv_w_sdiv
00373 #endif
00374 #endif
00375
00376 #ifdef L_udiv_w_sdiv
00377 #if defined (sdiv_qrnnd)
00378 #if (defined (L_udivdi3) || defined (L_divdi3) || \
00379 defined (L_umoddi3) || defined (L_moddi3))
00380 static inline __attribute__ ((__always_inline__))
00381 #endif
00382 UWtype
00383 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
00384 {
00385 UWtype q, r;
00386 UWtype c0, c1, b1;
00387
00388 if ((Wtype) d >= 0)
00389 {
00390 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
00391 {
00392
00393 sdiv_qrnnd (q, r, a1, a0, d);
00394 }
00395 else
00396 {
00397
00398 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
00399
00400 sdiv_qrnnd (q, r, c1, c0, d);
00401
00402 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
00403 }
00404 }
00405 else
00406 {
00407 b1 = d >> 1;
00408 c1 = a1 >> 1;
00409 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
00410
00411 if (a1 < b1)
00412 {
00413 sdiv_qrnnd (q, r, c1, c0, b1);
00414
00415 r = 2*r + (a0 & 1);
00416 if ((d & 1) != 0)
00417 {
00418 if (r >= q)
00419 r = r - q;
00420 else if (q - r <= d)
00421 {
00422 r = r - q + d;
00423 q--;
00424 }
00425 else
00426 {
00427 r = r - q + 2*d;
00428 q -= 2;
00429 }
00430 }
00431 }
00432 else if (c1 < b1)
00433 {
00434 c1 = (b1 - 1) - c1;
00435 c0 = ~c0;
00436
00437 sdiv_qrnnd (q, r, c1, c0, b1);
00438
00439 q = ~q;
00440 r = (b1 - 1) - r;
00441
00442 r = 2*r + (a0 & 1);
00443
00444 if ((d & 1) != 0)
00445 {
00446 if (r >= q)
00447 r = r - q;
00448 else if (q - r <= d)
00449 {
00450 r = r - q + d;
00451 q--;
00452 }
00453 else
00454 {
00455 r = r - q + 2*d;
00456 q -= 2;
00457 }
00458 }
00459 }
00460 else
00461 {
00462 if (a0 >= -d)
00463 {
00464 q = -1;
00465 r = a0 + d;
00466 }
00467 else
00468 {
00469 q = -2;
00470 r = a0 + 2*d;
00471 }
00472 }
00473 }
00474
00475 *rp = r;
00476 return q;
00477 }
00478 #else
00479
00480 UWtype
00481 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
00482 UWtype a1 __attribute__ ((__unused__)),
00483 UWtype a0 __attribute__ ((__unused__)),
00484 UWtype d __attribute__ ((__unused__)))
00485 {
00486 return 0;
00487 }
00488 #endif
00489 #endif
00490
00491 #if (defined (L_udivdi3) || defined (L_divdi3) || \
00492 defined (L_umoddi3) || defined (L_moddi3))
00493 #define L_udivmoddi4
00494 #endif
00495
00496 #ifdef L_clz
00497 const UQItype __clz_tab[] =
00498 {
00499 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00500 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00501 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00502 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00503 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
00504 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
00505 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
00506 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
00507 };
00508 #endif
00509
00510 #ifdef L_udivmoddi4
00511
00512 #if (defined (L_udivdi3) || defined (L_divdi3) || \
00513 defined (L_umoddi3) || defined (L_moddi3))
00514 static inline __attribute__ ((__always_inline__))
00515 #endif
00516 UDWtype
00517 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
00518 {
00519 DWunion ww;
00520 DWunion nn, dd;
00521 DWunion rr;
00522 UWtype d0, d1, n0, n1, n2;
00523 UWtype q0, q1;
00524 UWtype b, bm;
00525
00526 nn.ll = n;
00527 dd.ll = d;
00528
00529 d0 = dd.s.low;
00530 d1 = dd.s.high;
00531 n0 = nn.s.low;
00532 n1 = nn.s.high;
00533
00534 #if !UDIV_NEEDS_NORMALIZATION
00535 if (d1 == 0)
00536 {
00537 if (d0 > n1)
00538 {
00539
00540
00541 udiv_qrnnd (q0, n0, n1, n0, d0);
00542 q1 = 0;
00543
00544
00545 }
00546 else
00547 {
00548
00549
00550 if (d0 == 0)
00551 d0 = 1 / d0;
00552
00553 udiv_qrnnd (q1, n1, 0, n1, d0);
00554 udiv_qrnnd (q0, n0, n1, n0, d0);
00555
00556
00557 }
00558
00559 if (rp != 0)
00560 {
00561 rr.s.low = n0;
00562 rr.s.high = 0;
00563 *rp = rr.ll;
00564 }
00565 }
00566
00567 #else
00568
00569 if (d1 == 0)
00570 {
00571 if (d0 > n1)
00572 {
00573
00574
00575 count_leading_zeros (bm, d0);
00576
00577 if (bm != 0)
00578 {
00579
00580
00581
00582 d0 = d0 << bm;
00583 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
00584 n0 = n0 << bm;
00585 }
00586
00587 udiv_qrnnd (q0, n0, n1, n0, d0);
00588 q1 = 0;
00589
00590
00591 }
00592 else
00593 {
00594
00595
00596 if (d0 == 0)
00597 d0 = 1 / d0;
00598
00599 count_leading_zeros (bm, d0);
00600
00601 if (bm == 0)
00602 {
00603
00604
00605
00606
00607
00608
00609
00610 n1 -= d0;
00611 q1 = 1;
00612 }
00613 else
00614 {
00615
00616
00617 b = W_TYPE_SIZE - bm;
00618
00619 d0 = d0 << bm;
00620 n2 = n1 >> b;
00621 n1 = (n1 << bm) | (n0 >> b);
00622 n0 = n0 << bm;
00623
00624 udiv_qrnnd (q1, n1, n2, n1, d0);
00625 }
00626
00627
00628
00629 udiv_qrnnd (q0, n0, n1, n0, d0);
00630
00631
00632 }
00633
00634 if (rp != 0)
00635 {
00636 rr.s.low = n0 >> bm;
00637 rr.s.high = 0;
00638 *rp = rr.ll;
00639 }
00640 }
00641 #endif
00642
00643 else
00644 {
00645 if (d1 > n1)
00646 {
00647
00648
00649 q0 = 0;
00650 q1 = 0;
00651
00652
00653 if (rp != 0)
00654 {
00655 rr.s.low = n0;
00656 rr.s.high = n1;
00657 *rp = rr.ll;
00658 }
00659 }
00660 else
00661 {
00662
00663
00664 count_leading_zeros (bm, d1);
00665 if (bm == 0)
00666 {
00667
00668
00669
00670
00671
00672
00673
00674
00675 if (n1 > d1 || n0 >= d0)
00676 {
00677 q0 = 1;
00678 sub_ddmmss (n1, n0, n1, n0, d1, d0);
00679 }
00680 else
00681 q0 = 0;
00682
00683 q1 = 0;
00684
00685 if (rp != 0)
00686 {
00687 rr.s.low = n0;
00688 rr.s.high = n1;
00689 *rp = rr.ll;
00690 }
00691 }
00692 else
00693 {
00694 UWtype m1, m0;
00695
00696
00697 b = W_TYPE_SIZE - bm;
00698
00699 d1 = (d1 << bm) | (d0 >> b);
00700 d0 = d0 << bm;
00701 n2 = n1 >> b;
00702 n1 = (n1 << bm) | (n0 >> b);
00703 n0 = n0 << bm;
00704
00705 udiv_qrnnd (q0, n1, n2, n1, d1);
00706 umul_ppmm (m1, m0, q0, d0);
00707
00708 if (m1 > n1 || (m1 == n1 && m0 > n0))
00709 {
00710 q0--;
00711 sub_ddmmss (m1, m0, m1, m0, d1, d0);
00712 }
00713
00714 q1 = 0;
00715
00716
00717 if (rp != 0)
00718 {
00719 sub_ddmmss (n1, n0, n1, n0, m1, m0);
00720 rr.s.low = (n1 << b) | (n0 >> bm);
00721 rr.s.high = n1 >> bm;
00722 *rp = rr.ll;
00723 }
00724 }
00725 }
00726 }
00727
00728 ww.s.low = q0;
00729 ww.s.high = q1;
00730 return ww.ll;
00731 }
00732 #endif
00733
00734 #ifdef L_divdi3
00735 DWtype
00736 __divdi3 (DWtype u, DWtype v)
00737 {
00738 word_type c = 0;
00739 DWunion uu, vv;
00740 DWtype w;
00741
00742 uu.ll = u;
00743 vv.ll = v;
00744
00745 if (uu.s.high < 0)
00746 c = ~c,
00747 uu.ll = -uu.ll;
00748 if (vv.s.high < 0)
00749 c = ~c,
00750 vv.ll = -vv.ll;
00751
00752 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
00753 if (c)
00754 w = -w;
00755
00756 return w;
00757 }
00758 #endif
00759
00760 #ifdef L_moddi3
00761 DWtype
00762 __moddi3 (DWtype u, DWtype v)
00763 {
00764 word_type c = 0;
00765 DWunion uu, vv;
00766 DWtype w;
00767
00768 uu.ll = u;
00769 vv.ll = v;
00770
00771 if (uu.s.high < 0)
00772 c = ~c,
00773 uu.ll = -uu.ll;
00774 if (vv.s.high < 0)
00775 vv.ll = -vv.ll;
00776
00777 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
00778 if (c)
00779 w = -w;
00780
00781 return w;
00782 }
00783 #endif
00784
00785 #ifdef L_umoddi3
00786 UDWtype
00787 __umoddi3 (UDWtype u, UDWtype v)
00788 {
00789 UDWtype w;
00790
00791 (void) __udivmoddi4 (u, v, &w);
00792
00793 return w;
00794 }
00795 #endif
00796
00797 #ifdef L_udivdi3
00798 UDWtype
00799 __udivdi3 (UDWtype n, UDWtype d)
00800 {
00801 return __udivmoddi4 (n, d, (UDWtype *) 0);
00802 }
00803 #endif
00804
00805 #ifdef L_cmpdi2
00806 word_type
00807 __cmpdi2 (DWtype a, DWtype b)
00808 {
00809 DWunion au, bu;
00810
00811 au.ll = a, bu.ll = b;
00812
00813 if (au.s.high < bu.s.high)
00814 return 0;
00815 else if (au.s.high > bu.s.high)
00816 return 2;
00817 if ((UWtype) au.s.low < (UWtype) bu.s.low)
00818 return 0;
00819 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
00820 return 2;
00821 return 1;
00822 }
00823 #endif
00824
00825 #ifdef L_ucmpdi2
00826 word_type
00827 __ucmpdi2 (DWtype a, DWtype b)
00828 {
00829 DWunion au, bu;
00830
00831 au.ll = a, bu.ll = b;
00832
00833 if ((UWtype) au.s.high < (UWtype) bu.s.high)
00834 return 0;
00835 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
00836 return 2;
00837 if ((UWtype) au.s.low < (UWtype) bu.s.low)
00838 return 0;
00839 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
00840 return 2;
00841 return 1;
00842 }
00843 #endif
00844
00845 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
00846 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
00847 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
00848
00849 DWtype
00850 __fixunstfDI (TFtype a)
00851 {
00852 TFtype b;
00853 UDWtype v;
00854
00855 if (a < 0)
00856 return 0;
00857
00858
00859 b = (a / HIGH_WORD_COEFF);
00860
00861
00862 v = (UWtype) b;
00863 v <<= WORD_SIZE;
00864
00865 a -= (TFtype)v;
00866
00867
00868
00869 if (a < 0)
00870 v -= (UWtype) (- a);
00871 else
00872 v += (UWtype) a;
00873 return v;
00874 }
00875 #endif
00876
00877 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
00878 DWtype
00879 __fixtfdi (TFtype a)
00880 {
00881 if (a < 0)
00882 return - __fixunstfDI (-a);
00883 return __fixunstfDI (a);
00884 }
00885 #endif
00886
00887 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
00888 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
00889 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
00890
00891 DWtype
00892 __fixunsxfDI (XFtype a)
00893 {
00894 XFtype b;
00895 UDWtype v;
00896
00897 if (a < 0)
00898 return 0;
00899
00900
00901 b = (a / HIGH_WORD_COEFF);
00902
00903
00904 v = (UWtype) b;
00905 v <<= WORD_SIZE;
00906
00907 a -= (XFtype)v;
00908
00909
00910
00911 if (a < 0)
00912 v -= (UWtype) (- a);
00913 else
00914 v += (UWtype) a;
00915 return v;
00916 }
00917 #endif
00918
00919 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
00920 DWtype
00921 __fixxfdi (XFtype a)
00922 {
00923 if (a < 0)
00924 return - __fixunsxfDI (-a);
00925 return __fixunsxfDI (a);
00926 }
00927 #endif
00928
00929 #ifdef L_fixunsdfdi
00930 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
00931 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
00932
00933 DWtype
00934 __fixunsdfDI (DFtype a)
00935 {
00936 DFtype b;
00937 UDWtype v;
00938
00939 if (a < 0)
00940 return 0;
00941
00942
00943 b = (a / HIGH_WORD_COEFF);
00944
00945
00946 v = (UWtype) b;
00947 v <<= WORD_SIZE;
00948
00949 a -= (DFtype)v;
00950
00951
00952
00953 if (a < 0)
00954 v -= (UWtype) (- a);
00955 else
00956 v += (UWtype) a;
00957 return v;
00958 }
00959 #endif
00960
00961 #ifdef L_fixdfdi
00962 DWtype
00963 __fixdfdi (DFtype a)
00964 {
00965 if (a < 0)
00966 return - __fixunsdfDI (-a);
00967 return __fixunsdfDI (a);
00968 }
00969 #endif
00970
00971 #ifdef L_fixunssfdi
00972 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
00973 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
00974
00975 DWtype
00976 __fixunssfDI (SFtype original_a)
00977 {
00978
00979
00980
00981 DFtype a = original_a;
00982 DFtype b;
00983 UDWtype v;
00984
00985 if (a < 0)
00986 return 0;
00987
00988
00989 b = (a / HIGH_WORD_COEFF);
00990
00991
00992 v = (UWtype) b;
00993 v <<= WORD_SIZE;
00994
00995 a -= (DFtype) v;
00996
00997
00998
00999 if (a < 0)
01000 v -= (UWtype) (- a);
01001 else
01002 v += (UWtype) a;
01003 return v;
01004 }
01005 #endif
01006
01007 #ifdef L_fixsfdi
01008 DWtype
01009 __fixsfdi (SFtype a)
01010 {
01011 if (a < 0)
01012 return - __fixunssfDI (-a);
01013 return __fixunssfDI (a);
01014 }
01015 #endif
01016
01017 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
01018 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
01019 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
01020 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
01021
01022 XFtype
01023 __floatdixf (DWtype u)
01024 {
01025 XFtype d;
01026
01027 d = (Wtype) (u >> WORD_SIZE);
01028 d *= HIGH_HALFWORD_COEFF;
01029 d *= HIGH_HALFWORD_COEFF;
01030 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
01031
01032 return d;
01033 }
01034 #endif
01035
01036 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
01037 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
01038 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
01039 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
01040
01041 TFtype
01042 __floatditf (DWtype u)
01043 {
01044 TFtype d;
01045
01046 d = (Wtype) (u >> WORD_SIZE);
01047 d *= HIGH_HALFWORD_COEFF;
01048 d *= HIGH_HALFWORD_COEFF;
01049 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
01050
01051 return d;
01052 }
01053 #endif
01054
01055 #ifdef L_floatdidf
01056 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
01057 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
01058 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
01059
01060 DFtype
01061 __floatdidf (DWtype u)
01062 {
01063 DFtype d;
01064
01065 d = (Wtype) (u >> WORD_SIZE);
01066 d *= HIGH_HALFWORD_COEFF;
01067 d *= HIGH_HALFWORD_COEFF;
01068 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
01069
01070 return d;
01071 }
01072 #endif
01073
01074 #ifdef L_floatdisf
01075 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
01076 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
01077 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
01078
01079 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
01080 #define DF_SIZE DBL_MANT_DIG
01081 #define SF_SIZE FLT_MANT_DIG
01082
01083 SFtype
01084 __floatdisf (DWtype u)
01085 {
01086
01087
01088
01089 DFtype f;
01090
01091
01092
01093
01094
01095
01096
01097 if (DF_SIZE < DI_SIZE
01098 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
01099 {
01100 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
01101 if (! (- ((DWtype) 1 << DF_SIZE) < u
01102 && u < ((DWtype) 1 << DF_SIZE)))
01103 {
01104 if ((UDWtype) u & (REP_BIT - 1))
01105 {
01106 u &= ~ (REP_BIT - 1);
01107 u |= REP_BIT;
01108 }
01109 }
01110 }
01111 f = (Wtype) (u >> WORD_SIZE);
01112 f *= HIGH_HALFWORD_COEFF;
01113 f *= HIGH_HALFWORD_COEFF;
01114 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
01115
01116 return (SFtype) f;
01117 }
01118 #endif
01119
01120 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
01121
01122 #undef char
01123 #undef short
01124 #undef int
01125 #undef long
01126 #undef unsigned
01127 #undef float
01128 #undef double
01129 #undef MIN
01130 #undef MAX
01131 #include <limits.h>
01132
01133 UWtype
01134 __fixunsxfSI (XFtype a)
01135 {
01136 if (a >= - (DFtype) Wtype_MIN)
01137 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
01138 return (Wtype) a;
01139 }
01140 #endif
01141
01142 #ifdef L_fixunsdfsi
01143
01144 #undef char
01145 #undef short
01146 #undef int
01147 #undef long
01148 #undef unsigned
01149 #undef float
01150 #undef double
01151 #undef MIN
01152 #undef MAX
01153 #include <limits.h>
01154
01155 UWtype
01156 __fixunsdfSI (DFtype a)
01157 {
01158 if (a >= - (DFtype) Wtype_MIN)
01159 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
01160 return (Wtype) a;
01161 }
01162 #endif
01163
01164 #ifdef L_fixunssfsi
01165
01166 #undef char
01167 #undef short
01168 #undef int
01169 #undef long
01170 #undef unsigned
01171 #undef float
01172 #undef double
01173 #undef MIN
01174 #undef MAX
01175 #include <limits.h>
01176
01177 UWtype
01178 __fixunssfSI (SFtype a)
01179 {
01180 if (a >= - (SFtype) Wtype_MIN)
01181 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
01182 return (Wtype) a;
01183 }
01184 #endif
01185
01186
01187
01188 #define SItype bogus_type
01189 #define USItype bogus_type
01190 #define DItype bogus_type
01191 #define UDItype bogus_type
01192 #define SFtype bogus_type
01193 #define DFtype bogus_type
01194 #undef Wtype
01195 #undef UWtype
01196 #undef HWtype
01197 #undef UHWtype
01198 #undef DWtype
01199 #undef UDWtype
01200
01201 #undef char
01202 #undef short
01203 #undef int
01204 #undef long
01205 #undef unsigned
01206 #undef float
01207 #undef double
01208
01209 #ifdef L__gcc_bcmp
01210
01211
01212
01213
01214
01215 int
01216 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
01217 {
01218 while (size > 0)
01219 {
01220 unsigned char c1 = *s1++, c2 = *s2++;
01221 if (c1 != c2)
01222 return c1 - c2;
01223 size--;
01224 }
01225 return 0;
01226 }
01227
01228 #endif
01229
01230
01231
01232
01233
01234 #ifdef L_eprintf
01235 #ifndef inhibit_libc
01236
01237 #undef NULL
01238 #include <stdio.h>
01239
01240 void
01241 __eprintf (const char *string, const char *expression,
01242 unsigned int line, const char *filename)
01243 {
01244 fprintf (stderr, string, expression, line, filename);
01245 fflush (stderr);
01246 abort ();
01247 }
01248
01249 #endif
01250 #endif
01251
01252 #ifdef L_bb
01253
01254 struct bb_function_info {
01255 long checksum;
01256 int arc_count;
01257 const char *name;
01258 };
01259
01260
01261 struct bb
01262 {
01263 long zero_word;
01264 const char *filename;
01265 gcov_type *counts;
01266 long ncounts;
01267 struct bb *next;
01268
01269
01270 long sizeof_bb;
01271 struct bb_function_info *function_infos;
01272 };
01273
01274 #ifndef inhibit_libc
01275
01276
01277
01278 #undef NULL
01279 #include <stdio.h>
01280
01281 #include "gcov-io.h"
01282 #include <string.h>
01283 #ifdef TARGET_HAS_F_SETLKW
01284 #include <fcntl.h>
01285 #include <errno.h>
01286 #endif
01287
01288
01289 static struct bb *bb_head;
01290
01291
01292
01293
01294 void
01295 __bb_exit_func (void)
01296 {
01297 struct bb *ptr;
01298 int i;
01299 gcov_type program_sum = 0;
01300 gcov_type program_max = 0;
01301 long program_arcs = 0;
01302 gcov_type merged_sum = 0;
01303 gcov_type merged_max = 0;
01304 long merged_arcs = 0;
01305
01306 #if defined (TARGET_HAS_F_SETLKW)
01307 struct flock s_flock;
01308
01309 s_flock.l_type = F_WRLCK;
01310 s_flock.l_whence = SEEK_SET;
01311 s_flock.l_start = 0;
01312 s_flock.l_len = 0;
01313 s_flock.l_pid = getpid ();
01314 #endif
01315
01316
01317 for (ptr = bb_head; ptr; ptr = ptr->next)
01318 {
01319 for (i = 0; i < ptr->ncounts; i++)
01320 {
01321 program_sum += ptr->counts[i];
01322
01323 if (ptr->counts[i] > program_max)
01324 program_max = ptr->counts[i];
01325 }
01326 program_arcs += ptr->ncounts;
01327 }
01328
01329 for (ptr = bb_head; ptr; ptr = ptr->next)
01330 {
01331 FILE *da_file;
01332 gcov_type object_max = 0;
01333 gcov_type object_sum = 0;
01334 long object_functions = 0;
01335 int merging = 0;
01336 int error = 0;
01337 struct bb_function_info *fn_info;
01338 gcov_type *count_ptr;
01339
01340
01341 da_file = fopen (ptr->filename, "r+b");
01342
01343 if (da_file)
01344 merging = 1;
01345 else
01346 {
01347
01348 da_file = fopen (ptr->filename, "ab");
01349
01350
01351
01352
01353
01354 if (!da_file)
01355 da_file = fopen (ptr->filename, "a");
01356 }
01357
01358 if (!da_file)
01359 {
01360 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
01361 ptr->filename);
01362 ptr->filename = 0;
01363 continue;
01364 }
01365
01366 #if defined (TARGET_HAS_F_SETLKW)
01367
01368
01369
01370 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
01371 && errno == EINTR)
01372 continue;
01373 #endif
01374 for (fn_info = ptr->function_infos; fn_info->arc_count != -1; fn_info++)
01375 object_functions++;
01376
01377 if (merging)
01378 {
01379
01380 long tmp_long;
01381 gcov_type tmp_gcov;
01382
01383 if (
01384 (__read_long (&tmp_long, da_file, 4) || tmp_long != -123l)
01385
01386 || (__read_long (&tmp_long, da_file, 4)
01387 || tmp_long != object_functions)
01388
01389 || (__read_long (&tmp_long, da_file, 4)
01390 || fseek (da_file, tmp_long, SEEK_CUR)))
01391 {
01392 read_error:;
01393 fprintf (stderr, "arc profiling: Error merging output file %s.\n",
01394 ptr->filename);
01395 clearerr (da_file);
01396 }
01397 else
01398 {
01399
01400 count_ptr = ptr->counts;
01401
01402 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
01403 fn_info++)
01404 {
01405 if (
01406 (__read_long (&tmp_long, da_file, 4)
01407 || tmp_long != -1)
01408
01409 || (__read_long (&tmp_long, da_file, 4)
01410 || tmp_long != (long) strlen (fn_info->name))
01411
01412 || fseek (da_file, ((tmp_long + 1) + 3) & ~3, SEEK_CUR)
01413
01414 || (__read_long (&tmp_long, da_file, 4)
01415 || tmp_long != -1))
01416 goto read_error;
01417
01418 if (
01419 (__read_long (&tmp_long, da_file, 4)
01420 || tmp_long != fn_info->checksum)
01421
01422 || (__read_long (&tmp_long, da_file, 4)
01423 || tmp_long != fn_info->arc_count))
01424 goto read_error;
01425
01426 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
01427 if (__read_gcov_type (&tmp_gcov, da_file, 8))
01428 goto read_error;
01429 else
01430 *count_ptr += tmp_gcov;
01431 }
01432 }
01433 fseek (da_file, 0, SEEK_SET);
01434 }
01435
01436
01437 for (i = 0; i < ptr->ncounts; i++)
01438 {
01439 object_sum += ptr->counts[i];
01440
01441 if (ptr->counts[i] > object_max)
01442 object_max = ptr->counts[i];
01443 }
01444 merged_sum += object_sum;
01445 if (merged_max < object_max)
01446 merged_max = object_max;
01447 merged_arcs += ptr->ncounts;
01448
01449
01450 if (
01451 __write_long (-123, da_file, 4)
01452
01453 || __write_long (object_functions, da_file, 4)
01454
01455 || __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4)
01456
01457
01458
01459
01460 || __write_long (merging ? ptr->ncounts : program_arcs, da_file, 4)
01461
01462 || __write_gcov_type (merging ? object_sum : program_sum, da_file, 8)
01463
01464 || __write_gcov_type (merging ? object_max : program_max, da_file, 8)
01465
01466
01467
01468 || __write_long (ptr->ncounts, da_file, 4)
01469
01470 || __write_gcov_type (object_sum, da_file, 8)
01471
01472 || __write_gcov_type (object_max, da_file, 8))
01473 {
01474 write_error:;
01475 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
01476 ptr->filename);
01477 error = 1;
01478 }
01479 else
01480 {
01481
01482 count_ptr = ptr->counts;
01483
01484 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
01485 fn_info++)
01486 {
01487 if (__write_gcov_string (fn_info->name,
01488 strlen (fn_info->name), da_file, -1)
01489 || __write_long (fn_info->checksum, da_file, 4)
01490 || __write_long (fn_info->arc_count, da_file, 4))
01491 goto write_error;
01492
01493 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
01494 if (__write_gcov_type (*count_ptr, da_file, 8))
01495 goto write_error;
01496 }
01497 }
01498
01499 if (fclose (da_file))
01500 {
01501 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
01502 ptr->filename);
01503 error = 1;
01504 }
01505 if (error || !merging)
01506 ptr->filename = 0;
01507 }
01508
01509
01510 for (ptr = bb_head; ptr; ptr = ptr->next)
01511 if (ptr->filename)
01512 {
01513 FILE *da_file;
01514
01515 da_file = fopen (ptr->filename, "r+b");
01516 if (!da_file)
01517 {
01518 fprintf (stderr, "arc profiling: Cannot reopen %s.\n",
01519 ptr->filename);
01520 continue;
01521 }
01522
01523 #if defined (TARGET_HAS_F_SETLKW)
01524 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
01525 && errno == EINTR)
01526 continue;
01527 #endif
01528
01529 if (fseek (da_file, 4 * 3, SEEK_SET)
01530
01531 || __write_long (merged_arcs, da_file, 4)
01532
01533 || __write_gcov_type (merged_sum, da_file, 8)
01534
01535 || __write_gcov_type (merged_max, da_file, 8))
01536 fprintf (stderr, "arc profiling: Error updating program header %s.\n",
01537 ptr->filename);
01538 if (fclose (da_file))
01539 fprintf (stderr, "arc profiling: Error reclosing %s\n",
01540 ptr->filename);
01541 }
01542 }
01543
01544
01545
01546
01547 void
01548 __bb_init_func (struct bb *blocks)
01549 {
01550 if (blocks->zero_word)
01551 return;
01552
01553
01554 if (!bb_head)
01555 atexit (__bb_exit_func);
01556
01557
01558 blocks->zero_word = 1;
01559 blocks->next = bb_head;
01560 bb_head = blocks;
01561 }
01562
01563
01564
01565
01566
01567 void
01568 __bb_fork_func (void)
01569 {
01570 struct bb *ptr;
01571
01572 __bb_exit_func ();
01573 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
01574 {
01575 long i;
01576 for (i = ptr->ncounts - 1; i >= 0; i--)
01577 ptr->counts[i] = 0;
01578 }
01579 }
01580
01581 #endif
01582 #endif
01583
01584 #ifdef L_clear_cache
01585
01586
01587 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
01588
01589 void
01590 __clear_cache (char *beg __attribute__((__unused__)),
01591 char *end __attribute__((__unused__)))
01592 {
01593 #ifdef CLEAR_INSN_CACHE
01594 CLEAR_INSN_CACHE (beg, end);
01595 #else
01596 #ifdef INSN_CACHE_SIZE
01597 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
01598 static int initialized;
01599 int offset;
01600 void *start_addr
01601 void *end_addr;
01602 typedef (*function_ptr) (void);
01603
01604 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
01605
01606
01607
01608
01609 if (! initialized)
01610 {
01611 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
01612 & -INSN_CACHE_LINE_WIDTH);
01613 int end_ptr = ptr + INSN_CACHE_SIZE;
01614
01615 while (ptr < end_ptr)
01616 {
01617 *(INSTRUCTION_TYPE *)ptr
01618 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
01619 ptr += INSN_CACHE_LINE_WIDTH;
01620 }
01621 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
01622
01623 initialized = 1;
01624 }
01625
01626
01627 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
01628 & -INSN_CACHE_LINE_WIDTH))
01629 ());
01630
01631 #else
01632
01633 if (! initialized)
01634 {
01635 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
01636 & -INSN_CACHE_LINE_WIDTH);
01637
01638 while (ptr < (int) array + sizeof array)
01639 {
01640 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
01641 ptr += INSN_CACHE_LINE_WIDTH;
01642 }
01643
01644 initialized = 1;
01645 }
01646
01647
01648
01649 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
01650 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
01651 & -INSN_CACHE_PLANE_SIZE)
01652 + offset);
01653
01654
01655 #if 0
01656
01657
01658 if (end < beg + INSN_CACHE_PLANE_SIZE)
01659 #endif
01660 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
01661 & -INSN_CACHE_LINE_WIDTH)
01662 & (INSN_CACHE_PLANE_SIZE - 1));
01663
01664 #if INSN_CACHE_DEPTH > 1
01665 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
01666 if (end_addr <= start_addr)
01667 end_addr += INSN_CACHE_PLANE_SIZE;
01668
01669 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
01670 {
01671 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
01672 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
01673
01674 while (addr != stop)
01675 {
01676
01677 ((function_ptr) addr) ();
01678
01679 addr += INSN_CACHE_LINE_WIDTH;
01680 }
01681 }
01682 #else
01683 do
01684 {
01685
01686 ((function_ptr) start_addr) ();
01687
01688 start_addr += INSN_CACHE_LINE_WIDTH;
01689 }
01690 while ((start_addr % INSN_CACHE_SIZE) != offset);
01691 #endif
01692 #endif
01693 #endif
01694 #endif
01695 }
01696
01697 #endif
01698
01699 #ifdef L_trampoline
01700
01701
01702
01703 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
01704
01705 long
01706 getpagesize (void)
01707 {
01708 #ifdef _ALPHA_
01709 return 8192;
01710 #else
01711 return 4096;
01712 #endif
01713 }
01714
01715 #ifdef __i386__
01716 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
01717 #endif
01718
01719 int
01720 mprotect (char *addr, int len, int prot)
01721 {
01722 int np, op;
01723
01724 if (prot == 7)
01725 np = 0x40;
01726 else if (prot == 5)
01727 np = 0x20;
01728 else if (prot == 4)
01729 np = 0x10;
01730 else if (prot == 3)
01731 np = 0x04;
01732 else if (prot == 1)
01733 np = 0x02;
01734 else if (prot == 0)
01735 np = 0x01;
01736
01737 if (VirtualProtect (addr, len, np, &op))
01738 return 0;
01739 else
01740 return -1;
01741 }
01742
01743 #endif
01744
01745 #ifdef TRANSFER_FROM_TRAMPOLINE
01746 TRANSFER_FROM_TRAMPOLINE
01747 #endif
01748
01749 #ifdef __sysV68__
01750
01751 #include <sys/signal.h>
01752 #include <errno.h>
01753
01754
01755
01756
01757
01758
01759 #ifdef MCT_TEXT
01760 asm("\n\
01761 global memctl\n\
01762 memctl:\n\
01763 movq &75,%d0\n\
01764 trap &0\n\
01765 bcc.b noerror\n\
01766 jmp cerror%\n\
01767 noerror:\n\
01768 movq &0,%d0\n\
01769 rts");
01770 #endif
01771
01772
01773
01774
01775 void
01776 __clear_insn_cache (void)
01777 {
01778 #ifdef MCT_TEXT
01779 int save_errno;
01780
01781
01782
01783 save_errno = errno;
01784
01785
01786
01787 memctl(0, 4096, MCT_TEXT);
01788 errno = save_errno;
01789 #endif
01790 }
01791
01792 #endif
01793 #endif
01794
01795 #ifndef __CYGWIN__
01796 #ifdef L__main
01797
01798 #include "gbl-ctors.h"
01799
01800
01801
01802
01803 #ifndef NAME__MAIN
01804 #define NAME__MAIN "__main"
01805 #define SYMBOL__MAIN __main
01806 #endif
01807
01808 #ifdef INIT_SECTION_ASM_OP
01809 #undef HAS_INIT_SECTION
01810 #define HAS_INIT_SECTION
01811 #endif
01812
01813 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
01814
01815
01816
01817
01818 #ifdef EH_FRAME_SECTION_NAME
01819 #include "unwind-dw2-fde.h"
01820 extern unsigned char __EH_FRAME_BEGIN__[];
01821 #endif
01822
01823
01824
01825 void
01826 __do_global_dtors (void)
01827 {
01828 #ifdef DO_GLOBAL_DTORS_BODY
01829 DO_GLOBAL_DTORS_BODY;
01830 #else
01831 static func_ptr *p = __DTOR_LIST__ + 1;
01832 while (*p)
01833 {
01834 p++;
01835 (*(p-1)) ();
01836 }
01837 #endif
01838 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
01839 {
01840 static int completed = 0;
01841 if (! completed)
01842 {
01843 completed = 1;
01844 __deregister_frame_info (__EH_FRAME_BEGIN__);
01845 }
01846 }
01847 #endif
01848 }
01849 #endif
01850
01851 #ifndef HAS_INIT_SECTION
01852
01853
01854 void
01855 __do_global_ctors (void)
01856 {
01857 #ifdef EH_FRAME_SECTION_NAME
01858 {
01859 static struct object object;
01860 __register_frame_info (__EH_FRAME_BEGIN__, &object);
01861 }
01862 #endif
01863 DO_GLOBAL_CTORS_BODY;
01864 atexit (__do_global_dtors);
01865 }
01866 #endif
01867
01868 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
01869
01870
01871
01872
01873
01874
01875
01876
01877 void
01878 SYMBOL__MAIN ()
01879 {
01880
01881 static int initialized;
01882 if (! initialized)
01883 {
01884 initialized = 1;
01885 __do_global_ctors ();
01886 }
01887 }
01888 #endif
01889
01890 #endif
01891 #endif
01892
01893 #ifdef L_ctors
01894
01895 #include "gbl-ctors.h"
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
01911 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
01912 func_ptr __CTOR_LIST__[2] = {0, 0};
01913 func_ptr __DTOR_LIST__[2] = {0, 0};
01914 #else
01915 func_ptr __CTOR_LIST__[2];
01916 func_ptr __DTOR_LIST__[2];
01917 #endif
01918 #endif
01919 #endif
01920
01921 #ifdef L_exit
01922
01923 #include "gbl-ctors.h"
01924
01925 #ifdef NEED_ATEXIT
01926
01927 #ifndef ON_EXIT
01928
01929 # include <errno.h>
01930
01931 static func_ptr *atexit_chain = 0;
01932 static long atexit_chain_length = 0;
01933 static volatile long last_atexit_chain_slot = -1;
01934
01935 int
01936 atexit (func_ptr func)
01937 {
01938 if (++last_atexit_chain_slot == atexit_chain_length)
01939 {
01940 atexit_chain_length += 32;
01941 if (atexit_chain)
01942 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
01943 * sizeof (func_ptr));
01944 else
01945 atexit_chain = (func_ptr *) malloc (atexit_chain_length
01946 * sizeof (func_ptr));
01947 if (! atexit_chain)
01948 {
01949 atexit_chain_length = 0;
01950 last_atexit_chain_slot = -1;
01951 errno = ENOMEM;
01952 return (-1);
01953 }
01954 }
01955 atexit_chain[last_atexit_chain_slot] = func;
01956 return (0);
01957 }
01958
01959 extern void _cleanup (void);
01960 extern void _exit (int) __attribute__ ((__noreturn__));
01961
01962 void
01963 exit (int status)
01964 {
01965 if (atexit_chain)
01966 {
01967 for ( ; last_atexit_chain_slot-- >= 0; )
01968 {
01969 (*atexit_chain[last_atexit_chain_slot + 1]) ();
01970 atexit_chain[last_atexit_chain_slot + 1] = 0;
01971 }
01972 free (atexit_chain);
01973 atexit_chain = 0;
01974 }
01975 #ifdef EXIT_BODY
01976 EXIT_BODY;
01977 #else
01978 _cleanup ();
01979 #endif
01980 _exit (status);
01981 }
01982
01983 #else
01984
01985
01986 int
01987 atexit (func_ptr func)
01988 {
01989 return ON_EXIT (func);
01990 }
01991
01992 #endif
01993 #endif
01994
01995 #endif