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