]> gcc.gnu.org Git - gcc.git/blob - gcc/libgcc2.c
(__builtin_new): Cast the result of malloc.
[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 "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 \f
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 \f
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 \f
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 \f
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 += 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 \f
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 \f
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 \f
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 \f
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_varargs
980 #ifdef __i860__
981 #if defined(__svr4__) || defined(__alliant__)
982 asm (" .text");
983 asm (" .align 4");
984
985 /* The Alliant needs the added underscore. */
986 asm (".globl __builtin_saveregs");
987 asm ("__builtin_saveregs:");
988 asm (".globl ___builtin_saveregs");
989 asm ("___builtin_saveregs:");
990
991 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
992 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
993 area and also for a new va_list
994 structure */
995 /* Save all argument registers in the arg reg save area. The
996 arg reg save area must have the following layout (according
997 to the svr4 ABI):
998
999 struct {
1000 union {
1001 float freg[8];
1002 double dreg[4];
1003 } float_regs;
1004 long ireg[12];
1005 };
1006 */
1007
1008 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1009 asm (" fst.q %f12,16(%sp)");
1010
1011 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1012 asm (" st.l %r17,36(%sp)");
1013 asm (" st.l %r18,40(%sp)");
1014 asm (" st.l %r19,44(%sp)");
1015 asm (" st.l %r20,48(%sp)");
1016 asm (" st.l %r21,52(%sp)");
1017 asm (" st.l %r22,56(%sp)");
1018 asm (" st.l %r23,60(%sp)");
1019 asm (" st.l %r24,64(%sp)");
1020 asm (" st.l %r25,68(%sp)");
1021 asm (" st.l %r26,72(%sp)");
1022 asm (" st.l %r27,76(%sp)");
1023
1024 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1025 va_list structure. Put in into
1026 r16 so that it will be returned
1027 to the caller. */
1028
1029 /* Initialize all fields of the new va_list structure. This
1030 structure looks like:
1031
1032 typedef struct {
1033 unsigned long ireg_used;
1034 unsigned long freg_used;
1035 long *reg_base;
1036 long *mem_ptr;
1037 } va_list;
1038 */
1039
1040 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1041 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1042 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1043 asm (" bri %r1"); /* delayed return */
1044 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1045
1046 #else /* not __SVR4__ */
1047 asm (" .text");
1048 asm (" .align 4");
1049
1050 asm (".globl ___builtin_saveregs");
1051 asm ("___builtin_saveregs:");
1052 asm (" mov sp,r30");
1053 asm (" andnot 0x0f,sp,sp");
1054 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1055
1056 /* Fill in the __va_struct. */
1057 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1058 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1059 asm (" st.l r18, 8(sp)");
1060 asm (" st.l r19,12(sp)");
1061 asm (" st.l r20,16(sp)");
1062 asm (" st.l r21,20(sp)");
1063 asm (" st.l r22,24(sp)");
1064 asm (" st.l r23,28(sp)");
1065 asm (" st.l r24,32(sp)");
1066 asm (" st.l r25,36(sp)");
1067 asm (" st.l r26,40(sp)");
1068 asm (" st.l r27,44(sp)");
1069
1070 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1071 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1072
1073 /* Fill in the __va_ctl. */
1074 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1075 asm (" st.l r28,84(sp)"); /* pointer to more args */
1076 asm (" st.l r0, 88(sp)"); /* nfixed */
1077 asm (" st.l r0, 92(sp)"); /* nfloating */
1078
1079 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1080 asm (" bri r1");
1081 asm (" mov r30,sp");
1082 /* recover stack and pass address to start
1083 of data. */
1084 #endif /* not __SVR4__ */
1085 #else /* not __i860__ */
1086 #ifdef __sparc__
1087 asm (".global __builtin_saveregs");
1088 asm ("__builtin_saveregs:");
1089 asm (".global ___builtin_saveregs");
1090 asm ("___builtin_saveregs:");
1091 #ifdef NEED_PROC_COMMAND
1092 asm (".proc 020");
1093 #endif
1094 asm ("st %i0,[%fp+68]");
1095 asm ("st %i1,[%fp+72]");
1096 asm ("st %i2,[%fp+76]");
1097 asm ("st %i3,[%fp+80]");
1098 asm ("st %i4,[%fp+84]");
1099 asm ("retl");
1100 asm ("st %i5,[%fp+88]");
1101 #ifdef NEED_TYPE_COMMAND
1102 asm (".type __builtin_saveregs,#function");
1103 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1104 #endif
1105 #else /* not __sparc__ */
1106 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1107
1108 asm (" .text");
1109 asm (" .ent __builtin_saveregs");
1110 asm (" .globl __builtin_saveregs");
1111 asm ("__builtin_saveregs:");
1112 asm (" sw $4,0($30)");
1113 asm (" sw $5,4($30)");
1114 asm (" sw $6,8($30)");
1115 asm (" sw $7,12($30)");
1116 asm (" j $31");
1117 asm (" .end __builtin_saveregs");
1118 #else /* not __mips__, etc. */
1119 __builtin_saveregs ()
1120 {
1121 abort ();
1122 }
1123 #endif /* not __mips__ */
1124 #endif /* not __sparc__ */
1125 #endif /* not __i860__ */
1126 #endif
1127 \f
1128 #ifdef L_eprintf
1129 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1130 #include <stdio.h>
1131 /* This is used by the `assert' macro. */
1132 void
1133 __eprintf (string, expression, line, filename)
1134 const char *string;
1135 const char *expression;
1136 int line;
1137 const char *filename;
1138 {
1139 fprintf (stderr, string, expression, line, filename);
1140 fflush (stderr);
1141 abort ();
1142 }
1143 #endif
1144
1145 #ifdef L_bb
1146 /* Avoid warning from ranlib about empty object file. */
1147 void
1148 __bb_avoid_warning ()
1149 {}
1150
1151 #if defined (__sun__) && defined (__mc68000__)
1152 struct bb
1153 {
1154 int initialized;
1155 char *filename;
1156 int *counts;
1157 int ncounts;
1158 int zero_word;
1159 int *addresses;
1160 };
1161
1162 extern int ___tcov_init;
1163
1164 __bb_init_func (blocks)
1165 struct bb *blocks;
1166 {
1167 if (! ___tcov_init)
1168 ___tcov_init_func ();
1169
1170 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1171 }
1172
1173 #endif
1174 #endif
1175 \f
1176 /* frills for C++ */
1177
1178 #ifdef L_builtin_new
1179 typedef void (*vfp)(void);
1180
1181 extern vfp __new_handler;
1182
1183 void *
1184 __builtin_new (sz)
1185 size_t sz;
1186 {
1187 void *p;
1188
1189 p = (void *) 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 HOST_WIDE_INT) __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.108415 seconds and 6 git commands to generate.