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