OSDN Git Service

(__unwind_function): Provide a default definition for implementations
[pf3gnuchains/gcc-fork.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, 1993, 1994, 1995 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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 /* It is incorrect to include config.h here, because this file is being
30    compiled for the target, and hence definitions concerning only the host
31    do not apply.  */
32
33 #include "tconfig.h"
34 #include "machmode.h"
35 #include "defaults.h" 
36 #ifndef L_trampoline
37 #include <stddef.h>
38 #endif
39
40 /* Don't use `fancy_abort' here even if config.h says to use it.  */
41 #ifdef abort
42 #undef abort
43 #endif
44
45 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
46 #define WEAK_ALIAS
47 #endif
48
49 /* Permit the tm.h file to select the endianness to use just for this
50    file.  This is used when the endianness is determined when the
51    compiler is run.  */
52
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
55 #endif
56
57 /* In the first part of this file, we are interfacing to calls generated
58    by the compiler itself.  These calls pass values into these routines
59    which have very specific modes (rather than very specific types), and
60    these compiler-generated calls also expect any return values to have
61    very specific modes (rather than very specific types).  Thus, we need
62    to avoid using regular C language type names in this part of the file
63    because the sizes for those types can be configured to be anything.
64    Instead we use the following special type names.  */
65
66 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
67 typedef          int SItype     __attribute__ ((mode (SI)));
68 typedef unsigned int USItype    __attribute__ ((mode (SI)));
69 typedef          int DItype     __attribute__ ((mode (DI)));
70 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
71
72 typedef         float SFtype    __attribute__ ((mode (SF)));
73 typedef         float DFtype    __attribute__ ((mode (DF)));
74
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef         float XFtype    __attribute__ ((mode (XF)));
77 #endif
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef         float TFtype    __attribute__ ((mode (TF)));
80 #endif
81
82 typedef int word_type __attribute__ ((mode (__word__)));
83
84 /* Make sure that we don't accidentally use any normal C language built-in
85    type names in the first part of this file.  Instead we want to use *only*
86    the type names defined above.  The following macro definitions insure
87    that if we *do* accidentally use some normal C language built-in type name,
88    we will get a syntax error.  */
89
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
97
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
99
100 /* DIstructs are pairs of SItype values in the order determined by
101    LIBGCC2_WORDS_BIG_ENDIAN.  */
102
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104   struct DIstruct {SItype high, low;};
105 #else
106   struct DIstruct {SItype low, high;};
107 #endif
108
109 /* We need this union to unpack/pack DImode values, since we don't have
110    any arithmetic yet.  Incoming DImode parameters are stored into the
111    `ll' field, and the unpacked result is read from the struct `s'.  */
112
113 typedef union
114 {
115   struct DIstruct s;
116   DItype ll;
117 } DIunion;
118
119 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120      || defined (L_divdi3) || defined (L_udivdi3) \
121      || defined (L_moddi3) || defined (L_umoddi3))
122
123 #include "longlong.h"
124
125 #endif /* udiv or mul */
126
127 extern DItype __fixunssfdi (SFtype a);
128 extern DItype __fixunsdfdi (DFtype a);
129 #if LONG_DOUBLE_TYPE_SIZE == 96
130 extern DItype __fixunsxfdi (XFtype a);
131 #endif
132 #if LONG_DOUBLE_TYPE_SIZE == 128
133 extern DItype __fixunstfdi (TFtype a);
134 #endif
135 \f
136 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137 #if defined (L_divdi3) || defined (L_moddi3)
138 static inline
139 #endif
140 DItype
141 __negdi2 (u)
142      DItype u;
143 {
144   DIunion w;
145   DIunion uu;
146
147   uu.ll = u;
148
149   w.s.low = -uu.s.low;
150   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
151
152   return w.ll;
153 }
154 #endif
155 \f
156 #ifdef L_lshrdi3
157 DItype
158 __lshrdi3 (u, b)
159      DItype u;
160      word_type b;
161 {
162   DIunion w;
163   word_type 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      word_type b;
193 {
194   DIunion w;
195   word_type 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      word_type b;
225 {
226   DIunion w;
227   word_type 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_ffsdi2
254 DItype
255 __ffsdi2 (u)
256      DItype u;
257 {
258   DIunion uu, w;
259   uu.ll = u;
260   w.s.high = 0;
261   w.s.low = ffs (uu.s.low);
262   if (w.s.low != 0)
263     return w.ll;
264   w.s.low = ffs (uu.s.high);
265   if (w.s.low != 0)
266     {
267       w.s.low += BITS_PER_UNIT * sizeof (SItype);
268       return w.ll;
269     }
270   return w.ll;
271 }
272 #endif
273 \f
274 #ifdef L_muldi3
275 DItype
276 __muldi3 (u, v)
277      DItype u, v;
278 {
279   DIunion w;
280   DIunion uu, vv;
281
282   uu.ll = u,
283   vv.ll = v;
284
285   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
286   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
287                + (USItype) uu.s.high * (USItype) vv.s.low);
288
289   return w.ll;
290 }
291 #endif
292 \f
293 #ifdef L_udiv_w_sdiv
294 #if defined (sdiv_qrnnd)
295 USItype
296 __udiv_w_sdiv (rp, a1, a0, d)
297      USItype *rp, a1, a0, d;
298 {
299   USItype q, r;
300   USItype c0, c1, b1;
301
302   if ((SItype) d >= 0)
303     {
304       if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
305         {
306           /* dividend, divisor, and quotient are nonnegative */
307           sdiv_qrnnd (q, r, a1, a0, d);
308         }
309       else
310         {
311           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
313           /* Divide (c1*2^32 + c0) by d */
314           sdiv_qrnnd (q, r, c1, c0, d);
315           /* Add 2^31 to quotient */
316           q += (USItype) 1 << (SI_TYPE_SIZE - 1);
317         }
318     }
319   else
320     {
321       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
322       c1 = a1 >> 1;                     /* A/2 */
323       c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
324
325       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
326         {
327           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
328
329           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
330           if ((d & 1) != 0)
331             {
332               if (r >= q)
333                 r = r - q;
334               else if (q - r <= d)
335                 {
336                   r = r - q + d;
337                   q--;
338                 }
339               else
340                 {
341                   r = r - q + 2*d;
342                   q -= 2;
343                 }
344             }
345         }
346       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
347         {
348           c1 = (b1 - 1) - c1;
349           c0 = ~c0;                     /* logical NOT */
350
351           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
352
353           q = ~q;                       /* (A/2)/b1 */
354           r = (b1 - 1) - r;
355
356           r = 2*r + (a0 & 1);           /* A/(2*b1) */
357
358           if ((d & 1) != 0)
359             {
360               if (r >= q)
361                 r = r - q;
362               else if (q - r <= d)
363                 {
364                   r = r - q + d;
365                   q--;
366                 }
367               else
368                 {
369                   r = r - q + 2*d;
370                   q -= 2;
371                 }
372             }
373         }
374       else                              /* Implies c1 = b1 */
375         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
376           if (a0 >= -d)
377             {
378               q = -1;
379               r = a0 + d;
380             }
381           else
382             {
383               q = -2;
384               r = a0 + 2*d;
385             }
386         }
387     }
388
389   *rp = r;
390   return q;
391 }
392 #else
393 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
394 USItype
395 __udiv_w_sdiv (rp, a1, a0, d)
396      USItype *rp, a1, a0, d;
397 {}
398 #endif
399 #endif
400 \f
401 #if (defined (L_udivdi3) || defined (L_divdi3) || \
402      defined (L_umoddi3) || defined (L_moddi3))
403 #define L_udivmoddi4
404 #endif
405
406 #ifdef L_udivmoddi4
407 static const UQItype __clz_tab[] =
408 {
409   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,
410   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,
411   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,
412   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,
413   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,
414   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,
415   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,
416   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,
417 };
418
419 #if (defined (L_udivdi3) || defined (L_divdi3) || \
420      defined (L_umoddi3) || defined (L_moddi3))
421 static inline
422 #endif
423 UDItype
424 __udivmoddi4 (n, d, rp)
425      UDItype n, d;
426      UDItype *rp;
427 {
428   DIunion ww;
429   DIunion nn, dd;
430   DIunion rr;
431   USItype d0, d1, n0, n1, n2;
432   USItype q0, q1;
433   USItype b, bm;
434
435   nn.ll = n;
436   dd.ll = d;
437
438   d0 = dd.s.low;
439   d1 = dd.s.high;
440   n0 = nn.s.low;
441   n1 = nn.s.high;
442
443 #if !UDIV_NEEDS_NORMALIZATION
444   if (d1 == 0)
445     {
446       if (d0 > n1)
447         {
448           /* 0q = nn / 0D */
449
450           udiv_qrnnd (q0, n0, n1, n0, d0);
451           q1 = 0;
452
453           /* Remainder in n0.  */
454         }
455       else
456         {
457           /* qq = NN / 0d */
458
459           if (d0 == 0)
460             d0 = 1 / d0;        /* Divide intentionally by zero.  */
461
462           udiv_qrnnd (q1, n1, 0, n1, d0);
463           udiv_qrnnd (q0, n0, n1, n0, d0);
464
465           /* Remainder in n0.  */
466         }
467
468       if (rp != 0)
469         {
470           rr.s.low = n0;
471           rr.s.high = 0;
472           *rp = rr.ll;
473         }
474     }
475
476 #else /* UDIV_NEEDS_NORMALIZATION */
477
478   if (d1 == 0)
479     {
480       if (d0 > n1)
481         {
482           /* 0q = nn / 0D */
483
484           count_leading_zeros (bm, d0);
485
486           if (bm != 0)
487             {
488               /* Normalize, i.e. make the most significant bit of the
489                  denominator set.  */
490
491               d0 = d0 << bm;
492               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
493               n0 = n0 << bm;
494             }
495
496           udiv_qrnnd (q0, n0, n1, n0, d0);
497           q1 = 0;
498
499           /* Remainder in n0 >> bm.  */
500         }
501       else
502         {
503           /* qq = NN / 0d */
504
505           if (d0 == 0)
506             d0 = 1 / d0;        /* Divide intentionally by zero.  */
507
508           count_leading_zeros (bm, d0);
509
510           if (bm == 0)
511             {
512               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513                  conclude (the most significant bit of n1 is set) /\ (the
514                  leading quotient digit q1 = 1).
515
516                  This special case is necessary, not an optimization.
517                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
518
519               n1 -= d0;
520               q1 = 1;
521             }
522           else
523             {
524               /* Normalize.  */
525
526               b = SI_TYPE_SIZE - bm;
527
528               d0 = d0 << bm;
529               n2 = n1 >> b;
530               n1 = (n1 << bm) | (n0 >> b);
531               n0 = n0 << bm;
532
533               udiv_qrnnd (q1, n1, n2, n1, d0);
534             }
535
536           /* n1 != d0... */
537
538           udiv_qrnnd (q0, n0, n1, n0, d0);
539
540           /* Remainder in n0 >> bm.  */
541         }
542
543       if (rp != 0)
544         {
545           rr.s.low = n0 >> bm;
546           rr.s.high = 0;
547           *rp = rr.ll;
548         }
549     }
550 #endif /* UDIV_NEEDS_NORMALIZATION */
551
552   else
553     {
554       if (d1 > n1)
555         {
556           /* 00 = nn / DD */
557
558           q0 = 0;
559           q1 = 0;
560
561           /* Remainder in n1n0.  */
562           if (rp != 0)
563             {
564               rr.s.low = n0;
565               rr.s.high = n1;
566               *rp = rr.ll;
567             }
568         }
569       else
570         {
571           /* 0q = NN / dd */
572
573           count_leading_zeros (bm, d1);
574           if (bm == 0)
575             {
576               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577                  conclude (the most significant bit of n1 is set) /\ (the
578                  quotient digit q0 = 0 or 1).
579
580                  This special case is necessary, not an optimization.  */
581
582               /* The condition on the next line takes advantage of that
583                  n1 >= d1 (true due to program flow).  */
584               if (n1 > d1 || n0 >= d0)
585                 {
586                   q0 = 1;
587                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
588                 }
589               else
590                 q0 = 0;
591
592               q1 = 0;
593
594               if (rp != 0)
595                 {
596                   rr.s.low = n0;
597                   rr.s.high = n1;
598                   *rp = rr.ll;
599                 }
600             }
601           else
602             {
603               USItype m1, m0;
604               /* Normalize.  */
605
606               b = SI_TYPE_SIZE - bm;
607
608               d1 = (d1 << bm) | (d0 >> b);
609               d0 = d0 << bm;
610               n2 = n1 >> b;
611               n1 = (n1 << bm) | (n0 >> b);
612               n0 = n0 << bm;
613
614               udiv_qrnnd (q0, n1, n2, n1, d1);
615               umul_ppmm (m1, m0, q0, d0);
616
617               if (m1 > n1 || (m1 == n1 && m0 > n0))
618                 {
619                   q0--;
620                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
621                 }
622
623               q1 = 0;
624
625               /* Remainder in (n1n0 - m1m0) >> bm.  */
626               if (rp != 0)
627                 {
628                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
629                   rr.s.low = (n1 << b) | (n0 >> bm);
630                   rr.s.high = n1 >> bm;
631                   *rp = rr.ll;
632                 }
633             }
634         }
635     }
636
637   ww.s.low = q0;
638   ww.s.high = q1;
639   return ww.ll;
640 }
641 #endif
642
643 #ifdef L_divdi3
644 UDItype __udivmoddi4 ();
645
646 DItype
647 __divdi3 (u, v)
648      DItype u, v;
649 {
650   word_type c = 0;
651   DIunion uu, vv;
652   DItype w;
653
654   uu.ll = u;
655   vv.ll = v;
656
657   if (uu.s.high < 0)
658     c = ~c,
659     uu.ll = __negdi2 (uu.ll);
660   if (vv.s.high < 0)
661     c = ~c,
662     vv.ll = __negdi2 (vv.ll);
663
664   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
665   if (c)
666     w = __negdi2 (w);
667
668   return w;
669 }
670 #endif
671
672 #ifdef L_moddi3
673 UDItype __udivmoddi4 ();
674 DItype
675 __moddi3 (u, v)
676      DItype u, v;
677 {
678   word_type c = 0;
679   DIunion uu, vv;
680   DItype w;
681
682   uu.ll = u;
683   vv.ll = v;
684
685   if (uu.s.high < 0)
686     c = ~c,
687     uu.ll = __negdi2 (uu.ll);
688   if (vv.s.high < 0)
689     vv.ll = __negdi2 (vv.ll);
690
691   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
692   if (c)
693     w = __negdi2 (w);
694
695   return w;
696 }
697 #endif
698
699 #ifdef L_umoddi3
700 UDItype __udivmoddi4 ();
701 UDItype
702 __umoddi3 (u, v)
703      UDItype u, v;
704 {
705   UDItype w;
706
707   (void) __udivmoddi4 (u, v, &w);
708
709   return w;
710 }
711 #endif
712
713 #ifdef L_udivdi3
714 UDItype __udivmoddi4 ();
715 UDItype
716 __udivdi3 (n, d)
717      UDItype n, d;
718 {
719   return __udivmoddi4 (n, d, (UDItype *) 0);
720 }
721 #endif
722 \f
723 #ifdef L_cmpdi2
724 word_type
725 __cmpdi2 (a, b)
726      DItype a, b;
727 {
728   DIunion au, bu;
729
730   au.ll = a, bu.ll = b;
731
732   if (au.s.high < bu.s.high)
733     return 0;
734   else if (au.s.high > bu.s.high)
735     return 2;
736   if ((USItype) au.s.low < (USItype) bu.s.low)
737     return 0;
738   else if ((USItype) au.s.low > (USItype) bu.s.low)
739     return 2;
740   return 1;
741 }
742 #endif
743
744 #ifdef L_ucmpdi2
745 word_type
746 __ucmpdi2 (a, b)
747      DItype a, b;
748 {
749   DIunion au, bu;
750
751   au.ll = a, bu.ll = b;
752
753   if ((USItype) au.s.high < (USItype) bu.s.high)
754     return 0;
755   else if ((USItype) au.s.high > (USItype) bu.s.high)
756     return 2;
757   if ((USItype) au.s.low < (USItype) bu.s.low)
758     return 0;
759   else if ((USItype) au.s.low > (USItype) bu.s.low)
760     return 2;
761   return 1;
762 }
763 #endif
764 \f
765 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
768
769 DItype
770 __fixunstfdi (a)
771      TFtype a;
772 {
773   TFtype b;
774   UDItype v;
775
776   if (a < 0)
777     return 0;
778
779   /* Compute high word of result, as a flonum.  */
780   b = (a / HIGH_WORD_COEFF);
781   /* Convert that to fixed (but not to DItype!),
782      and shift it into the high word.  */
783   v = (USItype) b;
784   v <<= WORD_SIZE;
785   /* Remove high part from the TFtype, leaving the low part as flonum.  */
786   a -= (TFtype)v;
787   /* Convert that to fixed (but not to DItype!) and add it in.
788      Sometimes A comes out negative.  This is significant, since
789      A has more bits than a long int does.  */
790   if (a < 0)
791     v -= (USItype) (- a);
792   else
793     v += (USItype) a;
794   return v;
795 }
796 #endif
797
798 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
799 DItype
800 __fixtfdi (a)
801      TFtype a;
802 {
803   if (a < 0)
804     return - __fixunstfdi (-a);
805   return __fixunstfdi (a);
806 }
807 #endif
808
809 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
812
813 DItype
814 __fixunsxfdi (a)
815      XFtype a;
816 {
817   XFtype b;
818   UDItype v;
819
820   if (a < 0)
821     return 0;
822
823   /* Compute high word of result, as a flonum.  */
824   b = (a / HIGH_WORD_COEFF);
825   /* Convert that to fixed (but not to DItype!),
826      and shift it into the high word.  */
827   v = (USItype) b;
828   v <<= WORD_SIZE;
829   /* Remove high part from the XFtype, leaving the low part as flonum.  */
830   a -= (XFtype)v;
831   /* Convert that to fixed (but not to DItype!) and add it in.
832      Sometimes A comes out negative.  This is significant, since
833      A has more bits than a long int does.  */
834   if (a < 0)
835     v -= (USItype) (- a);
836   else
837     v += (USItype) a;
838   return v;
839 }
840 #endif
841
842 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
843 DItype
844 __fixxfdi (a)
845      XFtype a;
846 {
847   if (a < 0)
848     return - __fixunsxfdi (-a);
849   return __fixunsxfdi (a);
850 }
851 #endif
852
853 #ifdef L_fixunsdfdi
854 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
856
857 DItype
858 __fixunsdfdi (a)
859      DFtype a;
860 {
861   DFtype b;
862   UDItype v;
863
864   if (a < 0)
865     return 0;
866
867   /* Compute high word of result, as a flonum.  */
868   b = (a / HIGH_WORD_COEFF);
869   /* Convert that to fixed (but not to DItype!),
870      and shift it into the high word.  */
871   v = (USItype) b;
872   v <<= WORD_SIZE;
873   /* Remove high part from the DFtype, leaving the low part as flonum.  */
874   a -= (DFtype)v;
875   /* Convert that to fixed (but not to DItype!) and add it in.
876      Sometimes A comes out negative.  This is significant, since
877      A has more bits than a long int does.  */
878   if (a < 0)
879     v -= (USItype) (- a);
880   else
881     v += (USItype) a;
882   return v;
883 }
884 #endif
885
886 #ifdef L_fixdfdi
887 DItype
888 __fixdfdi (a)
889      DFtype a;
890 {
891   if (a < 0)
892     return - __fixunsdfdi (-a);
893   return __fixunsdfdi (a);
894 }
895 #endif
896
897 #ifdef L_fixunssfdi
898 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
900
901 DItype
902 __fixunssfdi (SFtype original_a)
903 {
904   /* Convert the SFtype to a DFtype, because that is surely not going
905      to lose any bits.  Some day someone else can write a faster version
906      that avoids converting to DFtype, and verify it really works right.  */
907   DFtype a = original_a;
908   DFtype b;
909   UDItype v;
910
911   if (a < 0)
912     return 0;
913
914   /* Compute high word of result, as a flonum.  */
915   b = (a / HIGH_WORD_COEFF);
916   /* Convert that to fixed (but not to DItype!),
917      and shift it into the high word.  */
918   v = (USItype) b;
919   v <<= WORD_SIZE;
920   /* Remove high part from the DFtype, leaving the low part as flonum.  */
921   a -= (DFtype)v;
922   /* Convert that to fixed (but not to DItype!) and add it in.
923      Sometimes A comes out negative.  This is significant, since
924      A has more bits than a long int does.  */
925   if (a < 0)
926     v -= (USItype) (- a);
927   else
928     v += (USItype) a;
929   return v;
930 }
931 #endif
932
933 #ifdef L_fixsfdi
934 DItype
935 __fixsfdi (SFtype a)
936 {
937   if (a < 0)
938     return - __fixunssfdi (-a);
939   return __fixunssfdi (a);
940 }
941 #endif
942
943 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
944 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
947
948 XFtype
949 __floatdixf (u)
950      DItype u;
951 {
952   XFtype d;
953   SItype negate = 0;
954
955   if (u < 0)
956     u = -u, negate = 1;
957
958   d = (USItype) (u >> WORD_SIZE);
959   d *= HIGH_HALFWORD_COEFF;
960   d *= HIGH_HALFWORD_COEFF;
961   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
962
963   return (negate ? -d : d);
964 }
965 #endif
966
967 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
971
972 TFtype
973 __floatditf (u)
974      DItype u;
975 {
976   TFtype d;
977   SItype negate = 0;
978
979   if (u < 0)
980     u = -u, negate = 1;
981
982   d = (USItype) (u >> WORD_SIZE);
983   d *= HIGH_HALFWORD_COEFF;
984   d *= HIGH_HALFWORD_COEFF;
985   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
986
987   return (negate ? -d : d);
988 }
989 #endif
990
991 #ifdef L_floatdidf
992 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
995
996 DFtype
997 __floatdidf (u)
998      DItype u;
999 {
1000   DFtype d;
1001   SItype negate = 0;
1002
1003   if (u < 0)
1004     u = -u, negate = 1;
1005
1006   d = (USItype) (u >> WORD_SIZE);
1007   d *= HIGH_HALFWORD_COEFF;
1008   d *= HIGH_HALFWORD_COEFF;
1009   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1010
1011   return (negate ? -d : d);
1012 }
1013 #endif
1014
1015 #ifdef L_floatdisf
1016 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1020
1021 /* Define codes for all the float formats that we know of.  Note
1022    that this is copied from real.h.  */
1023    
1024 #define UNKNOWN_FLOAT_FORMAT 0
1025 #define IEEE_FLOAT_FORMAT 1
1026 #define VAX_FLOAT_FORMAT 2
1027 #define IBM_FLOAT_FORMAT 3
1028
1029 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1030 #ifndef HOST_FLOAT_FORMAT
1031 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1032 #endif
1033
1034 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1035 #define DF_SIZE 53
1036 #define SF_SIZE 24
1037 #endif
1038
1039 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1040 #define DF_SIZE 56
1041 #define SF_SIZE 24
1042 #endif
1043
1044 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1045 #define DF_SIZE 56
1046 #define SF_SIZE 24
1047 #endif
1048
1049 SFtype
1050 __floatdisf (u)
1051      DItype u;
1052 {
1053   /* Do the calculation in DFmode
1054      so that we don't lose any of the precision of the high word
1055      while multiplying it.  */
1056   DFtype f;
1057   SItype negate = 0;
1058
1059   if (u < 0)
1060     u = -u, negate = 1;
1061
1062   /* Protect against double-rounding error.
1063      Represent any low-order bits, that might be truncated in DFmode,
1064      by a bit that won't be lost.  The bit can go in anywhere below the
1065      rounding position of the SFmode.  A fixed mask and bit position
1066      handles all usual configurations.  It doesn't handle the case
1067      of 128-bit DImode, however.  */
1068   if (DF_SIZE < DI_SIZE
1069       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1070     {
1071 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072       if (u >= ((UDItype) 1 << DF_SIZE))
1073         {
1074           if ((USItype) u & (REP_BIT - 1))
1075             u |= REP_BIT;
1076         }
1077     }
1078   f = (USItype) (u >> WORD_SIZE);
1079   f *= HIGH_HALFWORD_COEFF;
1080   f *= HIGH_HALFWORD_COEFF;
1081   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1082
1083   return (SFtype) (negate ? -f : f);
1084 }
1085 #endif
1086
1087 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088 /* Reenable the normal types, in case limits.h needs them.  */
1089 #undef char
1090 #undef short
1091 #undef int
1092 #undef long
1093 #undef unsigned
1094 #undef float
1095 #undef double
1096 #undef MIN
1097 #undef MAX
1098 #include <limits.h>
1099
1100 USItype
1101 __fixunsxfsi (a)
1102      XFtype a;
1103 {
1104   if (a >= - (DFtype) LONG_MIN)
1105     return (SItype) (a + LONG_MIN) - LONG_MIN;
1106   return (SItype) a;
1107 }
1108 #endif
1109
1110 #ifdef L_fixunsdfsi
1111 /* Reenable the normal types, in case limits.h needs them.  */
1112 #undef char
1113 #undef short
1114 #undef int
1115 #undef long
1116 #undef unsigned
1117 #undef float
1118 #undef double
1119 #undef MIN
1120 #undef MAX
1121 #include <limits.h>
1122
1123 USItype
1124 __fixunsdfsi (a)
1125      DFtype a;
1126 {
1127   if (a >= - (DFtype) LONG_MIN)
1128     return (SItype) (a + LONG_MIN) - LONG_MIN;
1129   return (SItype) a;
1130 }
1131 #endif
1132
1133 #ifdef L_fixunssfsi
1134 /* Reenable the normal types, in case limits.h needs them.  */
1135 #undef char
1136 #undef short
1137 #undef int
1138 #undef long
1139 #undef unsigned
1140 #undef float
1141 #undef double
1142 #undef MIN
1143 #undef MAX
1144 #include <limits.h>
1145
1146 USItype
1147 __fixunssfsi (SFtype a)
1148 {
1149   if (a >= - (SFtype) LONG_MIN)
1150     return (SItype) (a + LONG_MIN) - LONG_MIN;
1151   return (SItype) a;
1152 }
1153 #endif
1154 \f
1155 /* From here on down, the routines use normal data types.  */
1156
1157 #define SItype bogus_type
1158 #define USItype bogus_type
1159 #define DItype bogus_type
1160 #define UDItype bogus_type
1161 #define SFtype bogus_type
1162 #define DFtype bogus_type
1163
1164 #undef char
1165 #undef short
1166 #undef int
1167 #undef long
1168 #undef unsigned
1169 #undef float
1170 #undef double
1171 \f
1172 #ifdef L__gcc_bcmp
1173
1174 /* Like bcmp except the sign is meaningful.
1175    Result is negative if S1 is less than S2,
1176    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1177
1178 int
1179 __gcc_bcmp (s1, s2, size)
1180      unsigned char *s1, *s2;
1181      size_t size;
1182 {
1183   while (size > 0)
1184     {
1185       unsigned char c1 = *s1++, c2 = *s2++;
1186       if (c1 != c2)
1187         return c1 - c2;
1188       size--;
1189     }
1190   return 0;
1191 }
1192
1193 #endif
1194 \f\f
1195 #ifdef L_varargs
1196 #ifdef __i860__
1197 #if defined(__svr4__) || defined(__alliant__)
1198         asm ("  .text");
1199         asm ("  .align  4");
1200
1201 /* The Alliant needs the added underscore.  */
1202         asm (".globl    __builtin_saveregs");
1203 asm ("__builtin_saveregs:");
1204         asm (".globl    ___builtin_saveregs");
1205 asm ("___builtin_saveregs:");
1206
1207         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1208         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1209                                            area and also for a new va_list
1210                                            structure */
1211         /* Save all argument registers in the arg reg save area.  The
1212            arg reg save area must have the following layout (according
1213            to the svr4 ABI):
1214
1215                 struct {
1216                   union  {
1217                     float freg[8];
1218                     double dreg[4];
1219                   } float_regs;
1220                   long  ireg[12];
1221                 };
1222         */
1223
1224         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1225         asm ("  fst.q   %f12,16(%sp)"); 
1226
1227         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1228         asm ("  st.l    %r17,36(%sp)"); 
1229         asm ("  st.l    %r18,40(%sp)");
1230         asm ("  st.l    %r19,44(%sp)");
1231         asm ("  st.l    %r20,48(%sp)");
1232         asm ("  st.l    %r21,52(%sp)");
1233         asm ("  st.l    %r22,56(%sp)");
1234         asm ("  st.l    %r23,60(%sp)");
1235         asm ("  st.l    %r24,64(%sp)");
1236         asm ("  st.l    %r25,68(%sp)");
1237         asm ("  st.l    %r26,72(%sp)");
1238         asm ("  st.l    %r27,76(%sp)");
1239
1240         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1241                                            va_list structure.  Put in into
1242                                            r16 so that it will be returned
1243                                            to the caller.  */
1244
1245         /* Initialize all fields of the new va_list structure.  This
1246            structure looks like:
1247
1248                 typedef struct {
1249                     unsigned long       ireg_used;
1250                     unsigned long       freg_used;
1251                     long                *reg_base;
1252                     long                *mem_ptr;
1253                 } va_list;
1254         */
1255
1256         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1257         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1258         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1259         asm ("  bri     %r1");          /* delayed return */
1260         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1261
1262 #else /* not __svr4__ */
1263 #if defined(__PARAGON__)
1264         /*
1265          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1266          *      and we stand a better chance of hooking into libraries
1267          *      compiled by PGI.  [andyp@ssd.intel.com]
1268          */
1269         asm ("  .text");
1270         asm ("  .align  4");
1271         asm (".globl    __builtin_saveregs");
1272 asm ("__builtin_saveregs:");
1273         asm (".globl    ___builtin_saveregs");
1274 asm ("___builtin_saveregs:");
1275
1276         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1277         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1278                                            area and also for a new va_list
1279                                            structure */
1280         /* Save all argument registers in the arg reg save area.  The
1281            arg reg save area must have the following layout (according
1282            to the svr4 ABI):
1283
1284                 struct {
1285                   union  {
1286                     float freg[8];
1287                     double dreg[4];
1288                   } float_regs;
1289                   long  ireg[12];
1290                 };
1291         */
1292
1293         asm ("  fst.q   f8,  0(sp)");
1294         asm ("  fst.q   f12,16(sp)"); 
1295         asm ("  st.l    r16,32(sp)");
1296         asm ("  st.l    r17,36(sp)"); 
1297         asm ("  st.l    r18,40(sp)");
1298         asm ("  st.l    r19,44(sp)");
1299         asm ("  st.l    r20,48(sp)");
1300         asm ("  st.l    r21,52(sp)");
1301         asm ("  st.l    r22,56(sp)");
1302         asm ("  st.l    r23,60(sp)");
1303         asm ("  st.l    r24,64(sp)");
1304         asm ("  st.l    r25,68(sp)");
1305         asm ("  st.l    r26,72(sp)");
1306         asm ("  st.l    r27,76(sp)");
1307
1308         asm ("  adds    80,sp,r16");  /* compute the address of the new
1309                                            va_list structure.  Put in into
1310                                            r16 so that it will be returned
1311                                            to the caller.  */
1312
1313         /* Initialize all fields of the new va_list structure.  This
1314            structure looks like:
1315
1316                 typedef struct {
1317                     unsigned long       ireg_used;
1318                     unsigned long       freg_used;
1319                     long                *reg_base;
1320                     long                *mem_ptr;
1321                 } va_list;
1322         */
1323
1324         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1325         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1326         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1327         asm ("  bri     r1");           /* delayed return */
1328         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1329 #else /* not __PARAGON__ */
1330         asm ("  .text");
1331         asm ("  .align  4");
1332
1333         asm (".globl    ___builtin_saveregs");
1334         asm ("___builtin_saveregs:");
1335         asm ("  mov     sp,r30");
1336         asm ("  andnot  0x0f,sp,sp");
1337         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1338
1339 /* Fill in the __va_struct.  */
1340         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1341         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1342         asm ("  st.l    r18, 8(sp)");
1343         asm ("  st.l    r19,12(sp)");
1344         asm ("  st.l    r20,16(sp)");
1345         asm ("  st.l    r21,20(sp)");
1346         asm ("  st.l    r22,24(sp)");
1347         asm ("  st.l    r23,28(sp)");
1348         asm ("  st.l    r24,32(sp)");
1349         asm ("  st.l    r25,36(sp)");
1350         asm ("  st.l    r26,40(sp)");
1351         asm ("  st.l    r27,44(sp)");
1352
1353         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1354         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1355
1356 /* Fill in the __va_ctl.  */
1357         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1358         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1359         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1360         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1361
1362         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1363         asm ("  bri     r1");
1364         asm ("  mov     r30,sp");
1365                                 /* recover stack and pass address to start 
1366                                    of data.  */
1367 #endif /* not __PARAGON__ */
1368 #endif /* not __svr4__ */
1369 #else /* not __i860__ */
1370 #ifdef __sparc__
1371         asm (".global __builtin_saveregs");
1372         asm ("__builtin_saveregs:");
1373         asm (".global ___builtin_saveregs");
1374         asm ("___builtin_saveregs:");
1375 #ifdef NEED_PROC_COMMAND
1376         asm (".proc 020");
1377 #endif
1378         asm ("st %i0,[%fp+68]");
1379         asm ("st %i1,[%fp+72]");
1380         asm ("st %i2,[%fp+76]");
1381         asm ("st %i3,[%fp+80]");
1382         asm ("st %i4,[%fp+84]");
1383         asm ("retl");
1384         asm ("st %i5,[%fp+88]");
1385 #ifdef NEED_TYPE_COMMAND
1386         asm (".type __builtin_saveregs,#function");
1387         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1388 #endif
1389 #else /* not __sparc__ */
1390 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1391
1392   asm ("        .text");
1393   asm ("        .ent __builtin_saveregs");
1394   asm ("        .globl __builtin_saveregs");
1395   asm ("__builtin_saveregs:");
1396   asm ("        sw      $4,0($30)");
1397   asm ("        sw      $5,4($30)");
1398   asm ("        sw      $6,8($30)");
1399   asm ("        sw      $7,12($30)");
1400   asm ("        j       $31");
1401   asm ("        .end __builtin_saveregs");
1402 #else /* not __mips__, etc. */
1403
1404 void *
1405 __builtin_saveregs ()
1406 {
1407   abort ();
1408 }
1409
1410 #endif /* not __mips__ */
1411 #endif /* not __sparc__ */
1412 #endif /* not __i860__ */
1413 #endif
1414 \f
1415 #ifdef L_eprintf
1416 #ifndef inhibit_libc
1417
1418 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1419 #include <stdio.h>
1420 /* This is used by the `assert' macro.  */
1421 void
1422 __eprintf (string, expression, line, filename)
1423      const char *string;
1424      const char *expression;
1425      int line;
1426      const char *filename;
1427 {
1428   fprintf (stderr, string, expression, line, filename);
1429   fflush (stderr);
1430   abort ();
1431 }
1432
1433 #endif
1434 #endif
1435
1436 #ifdef L_bb
1437
1438 /* Structure emitted by -a  */
1439 struct bb
1440 {
1441   long zero_word;
1442   const char *filename;
1443   long *counts;
1444   long ncounts;
1445   struct bb *next;
1446   const unsigned long *addresses;
1447
1448   /* Older GCC's did not emit these fields.  */
1449   long nwords;
1450   const char **functions;
1451   const long *line_nums;
1452   const char **filenames;
1453 };
1454
1455 #ifdef BLOCK_PROFILER_CODE
1456 BLOCK_PROFILER_CODE
1457 #else
1458 #ifndef inhibit_libc
1459
1460 /* Simple minded basic block profiling output dumper for
1461    systems that don't provide tcov support.  At present,
1462    it requires atexit and stdio.  */
1463
1464 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1465 #include <stdio.h>
1466 char *ctime ();
1467
1468 #ifdef HAVE_ATEXIT
1469 #ifdef WINNT
1470 extern int atexit (void (*) (void));
1471 #else
1472 extern void atexit (void (*) (void));
1473 #endif
1474 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1475 #else
1476 #ifdef sun
1477 extern void on_exit (void*, void*);
1478 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1479 #endif
1480 #endif
1481
1482 static struct bb *bb_head;
1483
1484 /* Return the number of digits needed to print a value */
1485 /* __inline__ */ static int num_digits (long value, int base)
1486 {
1487   int minus = (value < 0 && base != 16);
1488   unsigned long v = (minus) ? -value : value;
1489   int ret = minus;
1490
1491   do
1492     {
1493       v /= base;
1494       ret++;
1495     }
1496   while (v);
1497
1498   return ret;
1499 }
1500
1501 void
1502 __bb_exit_func (void)
1503 {
1504   FILE *file = fopen ("bb.out", "a");
1505   long time_value;
1506
1507   if (!file)
1508     perror ("bb.out");
1509
1510   else
1511     {
1512       struct bb *ptr;
1513
1514       /* This is somewhat type incorrect, but it avoids worrying about
1515          exactly where time.h is included from.  It should be ok unless
1516          a void * differs from other pointer formats, or if sizeof(long)
1517          is < sizeof (time_t).  It would be nice if we could assume the
1518          use of rationale standards here.  */
1519
1520       time((void *) &time_value);
1521       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1522
1523       /* We check the length field explicitly in order to allow compatibility
1524          with older GCC's which did not provide it.  */
1525
1526       for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1527         {
1528           int i;
1529           int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1530           int line_p    = (func_p && ptr->line_nums);
1531           int file_p    = (func_p && ptr->filenames);
1532           long ncounts  = ptr->ncounts;
1533           long cnt_max  = 0;
1534           long line_max = 0;
1535           long addr_max = 0;
1536           int file_len  = 0;
1537           int func_len  = 0;
1538           int blk_len   = num_digits (ncounts, 10);
1539           int cnt_len;
1540           int line_len;
1541           int addr_len;
1542
1543           fprintf (file, "File %s, %ld basic blocks \n\n",
1544                    ptr->filename, ncounts);
1545
1546           /* Get max values for each field.  */
1547           for (i = 0; i < ncounts; i++)
1548             {
1549               const char *p;
1550               int len;
1551
1552               if (cnt_max < ptr->counts[i])
1553                 cnt_max = ptr->counts[i];
1554
1555               if (addr_max < ptr->addresses[i])
1556                 addr_max = ptr->addresses[i];
1557
1558               if (line_p && line_max < ptr->line_nums[i])
1559                 line_max = ptr->line_nums[i];
1560
1561               if (func_p)
1562                 {
1563                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1564                   len = strlen (p);
1565                   if (func_len < len)
1566                     func_len = len;
1567                 }
1568
1569               if (file_p)
1570                 {
1571                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1572                   len = strlen (p);
1573                   if (file_len < len)
1574                     file_len = len;
1575                 }
1576             }
1577
1578           addr_len = num_digits (addr_max, 16);
1579           cnt_len  = num_digits (cnt_max, 10);
1580           line_len = num_digits (line_max, 10);
1581
1582           /* Now print out the basic block information.  */
1583           for (i = 0; i < ncounts; i++)
1584             {
1585               fprintf (file,
1586                        "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1587                        blk_len, i+1,
1588                        cnt_len, ptr->counts[i],
1589                        addr_len, ptr->addresses[i]);
1590
1591               if (func_p)
1592                 fprintf (file, " function= %-*s", func_len,
1593                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1594
1595               if (line_p)
1596                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1597
1598               if (file_p)
1599                 fprintf (file, " file= %s",
1600                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1601
1602               fprintf (file, "\n");
1603             }
1604
1605           fprintf (file, "\n");
1606           fflush (file);
1607         }
1608
1609       fprintf (file, "\n\n");
1610       fclose (file);
1611     }
1612 }
1613
1614 void
1615 __bb_init_func (struct bb *blocks)
1616 {
1617   /* User is supposed to check whether the first word is non-0,
1618      but just in case.... */
1619
1620   if (blocks->zero_word)
1621     return;
1622
1623 #ifdef ON_EXIT
1624   /* Initialize destructor.  */
1625   if (!bb_head)
1626     ON_EXIT (__bb_exit_func, 0);
1627 #endif
1628
1629   /* Set up linked list.  */
1630   blocks->zero_word = 1;
1631   blocks->next = bb_head;
1632   bb_head = blocks;
1633 }
1634
1635 #endif /* not inhibit_libc */
1636 #endif /* not BLOCK_PROFILER_CODE */
1637 #endif /* L_bb */
1638 \f
1639 /* Default free-store management functions for C++, per sections 12.5 and
1640    17.3.3 of the Working Paper. */
1641
1642 #ifdef L_op_new
1643 /* operator new (size_t), described in 17.3.3.5.  This function is used by
1644    C++ programs to allocate a block of memory to hold a single object. */
1645
1646 typedef void (*vfp)(void);
1647 extern vfp __new_handler;
1648 extern void __default_new_handler (void);
1649
1650 #ifdef WEAK_ALIAS
1651 void * __builtin_new (size_t sz)
1652      __attribute__ ((weak, alias ("___builtin_new")));
1653 void *
1654 ___builtin_new (size_t sz)
1655 #else
1656 void *
1657 __builtin_new (size_t sz)
1658 #endif
1659 {
1660   void *p;
1661   vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1662
1663   /* malloc (0) is unpredictable; avoid it.  */
1664   if (sz == 0)
1665     sz = 1;
1666   p = (void *) malloc (sz);
1667   while (p == 0)
1668     {
1669       (*handler) ();
1670       p = (void *) malloc (sz);
1671     }
1672   
1673   return p;
1674 }
1675 #endif /* L_op_new */
1676
1677 #ifdef L_op_vnew
1678 /* void * operator new [] (size_t), described in 17.3.3.6.  This function
1679    is used by C++ programs to allocate a block of memory for an array.  */
1680
1681 extern void * __builtin_new (size_t);
1682
1683 #ifdef WEAK_ALIAS
1684 void * __builtin_vec_new (size_t sz)
1685      __attribute__ ((weak, alias ("___builtin_vec_new")));
1686 void *
1687 ___builtin_vec_new (size_t sz)
1688 #else
1689 void *
1690 __builtin_vec_new (size_t sz)
1691 #endif
1692 {
1693   return __builtin_new (sz);
1694 }
1695 #endif /* L_op_vnew */
1696
1697 #ifdef L_new_handler
1698 /* set_new_handler (fvoid_t *) and the default new handler, described in
1699    17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
1700    to allocate the amount of memory requested from operator new or new []. */
1701
1702 #ifndef inhibit_libc
1703 /* This gets us __GNU_LIBRARY__.  */
1704 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1705 #include <stdio.h>
1706
1707 #ifdef __GNU_LIBRARY__
1708   /* Avoid forcing the library's meaning of `write' on the user program
1709      by using the "internal" name (for use within the library)  */
1710 #define write(fd, buf, n)       __write((fd), (buf), (n))
1711 #endif
1712 #endif /* inhibit_libc */
1713
1714 typedef void (*vfp)(void);
1715 void __default_new_handler (void);
1716
1717 vfp __new_handler = (vfp)0;
1718
1719 vfp
1720 set_new_handler (vfp handler)
1721 {
1722   vfp prev_handler;
1723
1724   prev_handler = __new_handler;
1725   if (handler == 0) handler = __default_new_handler;
1726   __new_handler = handler;
1727   return prev_handler;
1728 }
1729
1730 #define MESSAGE "Virtual memory exceeded in `new'\n"
1731
1732 void
1733 __default_new_handler ()
1734 {
1735 #ifndef inhibit_libc
1736   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1737   /* This should really print the name of the program, but that is hard to
1738      do.  We need a standard, clean way to get at the name.  */
1739   write (2, MESSAGE, sizeof (MESSAGE));
1740 #endif
1741   /* don't call exit () because that may call global destructors which
1742      may cause a loop.  */
1743   _exit (-1);
1744 }
1745 #endif
1746
1747 #ifdef L_op_delete
1748 /* operator delete (void *), described in 17.3.3.3.  This function is used
1749    by C++ programs to return to the free store a block of memory allocated
1750    as a single object. */
1751
1752 #ifdef WEAK_ALIAS
1753 void __builtin_delete (void *ptr)
1754      __attribute__ ((weak, alias ("___builtin_delete")));
1755 void
1756 ___builtin_delete (void *ptr)
1757 #else
1758 void
1759 __builtin_delete (void *ptr)
1760 #endif
1761 {
1762   if (ptr)
1763     free (ptr);
1764 }
1765 #endif
1766
1767 #ifdef L_op_vdel
1768 /* operator delete [] (void *), described in 17.3.3.4.  This function is
1769    used by C++ programs to return to the free store a block of memory
1770    allocated as an array. */
1771
1772 extern void __builtin_delete (void *);
1773
1774 #ifdef WEAK_ALIAS
1775 void __builtin_vec_delete (void *ptr)
1776      __attribute__ ((weak, alias ("___builtin_vec_delete")));
1777 void
1778 ___builtin_vec_delete (void *ptr)
1779 #else
1780 void
1781 __builtin_vec_delete (void *ptr)
1782 #endif
1783 {
1784   __builtin_delete (ptr);
1785 }
1786 #endif
1787
1788 /* End of C++ free-store management functions */
1789 \f
1790 #ifdef L_shtab
1791 unsigned int __shtab[] = {
1792     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1793     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1794     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1795     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1796     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1797     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1798     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1799     0x10000000, 0x20000000, 0x40000000, 0x80000000
1800   };
1801 #endif
1802 \f
1803 #ifdef L_clear_cache
1804 /* Clear part of an instruction cache.  */
1805
1806 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1807
1808 void
1809 __clear_cache (beg, end)
1810      char *beg, *end;
1811 {
1812 #ifdef CLEAR_INSN_CACHE 
1813   CLEAR_INSN_CACHE (beg, end);
1814 #else
1815 #ifdef INSN_CACHE_SIZE
1816   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1817   static int initialized;
1818   int offset;
1819   void *start_addr
1820   void *end_addr;
1821   typedef (*function_ptr) ();
1822
1823 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1824   /* It's cheaper to clear the whole cache.
1825      Put in a series of jump instructions so that calling the beginning
1826      of the cache will clear the whole thing.  */
1827
1828   if (! initialized)
1829     {
1830       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1831                  & -INSN_CACHE_LINE_WIDTH);
1832       int end_ptr = ptr + INSN_CACHE_SIZE;
1833
1834       while (ptr < end_ptr)
1835         {
1836           *(INSTRUCTION_TYPE *)ptr
1837             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1838           ptr += INSN_CACHE_LINE_WIDTH;
1839         }
1840       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1841
1842       initialized = 1;
1843     }
1844
1845   /* Call the beginning of the sequence.  */
1846   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1847                     & -INSN_CACHE_LINE_WIDTH))
1848    ());
1849
1850 #else /* Cache is large.  */
1851
1852   if (! initialized)
1853     {
1854       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1855                  & -INSN_CACHE_LINE_WIDTH);
1856
1857       while (ptr < (int) array + sizeof array)
1858         {
1859           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1860           ptr += INSN_CACHE_LINE_WIDTH;
1861         }
1862
1863       initialized = 1;
1864     }
1865
1866   /* Find the location in array that occupies the same cache line as BEG.  */
1867
1868   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1869   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1870                  & -INSN_CACHE_PLANE_SIZE)
1871                 + offset);
1872
1873   /* Compute the cache alignment of the place to stop clearing.  */
1874 #if 0  /* This is not needed for gcc's purposes.  */
1875   /* If the block to clear is bigger than a cache plane,
1876      we clear the entire cache, and OFFSET is already correct.  */ 
1877   if (end < beg + INSN_CACHE_PLANE_SIZE)
1878 #endif
1879     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1880                & -INSN_CACHE_LINE_WIDTH)
1881               & (INSN_CACHE_PLANE_SIZE - 1));
1882
1883 #if INSN_CACHE_DEPTH > 1
1884   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1885   if (end_addr <= start_addr)
1886     end_addr += INSN_CACHE_PLANE_SIZE;
1887
1888   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1889     {
1890       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1891       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1892
1893       while (addr != stop)
1894         {
1895           /* Call the return instruction at ADDR.  */
1896           ((function_ptr) addr) ();
1897
1898           addr += INSN_CACHE_LINE_WIDTH;
1899         }
1900     }
1901 #else /* just one plane */
1902   do
1903     {
1904       /* Call the return instruction at START_ADDR.  */
1905       ((function_ptr) start_addr) ();
1906
1907       start_addr += INSN_CACHE_LINE_WIDTH;
1908     }
1909   while ((start_addr % INSN_CACHE_SIZE) != offset);
1910 #endif /* just one plane */
1911 #endif /* Cache is large */
1912 #endif /* Cache exists */
1913 #endif /* CLEAR_INSN_CACHE */
1914 }
1915
1916 #endif /* L_clear_cache */
1917 \f
1918 #ifdef L_trampoline
1919
1920 /* Jump to a trampoline, loading the static chain address.  */
1921
1922 #ifdef TRANSFER_FROM_TRAMPOLINE 
1923 TRANSFER_FROM_TRAMPOLINE 
1924 #endif
1925
1926 #if defined (NeXT) && defined (__MACH__)
1927
1928 /* Make stack executable so we can call trampolines on stack.
1929    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1930 #ifdef NeXTStep21
1931  #include <mach.h>
1932 #else
1933  #include <mach/mach.h>
1934 #endif
1935
1936 void
1937 __enable_execute_stack (addr)
1938      char *addr;
1939 {
1940   kern_return_t r;
1941   char *eaddr = addr + TRAMPOLINE_SIZE;
1942   vm_address_t a = (vm_address_t) addr;
1943
1944   /* turn on execute access on stack */
1945   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1946   if (r != KERN_SUCCESS)
1947     {
1948       mach_error("vm_protect VM_PROT_ALL", r);
1949       exit(1);
1950     }
1951
1952   /* We inline the i-cache invalidation for speed */
1953
1954 #ifdef CLEAR_INSN_CACHE
1955   CLEAR_INSN_CACHE (addr, eaddr);
1956 #else
1957   __clear_cache ((int) addr, (int) eaddr);
1958 #endif
1959
1960
1961 #endif /* defined (NeXT) && defined (__MACH__) */
1962
1963 #ifdef __convex__
1964
1965 /* Make stack executable so we can call trampolines on stack.
1966    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1967
1968 #include <sys/mman.h>
1969 #include <sys/vmparam.h>
1970 #include <machine/machparam.h>
1971
1972 void
1973 __enable_execute_stack ()
1974 {
1975   int fp;
1976   static unsigned lowest = USRSTACK;
1977   unsigned current = (unsigned) &fp & -NBPG;
1978
1979   if (lowest > current)
1980     {
1981       unsigned len = lowest - current;
1982       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1983       lowest = current;
1984     }
1985
1986   /* Clear instruction cache in case an old trampoline is in it. */
1987   asm ("pich");
1988 }
1989 #endif /* __convex__ */
1990
1991 #ifdef __DOLPHIN__
1992
1993 /* Modified from the convex -code above. */
1994
1995 #include <sys/param.h>
1996 #include <errno.h>
1997 #include <sys/m88kbcs.h>
1998
1999 void
2000 __enable_execute_stack ()
2001 {
2002   int save_errno;
2003   static unsigned long lowest = USRSTACK;
2004   unsigned long current = (unsigned long) &save_errno & -NBPC;
2005   
2006   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2007      address is seen as 'negative'. That is the case with the stack.   */
2008
2009   save_errno=errno;
2010   if (lowest > current)
2011     {
2012       unsigned len=lowest-current;
2013       memctl(current,len,MCT_TEXT);
2014       lowest = current;
2015     }
2016   else
2017     memctl(current,NBPC,MCT_TEXT);
2018   errno=save_errno;
2019 }
2020
2021 #endif /* __DOLPHIN__ */
2022
2023 #ifdef __pyr__
2024
2025 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2026 #include <stdio.h>
2027 #include <sys/mman.h>
2028 #include <sys/types.h>
2029 #include <sys/param.h>
2030 #include <sys/vmmac.h>
2031
2032 /* Modified from the convex -code above.
2033    mremap promises to clear the i-cache. */
2034
2035 void
2036 __enable_execute_stack ()
2037 {
2038   int fp;
2039   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2040                 PROT_READ|PROT_WRITE|PROT_EXEC))
2041     {
2042       perror ("mprotect in __enable_execute_stack");
2043       fflush (stderr);
2044       abort ();
2045     }
2046 }
2047 #endif /* __pyr__ */
2048 #endif /* L_trampoline */
2049 \f
2050 #ifdef L__main
2051
2052 #include "gbl-ctors.h"
2053 /* Some systems use __main in a way incompatible with its use in gcc, in these
2054    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2055    give the same symbol without quotes for an alternative entry point.  You
2056    must define both, or neither. */
2057 #ifndef NAME__MAIN
2058 #define NAME__MAIN "__main"
2059 #define SYMBOL__MAIN __main
2060 #endif
2061
2062 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2063 /* Run all the global destructors on exit from the program.  */
2064
2065 void
2066 __do_global_dtors ()
2067 {
2068 #ifdef DO_GLOBAL_DTORS_BODY
2069   DO_GLOBAL_DTORS_BODY;
2070 #else
2071   func_ptr *p;
2072   for (p = __DTOR_LIST__ + 1; *p; )
2073     (*p++) ();
2074 #endif
2075 }
2076 #endif
2077
2078 #ifndef INIT_SECTION_ASM_OP
2079 /* Run all the global constructors on entry to the program.  */
2080
2081 #ifndef ON_EXIT
2082 #define ON_EXIT(a, b)
2083 #else
2084 /* Make sure the exit routine is pulled in to define the globals as
2085    bss symbols, just in case the linker does not automatically pull
2086    bss definitions from the library.  */
2087
2088 extern int _exit_dummy_decl;
2089 int *_exit_dummy_ref = &_exit_dummy_decl;
2090 #endif /* ON_EXIT */
2091
2092 void
2093 __do_global_ctors ()
2094 {
2095   DO_GLOBAL_CTORS_BODY;
2096   ON_EXIT (__do_global_dtors, 0);
2097 }
2098 #endif /* no INIT_SECTION_ASM_OP */
2099
2100 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2101 /* Subroutine called automatically by `main'.
2102    Compiling a global function named `main'
2103    produces an automatic call to this function at the beginning.
2104
2105    For many systems, this routine calls __do_global_ctors.
2106    For systems which support a .init section we use the .init section
2107    to run __do_global_ctors, so we need not do anything here.  */
2108
2109 void
2110 SYMBOL__MAIN ()
2111 {
2112   /* Support recursive calls to `main': run initializers just once.  */
2113   static int initialized;
2114   if (! initialized)
2115     {
2116       initialized = 1;
2117       __do_global_ctors ();
2118     }
2119 }
2120 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2121
2122 #endif /* L__main */
2123 \f
2124 #ifdef L_ctors
2125
2126 #include "gbl-ctors.h"
2127
2128 /* Provide default definitions for the lists of constructors and
2129    destructors, so that we don't get linker errors.  These symbols are
2130    intentionally bss symbols, so that gld and/or collect will provide
2131    the right values.  */
2132
2133 /* We declare the lists here with two elements each,
2134    so that they are valid empty lists if no other definition is loaded.  */
2135 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2136 #ifdef __NeXT__
2137 /* After 2.3, try this definition on all systems.  */
2138 func_ptr __CTOR_LIST__[2] = {0, 0};
2139 func_ptr __DTOR_LIST__[2] = {0, 0};
2140 #else
2141 func_ptr __CTOR_LIST__[2];
2142 func_ptr __DTOR_LIST__[2];
2143 #endif
2144 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2145 #endif /* L_ctors */
2146 \f
2147 #ifdef L_exit
2148
2149 #include "gbl-ctors.h"
2150
2151 #ifndef ON_EXIT
2152
2153 /* If we have no known way of registering our own __do_global_dtors
2154    routine so that it will be invoked at program exit time, then we
2155    have to define our own exit routine which will get this to happen.  */
2156
2157 extern void __do_global_dtors ();
2158 extern void _cleanup ();
2159 extern void _exit () __attribute__ ((noreturn));
2160
2161 void 
2162 exit (status)
2163      int status;
2164 {
2165 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2166   __do_global_dtors ();
2167 #endif
2168 #ifdef EXIT_BODY
2169   EXIT_BODY;
2170 #else
2171   _cleanup ();
2172 #endif
2173   _exit (status);
2174 }
2175
2176 #else
2177 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2178 #endif
2179
2180 #endif /* L_exit */
2181 \f
2182 #ifdef L_eh
2183 typedef struct {
2184   void *start;
2185   void *end;
2186   void *exception_handler;
2187 } exception_table;
2188
2189 struct exception_table_node {
2190   exception_table *table;
2191   void *start;
2192   void *end;
2193   struct exception_table_node *next;
2194 };
2195
2196 static int except_table_pos;
2197 static void *except_pc;
2198 static struct exception_table_node *exception_table_list;
2199
2200 static exception_table *
2201 find_exception_table (pc)
2202      void* pc;
2203 {
2204   register struct exception_table_node *table = exception_table_list;
2205   for ( ; table != 0; table = table->next)
2206     {
2207       if (table->start <= pc && table->end > pc)
2208         return table->table;
2209     }
2210   return 0;
2211 }
2212
2213 /* this routine takes a pc, and the address of the exception handler associated
2214    with the closest exception table handler entry associated with that PC,
2215    or 0 if there are no table entries the PC fits in.  The algorithm works
2216    something like this:
2217
2218     while(current_entry exists) {
2219         if(current_entry.start < pc )
2220             current_entry = next_entry;
2221         else {
2222             if(prev_entry.start <= pc && prev_entry.end > pc) {
2223                 save pointer to prev_entry;
2224                 return prev_entry.exception_handler;
2225              }
2226             else return 0;
2227          }
2228      }
2229     return 0;
2230
2231    Assuming a correctly sorted table (ascending order) this routine should
2232    return the tightest match...
2233
2234    In the advent of a tie, we have to give the last entry, as it represents
2235    an inner block.
2236  */
2237
2238
2239 void *
2240 __find_first_exception_table_match(pc)
2241 void *pc;
2242 {
2243   exception_table *table = find_exception_table (pc);
2244   int pos = 0;
2245   int best = 0;
2246   if (table == 0)
2247     return (void*)0;
2248 #if 0
2249   printf("find_first_exception_table_match(): pc = %x!\n",pc);
2250 #endif
2251
2252   except_pc = pc;
2253
2254 #if 0
2255   /* We can't do this yet, as we don't know that the table is sorted.  */
2256   do {
2257     ++pos;
2258     if (table[pos].start > except_pc)
2259       /* found the first table[pos].start > except_pc, so the previous
2260          entry better be the one we want! */
2261       break;
2262   } while(table[pos].exception_handler != (void*)-1);
2263
2264   --pos;
2265   if (table[pos].start <= except_pc && table[pos].end > except_pc)
2266     {
2267       except_table_pos = pos;
2268 #if 0
2269       printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2270 #endif
2271       return table[pos].exception_handler;
2272     }
2273 #else
2274   while (table[++pos].exception_handler != (void*)-1) {
2275     if (table[pos].start <= except_pc && table[pos].end > except_pc)
2276       {
2277         /* This can apply.  Make sure it is better or as good as the previous
2278            best.  */
2279         /* The best one ends first. */
2280         if (best == 0 || (table[pos].end <= table[best].end
2281                           /* The best one starts last.  */
2282                           && table[pos].start >= table[best].start))
2283           best = pos;
2284       }
2285   }
2286   if (best != 0)
2287     return table[best].exception_handler;
2288 #endif
2289
2290 #if 0
2291   printf("find_first_eh_table_match(): else: returning NULL!\n");
2292 #endif
2293   return (void*)0;
2294 }
2295
2296 void *
2297 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2298 {
2299 #if 0
2300  printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2301         catch_type, throw_type);
2302 #endif
2303  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2304    return obj;
2305  return 0;
2306 }
2307
2308 void
2309 __register_exceptions (exception_table *table)
2310 {
2311   struct exception_table_node *node;
2312   exception_table *range = table + 1;
2313
2314   if (range->start == (void*)-1)
2315     return;
2316
2317   node = (struct exception_table_node*)
2318     malloc (sizeof (struct exception_table_node));
2319   node->table = table;
2320
2321   /* This look can be optimized away either if the table
2322      is sorted, or if we pass in extra parameters. */
2323   node->start = range->start;
2324   node->end = range->end;
2325   for (range++ ; range->start != (void*)(-1); range++)
2326     {
2327       if (range->start < node->start)
2328         node->start = range->start;
2329       if (range->end > node->end)
2330         node->end = range->end;
2331     }
2332
2333   node->next = exception_table_list;
2334   exception_table_list = node;
2335 }
2336
2337 #if #machine(i386)
2338 void
2339 __unwind_function(void *ptr)
2340 {
2341   asm("movl 8(%esp),%ecx");
2342   /* Undo current frame */
2343   asm("movl %ebp,%esp");
2344   asm("popl %ebp");
2345   /* like ret, but stay here */
2346   asm("addl $4,%esp");
2347   
2348   /* Now, undo previous frame. */
2349   /* This is a test routine, as we have to dynamically probe to find out
2350      what to pop for certain, this is just a guess. */
2351   asm("leal -16(%ebp),%esp");
2352   asm("pop %ebx");
2353   asm("pop %esi");
2354   asm("pop %edi");
2355   asm("movl %ebp,%esp");
2356   asm("popl %ebp");
2357
2358   asm("movl %ecx,0(%esp)");
2359   asm("ret");
2360 }
2361 #elif #machine(rs6000)
2362 __unwind_function(void *ptr)
2363 {
2364   asm("mr 31,1");
2365   asm("l 1,0(1)");
2366   asm("l 31,-4(1)");
2367   asm("# br");
2368
2369   asm("mr 31,1");
2370   asm("l 1,0(1)");
2371   /* use 31 as a scratch register to restore the link register. */
2372   asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2373   asm("l 31,-4(1)");
2374   asm("# br");
2375   asm("mtctr 3;bctr # b 3");
2376 }
2377 #elif #machine(powerpc)
2378 __unwind_function(void *ptr)
2379 {
2380   asm("mr 31,1");
2381   asm("lwz 1,0(1)");
2382   asm("lwz 31,-4(1)");
2383   asm("# br");
2384
2385   asm("mr 31,1");
2386   asm("lwz 1,0(1)");
2387   /* use 31 as a scratch register to restore the link register. */
2388   asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2389   asm("lwz 31,-4(1)");
2390   asm("# br");
2391   asm("mtctr 3;bctr # b 3");
2392 }
2393 #else
2394 __unwind_function(void *ptr)
2395 {
2396   abort ();
2397 }
2398 #endif /* powerpc */
2399 #endif /* L_eh */
2400 \f
2401 #ifdef L_pure
2402 #ifndef inhibit_libc
2403 /* This gets us __GNU_LIBRARY__.  */
2404 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2405 #include <stdio.h>
2406
2407 #ifdef __GNU_LIBRARY__
2408   /* Avoid forcing the library's meaning of `write' on the user program
2409      by using the "internal" name (for use within the library)  */
2410 #define write(fd, buf, n)       __write((fd), (buf), (n))
2411 #endif
2412 #endif /* inhibit_libc */
2413
2414 #define MESSAGE "pure virtual method called\n"
2415
2416 void
2417 __pure_virtual ()
2418 {
2419 #ifndef inhibit_libc
2420   write (2, MESSAGE, sizeof (MESSAGE) - 1);
2421 #endif
2422   _exit (-1);
2423 }
2424 #endif