1 /* More subroutines needed by GCC output code on some machines. */ 2 /* Compile this one with gcc. */ 3 /* Copyright (C) 1989, 1992 Free Software Foundation, Inc. 4 5 This file is part of GNU CC. 6 7 GNU CC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GNU CC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU CC; see the file COPYING. If not, write to 19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 20 21 /* As a special exception, if you link this library with files 22 compiled with GCC to produce an executable, this does not cause 23 the resulting executable to be covered by the GNU General Public License. 24 This exception does not however invalidate any other reasons why 25 the executable file might be covered by the GNU General Public License. */ 26 27 /* It is incorrect to include config.h here, because this file is being 28 compiled for the target, and hence definitions concerning only the host 29 do not apply. */ 30 31 #include "tconfig.h" 32 #include "machmode.h" 33 #ifndef L_trampoline 34 #include "gstddef.h" 35 #endif 36 37 /* Don't use `fancy_abort' here even if config.h says to use it. */ 38 #ifdef abort 39 #undef abort 40 #endif 41 42 /* In the first part of this file, we are interfacing to calls generated 43 by the compiler itself. These calls pass values into these routines 44 which have very specific modes (rather than very specific types), and 45 these compiler-generated calls also expect any return values to have 46 very specific modes (rather than very specific types). Thus, we need 47 to avoid using regular C language type names in this part of the file 48 because the sizes for those types can be configured to be anything. 49 Instead we use the following special type names. */ 50 51 typedef unsigned int UQItype __attribute__ ((mode (QI))); 52 typedef int SItype __attribute__ ((mode (SI))); 53 typedef unsigned int USItype __attribute__ ((mode (SI))); 54 typedef int DItype __attribute__ ((mode (DI))); 55 typedef unsigned int UDItype __attribute__ ((mode (DI))); 56 typedef float SFtype __attribute__ ((mode (SF))); 57 typedef float DFtype __attribute__ ((mode (DF))); 58 #if 0 59 typedef float XFtype __attribute__ ((mode (XF))); 60 #endif 61 #if LONG_DOUBLE_TYPE_SIZE == 128 62 typedef float TFtype __attribute__ ((mode (TF))); 63 #endif 64 65 /* Make sure that we don't accidentaly use any normal C language built-in 66 type names in the first part of this file. Instead we want to use *only* 67 the type names defined above. The following macro definitions insure 68 that if we *do* accidently use soem normal C language built-in type name, 69 we will get a syntax error. */ 70 71 #define char bogus_type 72 #define short bogus_type 73 #define int bogus_type 74 #define long bogus_type 75 #define unsigned bogus_type 76 #define float bogus_type 77 #define double bogus_type 78 79 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) 80 81 /* DIstructs are pairs of SItype values in the order determined by 82 WORDS_BIG_ENDIAN. */ 83 84 #if WORDS_BIG_ENDIAN 85 struct DIstruct {SItype high, low;}; 86 #else 87 struct DIstruct {SItype low, high;}; 88 #endif 89 90 /* We need this union to unpack/pack DImode values, since we don't have 91 any arithmetic yet. Incoming DImode parameters are stored into the 92 `ll' field, and the unpacked result is read from the struct `s'. */ 93 94 typedef union 95 { 96 struct DIstruct s; 97 DItype ll; 98 } DIunion; 99 100 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv) 101 102 #include "longlong.h" 103 104 #endif /* udiv or mul */ 105 106 extern DItype __fixunssfdi (SFtype a); 107 extern DItype __fixunsdfdi (DFtype a); 108 109 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3) 110 #if defined (L_divdi3) || defined (L_moddi3) 111 static inline 112 #endif 113 DItype 114 __negdi2 (u) 115 DItype u; 116 { 117 DIunion w; 118 DIunion uu; 119 120 uu.ll = u; 121 122 w.s.low = -uu.s.low; 123 w.s.high = -uu.s.high - ((USItype) w.s.low > 0); 124 125 return w.ll; 126 } 127 #endif 128 129 #ifdef L_lshldi3 130 DItype 131 __lshldi3 (u, b) 132 DItype u; 133 SItype b; 134 { 135 DIunion w; 136 SItype bm; 137 DIunion uu; 138 139 if (b == 0) 140 return u; 141 142 uu.ll = u; 143 144 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 145 if (bm <= 0) 146 { 147 w.s.low = 0; 148 w.s.high = (USItype)uu.s.low << -bm; 149 } 150 else 151 { 152 USItype carries = (USItype)uu.s.low >> bm; 153 w.s.low = (USItype)uu.s.low << b; 154 w.s.high = ((USItype)uu.s.high << b) | carries; 155 } 156 157 return w.ll; 158 } 159 #endif 160 161 #ifdef L_lshrdi3 162 DItype 163 __lshrdi3 (u, b) 164 DItype u; 165 SItype b; 166 { 167 DIunion w; 168 SItype bm; 169 DIunion uu; 170 171 if (b == 0) 172 return u; 173 174 uu.ll = u; 175 176 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 177 if (bm <= 0) 178 { 179 w.s.high = 0; 180 w.s.low = (USItype)uu.s.high >> -bm; 181 } 182 else 183 { 184 USItype carries = (USItype)uu.s.high << bm; 185 w.s.high = (USItype)uu.s.high >> b; 186 w.s.low = ((USItype)uu.s.low >> b) | carries; 187 } 188 189 return w.ll; 190 } 191 #endif 192 193 #ifdef L_ashldi3 194 DItype 195 __ashldi3 (u, b) 196 DItype u; 197 SItype b; 198 { 199 DIunion w; 200 SItype bm; 201 DIunion uu; 202 203 if (b == 0) 204 return u; 205 206 uu.ll = u; 207 208 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 209 if (bm <= 0) 210 { 211 w.s.low = 0; 212 w.s.high = (USItype)uu.s.low << -bm; 213 } 214 else 215 { 216 USItype carries = (USItype)uu.s.low >> bm; 217 w.s.low = (USItype)uu.s.low << b; 218 w.s.high = ((USItype)uu.s.high << b) | carries; 219 } 220 221 return w.ll; 222 } 223 #endif 224 225 #ifdef L_ashrdi3 226 DItype 227 __ashrdi3 (u, b) 228 DItype u; 229 SItype b; 230 { 231 DIunion w; 232 SItype bm; 233 DIunion uu; 234 235 if (b == 0) 236 return u; 237 238 uu.ll = u; 239 240 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 241 if (bm <= 0) 242 { 243 /* w.s.high = 1..1 or 0..0 */ 244 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); 245 w.s.low = uu.s.high >> -bm; 246 } 247 else 248 { 249 USItype carries = (USItype)uu.s.high << bm; 250 w.s.high = uu.s.high >> b; 251 w.s.low = ((USItype)uu.s.low >> b) | carries; 252 } 253 254 return w.ll; 255 } 256 #endif 257 258 #ifdef L_muldi3 259 DItype 260 __muldi3 (u, v) 261 DItype u, v; 262 { 263 DIunion w; 264 DIunion uu, vv; 265 266 uu.ll = u, 267 vv.ll = v; 268 269 w.ll = __umulsidi3 (uu.s.low, vv.s.low); 270 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 271 + (USItype) uu.s.high * (USItype) vv.s.low); 272 273 return w.ll; 274 } 275 #endif 276 277 #ifdef L_udiv_w_sdiv 278 USItype 279 __udiv_w_sdiv (rp, a1, a0, d) 280 USItype *rp, a1, a0, d; 281 { 282 USItype q, r; 283 USItype c0, c1, b1; 284 285 if ((SItype) d >= 0) 286 { 287 if (a1 < d - a1 - (a0 >> 31)) 288 { 289 /* dividend, divisor, and quotient are nonnegative */ 290 sdiv_qrnnd (q, r, a1, a0, d); 291 } 292 else 293 { 294 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ 295 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << 31); 296 /* Divide (c1*2^32 + c0) by d */ 297 sdiv_qrnnd (q, r, c1, c0, d); 298 /* Add 2^31 to quotient */ 299 q += (USItype) 1 << 31; 300 } 301 } 302 else 303 { 304 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 305 c1 = a1 >> 1; /* A/2 */ 306 c0 = (a1 << 31) + (a0 >> 1); 307 308 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 309 { 310 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 311 312 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 313 if ((d & 1) != 0) 314 { 315 if (r >= q) 316 r = r - q; 317 else if (q - r <= d) 318 { 319 r = r - q + d; 320 q--; 321 } 322 else 323 { 324 r = r - q + 2*d; 325 q -= 2; 326 } 327 } 328 } 329 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 330 { 331 c1 = (b1 - 1) - c1; 332 c0 = ~c0; /* logical NOT */ 333 334 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 335 336 q = ~q; /* (A/2)/b1 */ 337 r = (b1 - 1) - r; 338 339 r = 2*r + (a0 & 1); /* A/(2*b1) */ 340 341 if ((d & 1) != 0) 342 { 343 if (r >= q) 344 r = r - q; 345 else if (q - r <= d) 346 { 347 r = r - q + d; 348 q--; 349 } 350 else 351 { 352 r = r - q + 2*d; 353 q -= 2; 354 } 355 } 356 } 357 else /* Implies c1 = b1 */ 358 { /* Hence a1 = d - 1 = 2*b1 - 1 */ 359 if (a0 >= -d) 360 { 361 q = -1; 362 r = a0 + d; 363 } 364 else 365 { 366 q = -2; 367 r = a0 + 2*d; 368 } 369 } 370 } 371 372 *rp = r; 373 return q; 374 } 375 #endif 376 377 #ifdef L_udivmoddi4 378 static const UQItype __clz_tab[] = 379 { 380 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, 381 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, 382 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, 383 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, 384 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, 385 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, 386 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, 387 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, 388 }; 389 390 UDItype 391 __udivmoddi4 (n, d, rp) 392 UDItype n, d; 393 UDItype *rp; 394 { 395 DIunion ww; 396 DIunion nn, dd; 397 DIunion rr; 398 USItype d0, d1, n0, n1, n2; 399 USItype q0, q1; 400 USItype b, bm; 401 402 nn.ll = n; 403 dd.ll = d; 404 405 d0 = dd.s.low; 406 d1 = dd.s.high; 407 n0 = nn.s.low; 408 n1 = nn.s.high; 409 410 #if !UDIV_NEEDS_NORMALIZATION 411 if (d1 == 0) 412 { 413 if (d0 > n1) 414 { 415 /* 0q = nn / 0D */ 416 417 udiv_qrnnd (q0, n0, n1, n0, d0); 418 q1 = 0; 419 420 /* Remainder in n0. */ 421 } 422 else 423 { 424 /* qq = NN / 0d */ 425 426 if (d0 == 0) 427 d0 = 1 / d0; /* Divide intentionally by zero. */ 428 429 udiv_qrnnd (q1, n1, 0, n1, d0); 430 udiv_qrnnd (q0, n0, n1, n0, d0); 431 432 /* Remainder in n0. */ 433 } 434 435 if (rp != 0) 436 { 437 rr.s.low = n0; 438 rr.s.high = 0; 439 *rp = rr.ll; 440 } 441 } 442 443 #else /* UDIV_NEEDS_NORMALIZATION */ 444 445 if (d1 == 0) 446 { 447 if (d0 > n1) 448 { 449 /* 0q = nn / 0D */ 450 451 count_leading_zeros (bm, d0); 452 453 if (bm != 0) 454 { 455 /* Normalize, i.e. make the most significant bit of the 456 denominator set. */ 457 458 d0 = d0 << bm; 459 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); 460 n0 = n0 << bm; 461 } 462 463 udiv_qrnnd (q0, n0, n1, n0, d0); 464 q1 = 0; 465 466 /* Remainder in n0 >> bm. */ 467 } 468 else 469 { 470 /* qq = NN / 0d */ 471 472 if (d0 == 0) 473 d0 = 1 / d0; /* Divide intentionally by zero. */ 474 475 count_leading_zeros (bm, d0); 476 477 if (bm == 0) 478 { 479 /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 480 conclude (the most significant bit of n1 is set) /\ (the 481 leading quotient digit q1 = 1). 482 483 This special case is necessary, not an optimization. 484 (Shifts counts of SI_TYPE_SIZE are undefined.) */ 485 486 n1 -= d0; 487 q1 = 1; 488 } 489 else 490 { 491 /* Normalize. */ 492 493 b = SI_TYPE_SIZE - bm; 494 495 d0 = d0 << bm; 496 n2 = n1 >> b; 497 n1 = (n1 << bm) | (n0 >> b); 498 n0 = n0 << bm; 499 500 udiv_qrnnd (q1, n1, n2, n1, d0); 501 } 502 503 /* n1 != d0... */ 504 505 udiv_qrnnd (q0, n0, n1, n0, d0); 506 507 /* Remainder in n0 >> bm. */ 508 } 509 510 if (rp != 0) 511 { 512 rr.s.low = n0 >> bm; 513 rr.s.high = 0; 514 *rp = rr.ll; 515 } 516 } 517 #endif /* UDIV_NEEDS_NORMALIZATION */ 518 519 else 520 { 521 if (d1 > n1) 522 { 523 /* 00 = nn / DD */ 524 525 q0 = 0; 526 q1 = 0; 527 528 /* Remainder in n1n0. */ 529 if (rp != 0) 530 { 531 rr.s.low = n0; 532 rr.s.high = n1; 533 *rp = rr.ll; 534 } 535 } 536 else 537 { 538 /* 0q = NN / dd */ 539 540 count_leading_zeros (bm, d1); 541 if (bm == 0) 542 { 543 /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 544 conclude (the most significant bit of n1 is set) /\ (the 545 quotient digit q0 = 0 or 1). 546 547 This special case is necessary, not an optimization. */ 548 549 /* The condition on the next line takes advantage of that 550 n1 >= d1 (true due to program flow). */ 551 if (n1 > d1 || n0 >= d0) 552 { 553 q0 = 1; 554 sub_ddmmss (n1, n0, n1, n0, d1, d0); 555 } 556 else 557 q0 = 0; 558 559 q1 = 0; 560 561 if (rp != 0) 562 { 563 rr.s.low = n0; 564 rr.s.high = n1; 565 *rp = rr.ll; 566 } 567 } 568 else 569 { 570 USItype m1, m0; 571 /* Normalize. */ 572 573 b = SI_TYPE_SIZE - bm; 574 575 d1 = (d1 << bm) | (d0 >> b); 576 d0 = d0 << bm; 577 n2 = n1 >> b; 578 n1 = (n1 << bm) | (n0 >> b); 579 n0 = n0 << bm; 580 581 udiv_qrnnd (q0, n1, n2, n1, d1); 582 umul_ppmm (m1, m0, q0, d0); 583 584 if (m1 > n1 || (m1 == n1 && m0 > n0)) 585 { 586 q0--; 587 sub_ddmmss (m1, m0, m1, m0, d1, d0); 588 } 589 590 q1 = 0; 591 592 /* Remainder in (n1n0 - m1m0) >> bm. */ 593 if (rp != 0) 594 { 595 sub_ddmmss (n1, n0, n1, n0, m1, m0); 596 rr.s.low = (n1 << b) | (n0 >> bm); 597 rr.s.high = n1 >> bm; 598 *rp = rr.ll; 599 } 600 } 601 } 602 } 603 604 ww.s.low = q0; 605 ww.s.high = q1; 606 return ww.ll; 607 } 608 #endif 609 610 #ifdef L_divdi3 611 UDItype __udivmoddi4 (); 612 DItype 613 __divdi3 (u, v) 614 DItype u, v; 615 { 616 SItype c = 0; 617 DIunion uu, vv; 618 DItype w; 619 620 uu.ll = u; 621 vv.ll = v; 622 623 if (uu.s.high < 0) 624 c = ~c, 625 uu.ll = __negdi2 (uu.ll); 626 if (vv.s.high < 0) 627 c = ~c, 628 vv.ll = __negdi2 (vv.ll); 629 630 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0); 631 if (c) 632 w = __negdi2 (w); 633 634 return w; 635 } 636 #endif 637 638 #ifdef L_moddi3 639 UDItype __udivmoddi4 (); 640 DItype 641 __moddi3 (u, v) 642 DItype u, v; 643 { 644 SItype c = 0; 645 DIunion uu, vv; 646 DItype w; 647 648 uu.ll = u; 649 vv.ll = v; 650 651 if (uu.s.high < 0) 652 c = ~c, 653 uu.ll = __negdi2 (uu.ll); 654 if (vv.s.high < 0) 655 vv.ll = __negdi2 (vv.ll); 656 657 (void) __udivmoddi4 (uu.ll, vv.ll, &w); 658 if (c) 659 w = __negdi2 (w); 660 661 return w; 662 } 663 #endif 664 665 #ifdef L_umoddi3 666 UDItype __udivmoddi4 (); 667 UDItype 668 __umoddi3 (u, v) 669 UDItype u, v; 670 { 671 DItype w; 672 673 (void) __udivmoddi4 (u, v, &w); 674 675 return w; 676 } 677 #endif 678 679 #ifdef L_udivdi3 680 UDItype __udivmoddi4 (); 681 UDItype 682 __udivdi3 (n, d) 683 UDItype n, d; 684 { 685 return __udivmoddi4 (n, d, (UDItype *) 0); 686 } 687 #endif 688 689 #ifdef L_cmpdi2 690 SItype 691 __cmpdi2 (a, b) 692 DItype a, b; 693 { 694 DIunion au, bu; 695 696 au.ll = a, bu.ll = b; 697 698 if (au.s.high < bu.s.high) 699 return 0; 700 else if (au.s.high > bu.s.high) 701 return 2; 702 if ((USItype) au.s.low < (USItype) bu.s.low) 703 return 0; 704 else if ((USItype) au.s.low > (USItype) bu.s.low) 705 return 2; 706 return 1; 707 } 708 #endif 709 710 #ifdef L_ucmpdi2 711 SItype 712 __ucmpdi2 (a, b) 713 DItype a, b; 714 { 715 DIunion au, bu; 716 717 au.ll = a, bu.ll = b; 718 719 if ((USItype) au.s.high < (USItype) bu.s.high) 720 return 0; 721 else if ((USItype) au.s.high > (USItype) bu.s.high) 722 return 2; 723 if ((USItype) au.s.low < (USItype) bu.s.low) 724 return 0; 725 else if ((USItype) au.s.low > (USItype) bu.s.low) 726 return 2; 727 return 1; 728 } 729 #endif 730 731 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128) 732 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 733 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 734 735 DItype 736 __fixunstfdi (a) 737 TFtype a; 738 { 739 TFtype b; 740 UDItype v; 741 742 if (a < 0) 743 return 0; 744 745 /* Compute high word of result, as a flonum. */ 746 b = (a / HIGH_WORD_COEFF); 747 /* Convert that to fixed (but not to DItype!), 748 and shift it into the high word. */ 749 v = (USItype) b; 750 v <<= WORD_SIZE; 751 /* Remove high part from the TFtype, leaving the low part as flonum. */ 752 a -= (TFtype)v; 753 /* Convert that to fixed (but not to DItype!) and add it in. 754 Sometimes A comes out negative. This is significant, since 755 A has more bits than a long int does. */ 756 if (a < 0) 757 v -= (USItype) (- a); 758 else 759 v += (USItype) a; 760 return v; 761 } 762 #endif 763 764 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128) 765 DItype 766 __fixtfdi (a) 767 TFtype a; 768 { 769 if (a < 0) 770 return - __fixunstfdi (-a); 771 return __fixunstfdi (a); 772 } 773 #endif 774 775 #ifdef L_fixunsdfdi 776 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 777 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 778 779 DItype 780 __fixunsdfdi (a) 781 DFtype a; 782 { 783 DFtype b; 784 UDItype v; 785 786 if (a < 0) 787 return 0; 788 789 /* Compute high word of result, as a flonum. */ 790 b = (a / HIGH_WORD_COEFF); 791 /* Convert that to fixed (but not to DItype!), 792 and shift it into the high word. */ 793 v = (USItype) b; 794 v <<= WORD_SIZE; 795 /* Remove high part from the DFtype, leaving the low part as flonum. */ 796 a -= (DFtype)v; 797 /* Convert that to fixed (but not to DItype!) and add it in. 798 Sometimes A comes out negative. This is significant, since 799 A has more bits than a long int does. */ 800 if (a < 0) 801 v -= (USItype) (- a); 802 else 803 v += (USItype) a; 804 return v; 805 } 806 #endif 807 808 #ifdef L_fixdfdi 809 DItype 810 __fixdfdi (a) 811 DFtype a; 812 { 813 if (a < 0) 814 return - __fixunsdfdi (-a); 815 return __fixunsdfdi (a); 816 } 817 #endif 818 819 #ifdef L_fixunssfdi 820 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 821 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 822 823 DItype 824 __fixunssfdi (SFtype original_a) 825 { 826 /* Convert the SFtype to a DFtype, because that is surely not going 827 to lose any bits. Some day someone else can write a faster version 828 that avoids converting to DFtype, and verify it really works right. */ 829 DFtype a = original_a; 830 DFtype b; 831 UDItype v; 832 833 if (a < 0) 834 return 0; 835 836 /* Compute high word of result, as a flonum. */ 837 b = (a / HIGH_WORD_COEFF); 838 /* Convert that to fixed (but not to DItype!), 839 and shift it into the high word. */ 840 v = (USItype) b; 841 v <<= WORD_SIZE; 842 /* Remove high part from the DFtype, leaving the low part as flonum. */ 843 a -= (DFtype)v; 844 /* Convert that to fixed (but not to DItype!) and add it in. 845 Sometimes A comes out negative. This is significant, since 846 A has more bits than a long int does. */ 847 if (a < 0) 848 v -= (USItype) (- a); 849 else 850 v += (USItype) a; 851 return v; 852 } 853 #endif 854 855 #ifdef L_fixsfdi 856 DItype 857 __fixsfdi (SFtype a) 858 { 859 if (a < 0) 860 return - __fixunssfdi (-a); 861 return __fixunssfdi (a); 862 } 863 #endif 864 865 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128) 866 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 867 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 868 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 869 870 TFtype 871 __floatditf (u) 872 DItype u; 873 { 874 TFtype d; 875 SItype negate = 0; 876 877 if (u < 0) 878 u = -u, negate = 1; 879 880 d = (USItype) (u >> WORD_SIZE); 881 d *= HIGH_HALFWORD_COEFF; 882 d *= HIGH_HALFWORD_COEFF; 883 d += (USItype) (u & (HIGH_WORD_COEFF - 1)); 884 885 return (negate ? -d : d); 886 } 887 #endif 888 889 #ifdef L_floatdidf 890 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 891 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 892 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 893 894 DFtype 895 __floatdidf (u) 896 DItype u; 897 { 898 DFtype d; 899 SItype negate = 0; 900 901 if (u < 0) 902 u = -u, negate = 1; 903 904 d = (USItype) (u >> WORD_SIZE); 905 d *= HIGH_HALFWORD_COEFF; 906 d *= HIGH_HALFWORD_COEFF; 907 d += (USItype) (u & (HIGH_WORD_COEFF - 1)); 908 909 return (negate ? -d : d); 910 } 911 #endif 912 913 #ifdef L_floatdisf 914 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 915 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 916 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 917 918 SFtype 919 __floatdisf (u) 920 DItype u; 921 { 922 SFtype f; 923 SItype negate = 0; 924 925 if (u < 0) 926 u = -u, negate = 1; 927 928 f = (USItype) (u >> WORD_SIZE); 929 f *= HIGH_HALFWORD_COEFF; 930 f *= HIGH_HALFWORD_COEFF; 931 f += (USItype) (u & (HIGH_WORD_COEFF - 1)); 932 933 return (negate ? -f : f); 934 } 935 #endif 936 937 #ifdef L_fixunsdfsi 938 #include "glimits.h" 939 940 USItype 941 __fixunsdfsi (a) 942 DFtype a; 943 { 944 if (a >= - (DFtype) LONG_MIN) 945 return (SItype) (a + LONG_MIN) - LONG_MIN; 946 return (SItype) a; 947 } 948 #endif 949 950 #ifdef L_fixunssfsi 951 #include "glimits.h" 952 953 USItype 954 __fixunssfsi (SFtype a) 955 { 956 if (a >= - (SFtype) LONG_MIN) 957 return (SItype) (a + LONG_MIN) - LONG_MIN; 958 return (SItype) a; 959 } 960 #endif 961 962 /* From here on down, the routines use normal data types. */ 963 964 #define SItype bogus_type 965 #define USItype bogus_type 966 #define DItype bogus_type 967 #define UDItype bogus_type 968 #define SFtype bogus_type 969 #define DFtype bogus_type 970 971 #undef char 972 #undef short 973 #undef int 974 #undef long 975 #undef unsigned 976 #undef float 977 #undef double 978 979 #ifdef L__gcc_bcmp 980 981 /* Like bcmp except the sign is meaningful. 982 Reult is negative if S1 is less than S2, 983 positive if S1 is greater, 0 if S1 and S2 are equal. */ 984 985 #include <sys/types.h> 986 987 int 988 __gcc_bcmp (s1, s2, size) 989 unsigned char *s1, *s2; 990 size_t size; 991 { 992 while (size > 0) 993 { 994 unsigned char c1 = *s1++, c2 = *s2++; 995 if (c1 != c2) 996 return c1 - c2; 997 size--; 998 } 999 return 0; 1000 } 1001 1002 #endif 1003 1004 #ifdef L_varargs 1005 #ifdef __i860__ 1006 #if defined(__svr4__) || defined(__alliant__) 1007 asm (" .text"); 1008 asm (" .align 4"); 1009 1010 /* The Alliant needs the added underscore. */ 1011 asm (".globl __builtin_saveregs"); 1012 asm ("__builtin_saveregs:"); 1013 asm (".globl ___builtin_saveregs"); 1014 asm ("___builtin_saveregs:"); 1015 1016 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */ 1017 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save 1018 area and also for a new va_list 1019 structure */ 1020 /* Save all argument registers in the arg reg save area. The 1021 arg reg save area must have the following layout (according 1022 to the svr4 ABI): 1023 1024 struct { 1025 union { 1026 float freg[8]; 1027 double dreg[4]; 1028 } float_regs; 1029 long ireg[12]; 1030 }; 1031 */ 1032 1033 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */ 1034 asm (" fst.q %f12,16(%sp)"); 1035 1036 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */ 1037 asm (" st.l %r17,36(%sp)"); 1038 asm (" st.l %r18,40(%sp)"); 1039 asm (" st.l %r19,44(%sp)"); 1040 asm (" st.l %r20,48(%sp)"); 1041 asm (" st.l %r21,52(%sp)"); 1042 asm (" st.l %r22,56(%sp)"); 1043 asm (" st.l %r23,60(%sp)"); 1044 asm (" st.l %r24,64(%sp)"); 1045 asm (" st.l %r25,68(%sp)"); 1046 asm (" st.l %r26,72(%sp)"); 1047 asm (" st.l %r27,76(%sp)"); 1048 1049 asm (" adds 80,%sp,%r16"); /* compute the address of the new 1050 va_list structure. Put in into 1051 r16 so that it will be returned 1052 to the caller. */ 1053 1054 /* Initialize all fields of the new va_list structure. This 1055 structure looks like: 1056 1057 typedef struct { 1058 unsigned long ireg_used; 1059 unsigned long freg_used; 1060 long *reg_base; 1061 long *mem_ptr; 1062 } va_list; 1063 */ 1064 1065 asm (" st.l %r0, 0(%r16)"); /* nfixed */ 1066 asm (" st.l %r0, 4(%r16)"); /* nfloating */ 1067 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */ 1068 asm (" bri %r1"); /* delayed return */ 1069 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */ 1070 1071 #else /* not __SVR4__ */ 1072 asm (" .text"); 1073 asm (" .align 4"); 1074 1075 asm (".globl ___builtin_saveregs"); 1076 asm ("___builtin_saveregs:"); 1077 asm (" mov sp,r30"); 1078 asm (" andnot 0x0f,sp,sp"); 1079 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */ 1080 1081 /* Fill in the __va_struct. */ 1082 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */ 1083 asm (" st.l r17, 4(sp)"); /* int fixed[12] */ 1084 asm (" st.l r18, 8(sp)"); 1085 asm (" st.l r19,12(sp)"); 1086 asm (" st.l r20,16(sp)"); 1087 asm (" st.l r21,20(sp)"); 1088 asm (" st.l r22,24(sp)"); 1089 asm (" st.l r23,28(sp)"); 1090 asm (" st.l r24,32(sp)"); 1091 asm (" st.l r25,36(sp)"); 1092 asm (" st.l r26,40(sp)"); 1093 asm (" st.l r27,44(sp)"); 1094 1095 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */ 1096 asm (" fst.q f12,64(sp)"); /* int floating[8] */ 1097 1098 /* Fill in the __va_ctl. */ 1099 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */ 1100 asm (" st.l r28,84(sp)"); /* pointer to more args */ 1101 asm (" st.l r0, 88(sp)"); /* nfixed */ 1102 asm (" st.l r0, 92(sp)"); /* nfloating */ 1103 1104 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */ 1105 asm (" bri r1"); 1106 asm (" mov r30,sp"); 1107 /* recover stack and pass address to start 1108 of data. */ 1109 #endif /* not __SVR4__ */ 1110 #else /* not __i860__ */ 1111 #ifdef __sparc__ 1112 asm (".global __builtin_saveregs"); 1113 asm ("__builtin_saveregs:"); 1114 asm (".global ___builtin_saveregs"); 1115 asm ("___builtin_saveregs:"); 1116 #ifdef NEED_PROC_COMMAND 1117 asm (".proc 020"); 1118 #endif 1119 asm ("st %i0,[%fp+68]"); 1120 asm ("st %i1,[%fp+72]"); 1121 asm ("st %i2,[%fp+76]"); 1122 asm ("st %i3,[%fp+80]"); 1123 asm ("st %i4,[%fp+84]"); 1124 asm ("retl"); 1125 asm ("st %i5,[%fp+88]"); 1126 #ifdef NEED_TYPE_COMMAND 1127 asm (".type __builtin_saveregs,#function"); 1128 asm (".size __builtin_saveregs,.-__builtin_saveregs"); 1129 #endif 1130 #else /* not __sparc__ */ 1131 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__) 1132 1133 asm (" .text"); 1134 asm (" .ent __builtin_saveregs"); 1135 asm (" .globl __builtin_saveregs"); 1136 asm ("__builtin_saveregs:"); 1137 asm (" sw $4,0($30)"); 1138 asm (" sw $5,4($30)"); 1139 asm (" sw $6,8($30)"); 1140 asm (" sw $7,12($30)"); 1141 asm (" j $31"); 1142 asm (" .end __builtin_saveregs"); 1143 #else /* not __mips__, etc. */ 1144 __builtin_saveregs () 1145 { 1146 abort (); 1147 } 1148 #endif /* not __mips__ */ 1149 #endif /* not __sparc__ */ 1150 #endif /* not __i860__ */ 1151 #endif 1152 1153 #ifdef L_eprintf 1154 #ifndef inhibit_eprintf 1155 1156 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1157 #include <stdio.h> 1158 /* This is used by the `assert' macro. */ 1159 void 1160 __eprintf (string, expression, line, filename) 1161 const char *string; 1162 const char *expression; 1163 int line; 1164 const char *filename; 1165 { 1166 fprintf (stderr, string, expression, line, filename); 1167 fflush (stderr); 1168 abort (); 1169 } 1170 1171 #endif 1172 #endif 1173 1174 #ifdef L_bb 1175 /* Avoid warning from ranlib about empty object file. */ 1176 void 1177 __bb_avoid_warning () 1178 {} 1179 1180 #if defined (__sun__) && defined (__mc68000__) 1181 struct bb 1182 { 1183 int initialized; 1184 char *filename; 1185 int *counts; 1186 int ncounts; 1187 int zero_word; 1188 int *addresses; 1189 }; 1190 1191 extern int ___tcov_init; 1192 1193 __bb_init_func (blocks) 1194 struct bb *blocks; 1195 { 1196 if (! ___tcov_init) 1197 ___tcov_init_func (); 1198 1199 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts); 1200 } 1201 1202 #endif 1203 #endif 1204 1205 /* frills for C++ */ 1206 1207 #ifdef L_builtin_new 1208 1209 #include <sys/types.h> 1210 1211 typedef void (*vfp)(void); 1212 1213 extern vfp __new_handler; 1214 1215 void * 1216 __builtin_new (sz) 1217 size_t sz; 1218 { 1219 void *p; 1220 1221 /* malloc (0) is unpredictable; avoid it. */ 1222 if (sz == 0) 1223 sz = 1; 1224 p = (void *) malloc (sz); 1225 if (p == 0) 1226 (*__new_handler) (); 1227 return p; 1228 } 1229 #endif 1230 1231 #ifdef L_caps_New 1232 1233 /* This gets us __GNU_LIBRARY__. */ 1234 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1235 #include <stdio.h> 1236 #include <sys/types.h> 1237 1238 #ifdef __GNU_LIBRARY__ 1239 /* Avoid forcing the library's meaning of `write' on the user program 1240 by using the "internal" name (for use within the library) */ 1241 #define write(fd, buf, n) __write((fd), (buf), (n)) 1242 #endif 1243 1244 typedef void (*vfp)(void); 1245 1246 extern void *__builtin_new (size_t); 1247 static void default_new_handler (void); 1248 1249 vfp __new_handler = default_new_handler; 1250 1251 1252 void * 1253 __builtin_vec_new (p, maxindex, size, ctor) 1254 void *p; 1255 size_t maxindex; 1256 size_t size; 1257 void (*ctor)(void *); 1258 { 1259 size_t i; 1260 size_t nelts = maxindex + 1; 1261 void *rval; 1262 1263 if (p == 0) 1264 p = __builtin_new (nelts * size); 1265 1266 rval = p; 1267 1268 for (i = 0; i < nelts; i++) 1269 { 1270 (*ctor) (p); 1271 p += size; 1272 } 1273 1274 return rval; 1275 } 1276 1277 vfp 1278 __set_new_handler (handler) 1279 vfp handler; 1280 { 1281 vfp prev_handler; 1282 1283 prev_handler = __new_handler; 1284 if (handler == 0) handler = default_new_handler; 1285 __new_handler = handler; 1286 return prev_handler; 1287 } 1288 1289 vfp 1290 set_new_handler (handler) 1291 vfp handler; 1292 { 1293 return __set_new_handler (handler); 1294 } 1295 1296 #define MESSAGE "Virtual memory exceeded in `new'\n" 1297 1298 static void 1299 default_new_handler () 1300 { 1301 /* don't use fprintf (stderr, ...) because it may need to call malloc. */ 1302 /* This should really print the name of the program, but that is hard to 1303 do. We need a standard, clean way to get at the name. */ 1304 write (2, MESSAGE, sizeof (MESSAGE)); 1305 /* don't call exit () because that may call global destructors which 1306 may cause a loop. */ 1307 _exit (-1); 1308 } 1309 #endif 1310 1311 #ifdef L_builtin_del 1312 1313 #include <sys/types.h> 1314 1315 typedef void (*vfp)(void); 1316 1317 void 1318 __builtin_delete (ptr) 1319 void *ptr; 1320 { 1321 if (ptr) 1322 free (ptr); 1323 } 1324 1325 void 1326 __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete) 1327 void *ptr; 1328 size_t maxindex; 1329 size_t size; 1330 void (*dtor)(void *, int); 1331 int auto_delete; 1332 { 1333 size_t i; 1334 size_t nelts = maxindex + 1; 1335 void *p = ptr; 1336 1337 ptr += nelts * size; 1338 1339 for (i = 0; i < nelts; i++) 1340 { 1341 ptr -= size; 1342 (*dtor) (ptr, auto_delete); 1343 } 1344 1345 if (auto_delete_vec) 1346 __builtin_delete (p); 1347 } 1348 1349 #endif 1350 1351 #ifdef L_shtab 1352 unsigned int __shtab[] = { 1353 0x00000001, 0x00000002, 0x00000004, 0x00000008, 1354 0x00000010, 0x00000020, 0x00000040, 0x00000080, 1355 0x00000100, 0x00000200, 0x00000400, 0x00000800, 1356 0x00001000, 0x00002000, 0x00004000, 0x00008000, 1357 0x00010000, 0x00020000, 0x00040000, 0x00080000, 1358 0x00100000, 0x00200000, 0x00400000, 0x00800000, 1359 0x01000000, 0x02000000, 0x04000000, 0x08000000, 1360 0x10000000, 0x20000000, 0x40000000, 0x80000000 1361 }; 1362 #endif 1363 1364 #ifdef L_clear_cache 1365 /* Clear part of an instruction cache. */ 1366 1367 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH) 1368 1369 void 1370 __clear_cache (beg, end) 1371 char *beg, *end; 1372 { 1373 #ifdef INSN_CACHE_SIZE 1374 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH]; 1375 static int initialized = 0; 1376 int offset; 1377 void *start_addr 1378 void *end_addr; 1379 typedef (*function_ptr) (); 1380 1381 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16 1382 /* It's cheaper to clear the whole cache. 1383 Put in a series of jump instructions so that calling the beginning 1384 of the cache will clear the whole thing. */ 1385 1386 if (! initialized) 1387 { 1388 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1389 & -INSN_CACHE_LINE_WIDTH); 1390 int end_ptr = ptr + INSN_CACHE_SIZE; 1391 1392 while (ptr < end_ptr) 1393 { 1394 *(INSTRUCTION_TYPE *)ptr 1395 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH; 1396 ptr += INSN_CACHE_LINE_WIDTH; 1397 } 1398 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION; 1399 1400 initialized = 1; 1401 } 1402 1403 /* Call the beginning of the sequence. */ 1404 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1405 & -INSN_CACHE_LINE_WIDTH)) 1406 ()); 1407 1408 #else /* Cache is large. */ 1409 1410 if (! initialized) 1411 { 1412 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1413 & -INSN_CACHE_LINE_WIDTH); 1414 1415 while (ptr < (int) array + sizeof array) 1416 { 1417 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION; 1418 ptr += INSN_CACHE_LINE_WIDTH; 1419 } 1420 1421 initialized = 1; 1422 } 1423 1424 /* Find the location in array that occupies the same cache line as BEG. */ 1425 1426 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1); 1427 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1) 1428 & -INSN_CACHE_PLANE_SIZE) 1429 + offset); 1430 1431 /* Compute the cache alignment of the place to stop clearing. */ 1432 #if 0 /* This is not needed for gcc's purposes. */ 1433 /* If the block to clear is bigger than a cache plane, 1434 we clear the entire cache, and OFFSET is already correct. */ 1435 if (end < beg + INSN_CACHE_PLANE_SIZE) 1436 #endif 1437 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1) 1438 & -INSN_CACHE_LINE_WIDTH) 1439 & (INSN_CACHE_PLANE_SIZE - 1)); 1440 1441 #if INSN_CACHE_DEPTH > 1 1442 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset; 1443 if (end_addr <= start_addr) 1444 end_addr += INSN_CACHE_PLANE_SIZE; 1445 1446 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++) 1447 { 1448 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE; 1449 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE; 1450 1451 while (addr != stop) 1452 { 1453 /* Call the return instruction at ADDR. */ 1454 ((function_ptr) addr) (); 1455 1456 addr += INSN_CACHE_LINE_WIDTH; 1457 } 1458 } 1459 #else /* just one plane */ 1460 do 1461 { 1462 /* Call the return instruction at START_ADDR. */ 1463 ((function_ptr) start_addr) (); 1464 1465 start_addr += INSN_CACHE_LINE_WIDTH; 1466 } 1467 while ((start_addr % INSN_CACHE_SIZE) != offset); 1468 #endif /* just one plane */ 1469 #endif /* Cache is large */ 1470 #endif /* Cache exists */ 1471 } 1472 1473 #endif /* L_clear_cache */ 1474 1475 #ifdef L_trampoline 1476 1477 /* Jump to a trampoline, loading the static chain address. */ 1478 1479 #ifdef TRANSFER_FROM_TRAMPOLINE 1480 TRANSFER_FROM_TRAMPOLINE 1481 #endif 1482 1483 #ifdef __convex__ 1484 1485 /* Make stack executable so we can call trampolines on stack. 1486 This is called from INITIALIZE_TRAMPOLINE in convex.h. */ 1487 1488 #include <sys/mman.h> 1489 #include <sys/vmparam.h> 1490 #include <machine/machparam.h> 1491 1492 void 1493 __enable_execute_stack () 1494 { 1495 int fp; 1496 static unsigned lowest = USRSTACK; 1497 unsigned current = (unsigned) &fp & -NBPG; 1498 1499 if (lowest > current) 1500 { 1501 unsigned len = lowest - current; 1502 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); 1503 lowest = current; 1504 } 1505 1506 /* Clear instruction cache in case an old trampoline is in it. */ 1507 asm ("pich"); 1508 } 1509 #endif /* __convex__ */ 1510 1511 #ifdef __pyr__ 1512 1513 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1514 #include <stdio.h> 1515 #include <sys/mman.h> 1516 #include <sys/types.h> 1517 #include <sys/param.h> 1518 #include <sys/vmmac.h> 1519 1520 /* Modified from the convex -code above. 1521 mremap promises to clear the i-cache. */ 1522 1523 void 1524 __enable_execute_stack () 1525 { 1526 int fp; 1527 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ, 1528 PROT_READ|PROT_WRITE|PROT_EXEC)) 1529 { 1530 perror ("mprotect in __enable_execute_stack"); 1531 fflush (stderr); 1532 abort (); 1533 } 1534 } 1535 #endif /* __pyr__ */ 1536 #endif /* L_trampoline */ 1537 1538 #ifdef L__main 1539 1540 #include "gbl-ctors.h" 1541 1542 /* Run all the global destructors on exit from the program. */ 1543 1544 void 1545 __do_global_dtors () 1546 { 1547 #ifdef DO_GLOBAL_DTORS_BODY 1548 DO_GLOBAL_DTORS_BODY; 1549 #else 1550 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0]; 1551 unsigned i; 1552 1553 /* Some systems place the number of pointers 1554 in the first word of the table. 1555 On other systems, that word is -1. 1556 In all cases, the table is null-terminated. */ 1557 1558 /* If the length is not recorded, count up to the null. */ 1559 if (nptrs == -1) 1560 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++); 1561 1562 /* GNU LD format. */ 1563 for (i = nptrs; i >= 1; i--) 1564 __DTOR_LIST__[i] (); 1565 #endif 1566 } 1567 1568 #ifndef INIT_SECTION_ASM_OP 1569 /* Run all the global constructors on entry to the program. */ 1570 1571 #ifndef ON_EXIT 1572 #define ON_EXIT(a, b) 1573 #else 1574 /* Make sure the exit routine is pulled in to define the globals as 1575 bss symbols, just in case the linker does not automatically pull 1576 bss definitions from the library. */ 1577 1578 extern int _exit_dummy_decl; 1579 int *_exit_dummy_ref = &_exit_dummy_decl; 1580 #endif /* ON_EXIT */ 1581 1582 void 1583 __do_global_ctors () 1584 { 1585 DO_GLOBAL_CTORS_BODY; 1586 ON_EXIT (__do_global_dtors, 0); 1587 } 1588 #endif /* no INIT_SECTION_ASM_OP */ 1589 1590 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main) 1591 /* Subroutine called automatically by `main'. 1592 Compiling a global function named `main' 1593 produces an automatic call to this function at the beginning. 1594 1595 For many systems, this routine calls __do_global_ctors. 1596 For systems which support a .init section we use the .init section 1597 to run __do_global_ctors, so we need not do anything here. */ 1598 1599 void 1600 __main () 1601 { 1602 /* Support recursive calls to `main': run initializers just once. */ 1603 static int initialized = 0; 1604 if (! initialized) 1605 { 1606 initialized = 1; 1607 __do_global_ctors (); 1608 } 1609 } 1610 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */ 1611 1612 #endif /* L__main */ 1613 1614 #ifdef L_ctors 1615 1616 #include "gbl-ctors.h" 1617 1618 /* Provide default definitions for the lists of constructors and 1619 destructors, so that we don't get linker errors. These symbols are 1620 intentionally bss symbols, so that gld and/or collect will provide 1621 the right values. */ 1622 1623 /* We declare the lists here with two elements each, 1624 so that they are valid empty lists if no other definition is loaded. */ 1625 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 1626 #ifdef __NeXT__ 1627 /* After 2.3, try this definition on all systems. */ 1628 func_ptr __CTOR_LIST__[2] = {0, 0}; 1629 func_ptr __DTOR_LIST__[2] = {0, 0}; 1630 #else 1631 func_ptr __CTOR_LIST__[2]; 1632 func_ptr __DTOR_LIST__[2]; 1633 #endif 1634 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 1635 #endif /* L_ctors */ 1636 1637 #ifdef L_exit 1638 1639 #include "gbl-ctors.h" 1640 1641 #ifndef ON_EXIT 1642 1643 /* If we have no known way of registering our own __do_global_dtors 1644 routine so that it will be invoked at program exit time, then we 1645 have to define our own exit routine which will get this to happen. */ 1646 1647 extern void __do_global_dtors (); 1648 extern void _cleanup (); 1649 extern volatile void _exit (); 1650 1651 void 1652 exit (status) 1653 int status; 1654 { 1655 __do_global_dtors (); 1656 #ifdef EXIT_BODY 1657 EXIT_BODY; 1658 #else 1659 _cleanup (); 1660 #endif 1661 _exit (status); 1662 } 1663 1664 #else 1665 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ 1666 #endif 1667 1668 #endif /* L_exit */ 1669 1670 /* In a.out systems, we need to have these dummy constructor and destructor 1671 lists in the library. 1672 1673 When using `collect', the first link will resolve __CTOR_LIST__ 1674 and __DTOR_LIST__ to these symbols. We will then run "nm" on the 1675 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink. 1676 Since we don't do the second link if no constructors existed, these 1677 dummies must be fully functional empty lists. 1678 1679 When using `gnu ld', these symbols will be used if there are no 1680 constructors. If there are constructors, the N_SETV symbol defined 1681 by the linker from the N_SETT's in input files will define __CTOR_LIST__ 1682 and __DTOR_LIST__ rather than its being allocated as common storage 1683 by the definitions below. 1684 1685 When using a linker that supports constructor and destructor segments, 1686 these definitions will not be used, since crtbegin.o and crtend.o 1687 (from crtstuff.c) will have already defined __CTOR_LIST__ and 1688 __DTOR_LIST__. The crt*.o files are passed directly to the linker 1689 on its command line, by gcc. */ 1690 1691 /* The list needs two elements: one is ignored (the old count); the 1692 second is the terminating zero. Since both values are zero, this 1693 declaration is not initialized, and it becomes `common'. */ 1694 1695 #ifdef L_ctor_list 1696 #include "gbl-ctors.h" 1697 func_ptr __CTOR_LIST__[2]; 1698 #endif 1699 1700 #ifdef L_dtor_list 1701 #include "gbl-ctors.h" 1702 func_ptr __DTOR_LIST__[2]; 1703 #endif 1704