OSDN Git Service

* configure.in (m68*-*-rtemscoff*): New target, formal name for
[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, 92-98, 1999 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
35 /* We disable this when inhibit_libc, so that gcc can still be built without
36    needing header files first.  */
37 /* ??? This is not a good solution, since prototypes may be required in
38    some cases for correct code.  See also frame.c/crtstuff.c.  */
39 #ifndef inhibit_libc
40 /* fixproto guarantees these system headers exist. */
41 #include <stdlib.h>
42 #include <unistd.h>
43
44 #else
45 #ifndef L_trampoline
46 #include <stddef.h>
47 #ifndef malloc
48 extern void *malloc (size_t);
49 #endif
50 #ifndef free
51 extern void free (void *);
52 #endif
53 #ifndef atexit
54 extern int atexit(void (*)(void));
55 #endif
56 #endif
57 #endif
58
59 #include "machmode.h"
60 #include "defaults.h" 
61 #ifndef L_trampoline
62 #include <stddef.h>
63 #endif
64
65 /* Don't use `fancy_abort' here even if config.h says to use it.  */
66 #ifdef abort
67 #undef abort
68 #endif
69
70 /* In a cross-compilation situation, default to inhibiting compilation
71    of routines that use libc.  */
72
73 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
74 #define inhibit_libc
75 #endif
76
77 /* Permit the tm.h file to select the endianness to use just for this
78    file.  This is used when the endianness is determined when the
79    compiler is run.  */
80
81 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
82 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
83 #endif
84
85 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
86 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
87 #endif
88
89 /* In the first part of this file, we are interfacing to calls generated
90    by the compiler itself.  These calls pass values into these routines
91    which have very specific modes (rather than very specific types), and
92    these compiler-generated calls also expect any return values to have
93    very specific modes (rather than very specific types).  Thus, we need
94    to avoid using regular C language type names in this part of the file
95    because the sizes for those types can be configured to be anything.
96    Instead we use the following special type names.  */
97
98 typedef          int QItype     __attribute__ ((mode (QI)));
99 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
100 typedef          int HItype     __attribute__ ((mode (HI)));
101 typedef unsigned int UHItype    __attribute__ ((mode (HI)));
102 #if UNITS_PER_WORD > 1
103 /* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
104 typedef          int SItype     __attribute__ ((mode (SI)));
105 typedef unsigned int USItype    __attribute__ ((mode (SI)));
106 #if UNITS_PER_WORD > 2
107 /* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
108 typedef          int DItype     __attribute__ ((mode (DI)));
109 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
110 #endif
111 #endif
112
113 #if BITS_PER_UNIT == 8
114
115 typedef         float SFtype    __attribute__ ((mode (SF)));
116 typedef         float DFtype    __attribute__ ((mode (DF)));
117
118 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
119 typedef         float XFtype    __attribute__ ((mode (XF)));
120 #endif
121 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
122 typedef         float TFtype    __attribute__ ((mode (TF)));
123 #endif
124
125 #else /* BITS_PER_UNIT != 8 */
126
127 /* On dsp's there are usually qf/hf/tqf modes used instead of the above.
128    For now we don't support them in libgcc2.c.  */
129
130 #undef L_fixdfdi
131 #undef L_fixsfdi
132 #undef L_fixtfdi
133 #undef L_fixunsdfdi
134 #undef L_fixunsdfsi
135 #undef L_fixunssfdi
136 #undef L_fixunssfsi
137 #undef L_fixunstfdi
138 #undef L_fixunsxfdi
139 #undef L_fixunsxfsi
140 #undef L_fixxfdi
141 #undef L_floatdidf
142 #undef L_floatdisf
143 #undef L_floatditf
144 #undef L_floatdixf
145
146 #endif /* BITS_PER_UNIT != 8 */
147
148 typedef int word_type __attribute__ ((mode (__word__)));
149
150 /* Make sure that we don't accidentally use any normal C language built-in
151    type names in the first part of this file.  Instead we want to use *only*
152    the type names defined above.  The following macro definitions insure
153    that if we *do* accidentally use some normal C language built-in type name,
154    we will get a syntax error.  */
155
156 #define char bogus_type
157 #define short bogus_type
158 #define int bogus_type
159 #define long bogus_type
160 #define unsigned bogus_type
161 #define float bogus_type
162 #define double bogus_type
163
164 #if UNITS_PER_WORD > 2
165 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
166 #define Wtype   SItype
167 #define UWtype  USItype
168 #define HWtype  SItype
169 #define UHWtype USItype
170 #define DWtype  DItype
171 #define UDWtype UDItype
172 #define __NW(a,b)       __ ## a ## si ## b
173 #define __NDW(a,b)      __ ## a ## di ## b
174 #elif UNITS_PER_WORD > 1
175 #define W_TYPE_SIZE (2 * BITS_PER_UNIT)
176 #define Wtype   HItype
177 #define UWtype  UHItype
178 #define HWtype  HItype
179 #define UHWtype UHItype
180 #define DWtype  SItype
181 #define UDWtype USItype
182 #define __NW(a,b)       __ ## a ## hi ## b
183 #define __NDW(a,b)      __ ## a ## si ## b
184 #else
185 #define W_TYPE_SIZE BITS_PER_UNIT
186 #define Wtype   QItype
187 #define UWtype  UQItype
188 #define HWtype  QItype
189 #define UHWtype UQItype
190 #define DWtype  HItype
191 #define UDWtype UHItype
192 #define __NW(a,b)       __ ## a ## qi ## b
193 #define __NDW(a,b)      __ ## a ## hi ## b
194 #endif
195
196 #define __muldi3        __NDW(mul,3)
197 #define __divdi3        __NDW(div,3)
198 #define __udivdi3       __NDW(udiv,3)
199 #define __moddi3        __NDW(mod,3)
200 #define __umoddi3       __NDW(umod,3)
201 #define __negdi2        __NDW(neg,2)
202 #define __lshrdi3       __NDW(lshr,3)
203 #define __ashldi3       __NDW(ashl,3)
204 #define __ashrdi3       __NDW(ashr,3)
205 #define __ffsdi2        __NDW(ffs,2)
206 #define __cmpdi2        __NDW(cmp,2)
207 #define __ucmpdi2       __NDW(ucmp,2)
208 #define __udivmoddi4    __NDW(udivmod,4)
209 #define __fixunstfdi    __NDW(fixunstf,)
210 #define __fixtfdi       __NDW(fixtf,)
211 #define __fixunsxfdi    __NDW(fixunsxf,)
212 #define __fixxfdi       __NDW(fixxf,)
213 #define __fixunsdfdi    __NDW(fixunsdf,)
214 #define __fixdfdi       __NDW(fixdf,)
215 #define __fixunssfdi    __NDW(fixunssf,)
216 #define __fixsfdi       __NDW(fixsf,)
217 #define __floatdixf     __NDW(float,xf)
218 #define __floatditf     __NDW(float,tf)
219 #define __floatdidf     __NDW(float,df)
220 #define __floatdisf     __NDW(float,sf)
221 #define __fixunsxfsi    __NW(fixunsxf,)
222 #define __fixunstfsi    __NW(fixunstf,)
223 #define __fixunsdfsi    __NW(fixunsdf,)
224 #define __fixunssfsi    __NW(fixunssf,)
225
226 /* DWstructs are pairs of Wtype values in the order determined by
227    LIBGCC2_WORDS_BIG_ENDIAN.  */
228
229 #if LIBGCC2_WORDS_BIG_ENDIAN
230   struct DWstruct {Wtype high, low;};
231 #else
232   struct DWstruct {Wtype low, high;};
233 #endif
234
235 /* We need this union to unpack/pack DImode values, since we don't have
236    any arithmetic yet.  Incoming DImode parameters are stored into the
237    `ll' field, and the unpacked result is read from the struct `s'.  */
238
239 typedef union
240 {
241   struct DWstruct s;
242   DWtype ll;
243 } DWunion;
244
245 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
246      || defined (L_divdi3) || defined (L_udivdi3) \
247      || defined (L_moddi3) || defined (L_umoddi3))
248
249 #include "longlong.h"
250
251 #endif /* udiv or mul */
252
253 \f
254 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
255 #if defined (L_divdi3) || defined (L_moddi3)
256 static inline
257 #endif
258 DWtype
259 __negdi2 (DWtype u)
260 {
261   DWunion w;
262   DWunion uu;
263
264   uu.ll = u;
265
266   w.s.low = -uu.s.low;
267   w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
268
269   return w.ll;
270 }
271 #endif
272 \f
273 /* Unless shift functions are defined whith full ANSI prototypes,
274    parameter b will be promoted to int if word_type is smaller than an int.  */
275 #ifdef L_lshrdi3
276 DWtype
277 __lshrdi3 (DWtype u, word_type b)
278 {
279   DWunion w;
280   word_type bm;
281   DWunion uu;
282
283   if (b == 0)
284     return u;
285
286   uu.ll = u;
287
288   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
289   if (bm <= 0)
290     {
291       w.s.high = 0;
292       w.s.low = (UWtype)uu.s.high >> -bm;
293     }
294   else
295     {
296       UWtype carries = (UWtype)uu.s.high << bm;
297       w.s.high = (UWtype)uu.s.high >> b;
298       w.s.low = ((UWtype)uu.s.low >> b) | carries;
299     }
300
301   return w.ll;
302 }
303 #endif
304
305 #ifdef L_ashldi3
306 DWtype
307 __ashldi3 (DWtype u, word_type b)
308 {
309   DWunion w;
310   word_type bm;
311   DWunion uu;
312
313   if (b == 0)
314     return u;
315
316   uu.ll = u;
317
318   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
319   if (bm <= 0)
320     {
321       w.s.low = 0;
322       w.s.high = (UWtype)uu.s.low << -bm;
323     }
324   else
325     {
326       UWtype carries = (UWtype)uu.s.low >> bm;
327       w.s.low = (UWtype)uu.s.low << b;
328       w.s.high = ((UWtype)uu.s.high << b) | carries;
329     }
330
331   return w.ll;
332 }
333 #endif
334
335 #ifdef L_ashrdi3
336 DWtype
337 __ashrdi3 (DWtype u, word_type b)
338 {
339   DWunion w;
340   word_type bm;
341   DWunion uu;
342
343   if (b == 0)
344     return u;
345
346   uu.ll = u;
347
348   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
349   if (bm <= 0)
350     {
351       /* w.s.high = 1..1 or 0..0 */
352       w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
353       w.s.low = uu.s.high >> -bm;
354     }
355   else
356     {
357       UWtype carries = (UWtype)uu.s.high << bm;
358       w.s.high = uu.s.high >> b;
359       w.s.low = ((UWtype)uu.s.low >> b) | carries;
360     }
361
362   return w.ll;
363 }
364 #endif
365 \f
366 #ifdef L_ffsdi2
367 DWtype
368 __ffsdi2 (DWtype u)
369 {
370   DWunion uu, w;
371   uu.ll = u;
372   w.s.high = 0;
373   w.s.low = ffs (uu.s.low);
374   if (w.s.low != 0)
375     return w.ll;
376   w.s.low = ffs (uu.s.high);
377   if (w.s.low != 0)
378     {
379       w.s.low += BITS_PER_UNIT * sizeof (Wtype);
380       return w.ll;
381     }
382   return w.ll;
383 }
384 #endif
385 \f
386 #ifdef L_muldi3
387 DWtype
388 __muldi3 (DWtype u, DWtype v)
389 {
390   DWunion w;
391   DWunion uu, vv;
392
393   uu.ll = u,
394   vv.ll = v;
395
396   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
397   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
398                + (UWtype) uu.s.high * (UWtype) vv.s.low);
399
400   return w.ll;
401 }
402 #endif
403 \f
404 #ifdef L_udiv_w_sdiv
405 #if defined (sdiv_qrnnd)
406 UWtype
407 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
408 {
409   UWtype q, r;
410   UWtype c0, c1, b1;
411
412   if ((Wtype) d >= 0)
413     {
414       if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
415         {
416           /* dividend, divisor, and quotient are nonnegative */
417           sdiv_qrnnd (q, r, a1, a0, d);
418         }
419       else
420         {
421           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
422           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
423           /* Divide (c1*2^32 + c0) by d */
424           sdiv_qrnnd (q, r, c1, c0, d);
425           /* Add 2^31 to quotient */
426           q += (UWtype) 1 << (W_TYPE_SIZE - 1);
427         }
428     }
429   else
430     {
431       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
432       c1 = a1 >> 1;                     /* A/2 */
433       c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
434
435       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
436         {
437           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
438
439           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
440           if ((d & 1) != 0)
441             {
442               if (r >= q)
443                 r = r - q;
444               else if (q - r <= d)
445                 {
446                   r = r - q + d;
447                   q--;
448                 }
449               else
450                 {
451                   r = r - q + 2*d;
452                   q -= 2;
453                 }
454             }
455         }
456       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
457         {
458           c1 = (b1 - 1) - c1;
459           c0 = ~c0;                     /* logical NOT */
460
461           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
462
463           q = ~q;                       /* (A/2)/b1 */
464           r = (b1 - 1) - r;
465
466           r = 2*r + (a0 & 1);           /* A/(2*b1) */
467
468           if ((d & 1) != 0)
469             {
470               if (r >= q)
471                 r = r - q;
472               else if (q - r <= d)
473                 {
474                   r = r - q + d;
475                   q--;
476                 }
477               else
478                 {
479                   r = r - q + 2*d;
480                   q -= 2;
481                 }
482             }
483         }
484       else                              /* Implies c1 = b1 */
485         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
486           if (a0 >= -d)
487             {
488               q = -1;
489               r = a0 + d;
490             }
491           else
492             {
493               q = -2;
494               r = a0 + 2*d;
495             }
496         }
497     }
498
499   *rp = r;
500   return q;
501 }
502 #else
503 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
504 UWtype
505 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
506                UWtype a1 __attribute__ ((__unused__)),
507                UWtype a0 __attribute__ ((__unused__)),
508                UWtype d __attribute__ ((__unused__)))
509 {
510   return 0;
511 }
512 #endif
513 #endif
514 \f
515 #if (defined (L_udivdi3) || defined (L_divdi3) || \
516      defined (L_umoddi3) || defined (L_moddi3))
517 #define L_udivmoddi4
518 #endif
519
520 #ifdef L_udivmoddi4
521 static const UQItype __clz_tab[] =
522 {
523   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,
524   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,
525   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,
526   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,
527   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,
528   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,
529   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,
530   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,
531 };
532
533 #if (defined (L_udivdi3) || defined (L_divdi3) || \
534      defined (L_umoddi3) || defined (L_moddi3))
535 static inline
536 #endif
537 UDWtype
538 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
539 {
540   DWunion ww;
541   DWunion nn, dd;
542   DWunion rr;
543   UWtype d0, d1, n0, n1, n2;
544   UWtype q0, q1;
545   UWtype b, bm;
546
547   nn.ll = n;
548   dd.ll = d;
549
550   d0 = dd.s.low;
551   d1 = dd.s.high;
552   n0 = nn.s.low;
553   n1 = nn.s.high;
554
555 #if !UDIV_NEEDS_NORMALIZATION
556   if (d1 == 0)
557     {
558       if (d0 > n1)
559         {
560           /* 0q = nn / 0D */
561
562           udiv_qrnnd (q0, n0, n1, n0, d0);
563           q1 = 0;
564
565           /* Remainder in n0.  */
566         }
567       else
568         {
569           /* qq = NN / 0d */
570
571           if (d0 == 0)
572             d0 = 1 / d0;        /* Divide intentionally by zero.  */
573
574           udiv_qrnnd (q1, n1, 0, n1, d0);
575           udiv_qrnnd (q0, n0, n1, n0, d0);
576
577           /* Remainder in n0.  */
578         }
579
580       if (rp != 0)
581         {
582           rr.s.low = n0;
583           rr.s.high = 0;
584           *rp = rr.ll;
585         }
586     }
587
588 #else /* UDIV_NEEDS_NORMALIZATION */
589
590   if (d1 == 0)
591     {
592       if (d0 > n1)
593         {
594           /* 0q = nn / 0D */
595
596           count_leading_zeros (bm, d0);
597
598           if (bm != 0)
599             {
600               /* Normalize, i.e. make the most significant bit of the
601                  denominator set.  */
602
603               d0 = d0 << bm;
604               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
605               n0 = n0 << bm;
606             }
607
608           udiv_qrnnd (q0, n0, n1, n0, d0);
609           q1 = 0;
610
611           /* Remainder in n0 >> bm.  */
612         }
613       else
614         {
615           /* qq = NN / 0d */
616
617           if (d0 == 0)
618             d0 = 1 / d0;        /* Divide intentionally by zero.  */
619
620           count_leading_zeros (bm, d0);
621
622           if (bm == 0)
623             {
624               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
625                  conclude (the most significant bit of n1 is set) /\ (the
626                  leading quotient digit q1 = 1).
627
628                  This special case is necessary, not an optimization.
629                  (Shifts counts of W_TYPE_SIZE are undefined.)  */
630
631               n1 -= d0;
632               q1 = 1;
633             }
634           else
635             {
636               /* Normalize.  */
637
638               b = W_TYPE_SIZE - bm;
639
640               d0 = d0 << bm;
641               n2 = n1 >> b;
642               n1 = (n1 << bm) | (n0 >> b);
643               n0 = n0 << bm;
644
645               udiv_qrnnd (q1, n1, n2, n1, d0);
646             }
647
648           /* n1 != d0...  */
649
650           udiv_qrnnd (q0, n0, n1, n0, d0);
651
652           /* Remainder in n0 >> bm.  */
653         }
654
655       if (rp != 0)
656         {
657           rr.s.low = n0 >> bm;
658           rr.s.high = 0;
659           *rp = rr.ll;
660         }
661     }
662 #endif /* UDIV_NEEDS_NORMALIZATION */
663
664   else
665     {
666       if (d1 > n1)
667         {
668           /* 00 = nn / DD */
669
670           q0 = 0;
671           q1 = 0;
672
673           /* Remainder in n1n0.  */
674           if (rp != 0)
675             {
676               rr.s.low = n0;
677               rr.s.high = n1;
678               *rp = rr.ll;
679             }
680         }
681       else
682         {
683           /* 0q = NN / dd */
684
685           count_leading_zeros (bm, d1);
686           if (bm == 0)
687             {
688               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
689                  conclude (the most significant bit of n1 is set) /\ (the
690                  quotient digit q0 = 0 or 1).
691
692                  This special case is necessary, not an optimization.  */
693
694               /* The condition on the next line takes advantage of that
695                  n1 >= d1 (true due to program flow).  */
696               if (n1 > d1 || n0 >= d0)
697                 {
698                   q0 = 1;
699                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
700                 }
701               else
702                 q0 = 0;
703
704               q1 = 0;
705
706               if (rp != 0)
707                 {
708                   rr.s.low = n0;
709                   rr.s.high = n1;
710                   *rp = rr.ll;
711                 }
712             }
713           else
714             {
715               UWtype m1, m0;
716               /* Normalize.  */
717
718               b = W_TYPE_SIZE - bm;
719
720               d1 = (d1 << bm) | (d0 >> b);
721               d0 = d0 << bm;
722               n2 = n1 >> b;
723               n1 = (n1 << bm) | (n0 >> b);
724               n0 = n0 << bm;
725
726               udiv_qrnnd (q0, n1, n2, n1, d1);
727               umul_ppmm (m1, m0, q0, d0);
728
729               if (m1 > n1 || (m1 == n1 && m0 > n0))
730                 {
731                   q0--;
732                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
733                 }
734
735               q1 = 0;
736
737               /* Remainder in (n1n0 - m1m0) >> bm.  */
738               if (rp != 0)
739                 {
740                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
741                   rr.s.low = (n1 << b) | (n0 >> bm);
742                   rr.s.high = n1 >> bm;
743                   *rp = rr.ll;
744                 }
745             }
746         }
747     }
748
749   ww.s.low = q0;
750   ww.s.high = q1;
751   return ww.ll;
752 }
753 #endif
754
755 #ifdef L_divdi3
756 DWtype
757 __divdi3 (DWtype u, DWtype v)
758 {
759   word_type c = 0;
760   DWunion uu, vv;
761   DWtype w;
762
763   uu.ll = u;
764   vv.ll = v;
765
766   if (uu.s.high < 0)
767     c = ~c,
768     uu.ll = __negdi2 (uu.ll);
769   if (vv.s.high < 0)
770     c = ~c,
771     vv.ll = __negdi2 (vv.ll);
772
773   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
774   if (c)
775     w = __negdi2 (w);
776
777   return w;
778 }
779 #endif
780
781 #ifdef L_moddi3
782 DWtype
783 __moddi3 (DWtype u, DWtype v)
784 {
785   word_type c = 0;
786   DWunion uu, vv;
787   DWtype w;
788
789   uu.ll = u;
790   vv.ll = v;
791
792   if (uu.s.high < 0)
793     c = ~c,
794     uu.ll = __negdi2 (uu.ll);
795   if (vv.s.high < 0)
796     vv.ll = __negdi2 (vv.ll);
797
798   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
799   if (c)
800     w = __negdi2 (w);
801
802   return w;
803 }
804 #endif
805
806 #ifdef L_umoddi3
807 UDWtype
808 __umoddi3 (UDWtype u, UDWtype v)
809 {
810   UDWtype w;
811
812   (void) __udivmoddi4 (u, v, &w);
813
814   return w;
815 }
816 #endif
817
818 #ifdef L_udivdi3
819 UDWtype
820 __udivdi3 (UDWtype n, UDWtype d)
821 {
822   return __udivmoddi4 (n, d, (UDWtype *) 0);
823 }
824 #endif
825 \f
826 #ifdef L_cmpdi2
827 word_type
828 __cmpdi2 (DWtype a, DWtype b)
829 {
830   DWunion au, bu;
831
832   au.ll = a, bu.ll = b;
833
834   if (au.s.high < bu.s.high)
835     return 0;
836   else if (au.s.high > bu.s.high)
837     return 2;
838   if ((UWtype) au.s.low < (UWtype) bu.s.low)
839     return 0;
840   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
841     return 2;
842   return 1;
843 }
844 #endif
845
846 #ifdef L_ucmpdi2
847 word_type
848 __ucmpdi2 (DWtype a, DWtype b)
849 {
850   DWunion au, bu;
851
852   au.ll = a, bu.ll = b;
853
854   if ((UWtype) au.s.high < (UWtype) bu.s.high)
855     return 0;
856   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
857     return 2;
858   if ((UWtype) au.s.low < (UWtype) bu.s.low)
859     return 0;
860   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
861     return 2;
862   return 1;
863 }
864 #endif
865 \f
866 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
867 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
868 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
869
870 DWtype
871 __fixunstfdi (TFtype a)
872 {
873   TFtype b;
874   UDWtype v;
875
876   if (a < 0)
877     return 0;
878
879   /* Compute high word of result, as a flonum.  */
880   b = (a / HIGH_WORD_COEFF);
881   /* Convert that to fixed (but not to DWtype!),
882      and shift it into the high word.  */
883   v = (UWtype) b;
884   v <<= WORD_SIZE;
885   /* Remove high part from the TFtype, leaving the low part as flonum.  */
886   a -= (TFtype)v;
887   /* Convert that to fixed (but not to DWtype!) and add it in.
888      Sometimes A comes out negative.  This is significant, since
889      A has more bits than a long int does.  */
890   if (a < 0)
891     v -= (UWtype) (- a);
892   else
893     v += (UWtype) a;
894   return v;
895 }
896 #endif
897
898 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
899 extern DWtype __fixunstfdi (TFtype a);
900
901 DWtype
902 __fixtfdi (TFtype a)
903 {
904   if (a < 0)
905     return - __fixunstfdi (-a);
906   return __fixunstfdi (a);
907 }
908 #endif
909
910 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
911 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
912 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
913
914 DWtype
915 __fixunsxfdi (XFtype a)
916 {
917   XFtype b;
918   UDWtype v;
919
920   if (a < 0)
921     return 0;
922
923   /* Compute high word of result, as a flonum.  */
924   b = (a / HIGH_WORD_COEFF);
925   /* Convert that to fixed (but not to DWtype!),
926      and shift it into the high word.  */
927   v = (UWtype) b;
928   v <<= WORD_SIZE;
929   /* Remove high part from the XFtype, leaving the low part as flonum.  */
930   a -= (XFtype)v;
931   /* Convert that to fixed (but not to DWtype!) and add it in.
932      Sometimes A comes out negative.  This is significant, since
933      A has more bits than a long int does.  */
934   if (a < 0)
935     v -= (UWtype) (- a);
936   else
937     v += (UWtype) a;
938   return v;
939 }
940 #endif
941
942 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
943 extern DWtype __fixunsxfdi (XFtype a);
944
945 DWtype
946 __fixxfdi (XFtype a)
947 {
948   if (a < 0)
949     return - __fixunsxfdi (-a);
950   return __fixunsxfdi (a);
951 }
952 #endif
953
954 #ifdef L_fixunsdfdi
955 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
956 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
957
958 DWtype
959 __fixunsdfdi (DFtype a)
960 {
961   DFtype b;
962   UDWtype v;
963
964   if (a < 0)
965     return 0;
966
967   /* Compute high word of result, as a flonum.  */
968   b = (a / HIGH_WORD_COEFF);
969   /* Convert that to fixed (but not to DWtype!),
970      and shift it into the high word.  */
971   v = (UWtype) b;
972   v <<= WORD_SIZE;
973   /* Remove high part from the DFtype, leaving the low part as flonum.  */
974   a -= (DFtype)v;
975   /* Convert that to fixed (but not to DWtype!) and add it in.
976      Sometimes A comes out negative.  This is significant, since
977      A has more bits than a long int does.  */
978   if (a < 0)
979     v -= (UWtype) (- a);
980   else
981     v += (UWtype) a;
982   return v;
983 }
984 #endif
985
986 #ifdef L_fixdfdi
987 extern DWtype __fixunsdfdi (DFtype a);
988
989 DWtype
990 __fixdfdi (DFtype a)
991 {
992   if (a < 0)
993     return - __fixunsdfdi (-a);
994   return __fixunsdfdi (a);
995 }
996 #endif
997
998 #ifdef L_fixunssfdi
999 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1000 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1001
1002 DWtype
1003 __fixunssfdi (SFtype original_a)
1004 {
1005   /* Convert the SFtype to a DFtype, because that is surely not going
1006      to lose any bits.  Some day someone else can write a faster version
1007      that avoids converting to DFtype, and verify it really works right.  */
1008   DFtype a = original_a;
1009   DFtype b;
1010   UDWtype v;
1011
1012   if (a < 0)
1013     return 0;
1014
1015   /* Compute high word of result, as a flonum.  */
1016   b = (a / HIGH_WORD_COEFF);
1017   /* Convert that to fixed (but not to DWtype!),
1018      and shift it into the high word.  */
1019   v = (UWtype) b;
1020   v <<= WORD_SIZE;
1021   /* Remove high part from the DFtype, leaving the low part as flonum.  */
1022   a -= (DFtype)v;
1023   /* Convert that to fixed (but not to DWtype!) and add it in.
1024      Sometimes A comes out negative.  This is significant, since
1025      A has more bits than a long int does.  */
1026   if (a < 0)
1027     v -= (UWtype) (- a);
1028   else
1029     v += (UWtype) a;
1030   return v;
1031 }
1032 #endif
1033
1034 #ifdef L_fixsfdi
1035 extern DWtype __fixunssfdi (SFtype a);
1036
1037 DWtype
1038 __fixsfdi (SFtype a)
1039 {
1040   if (a < 0)
1041     return - __fixunssfdi (-a);
1042   return __fixunssfdi (a);
1043 }
1044 #endif
1045
1046 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1047 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1048 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1049 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1050
1051 XFtype
1052 __floatdixf (DWtype u)
1053 {
1054   XFtype d;
1055
1056   d = (Wtype) (u >> WORD_SIZE);
1057   d *= HIGH_HALFWORD_COEFF;
1058   d *= HIGH_HALFWORD_COEFF;
1059   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1060
1061   return d;
1062 }
1063 #endif
1064
1065 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1066 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1067 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1068 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1069
1070 TFtype
1071 __floatditf (DWtype u)
1072 {
1073   TFtype d;
1074
1075   d = (Wtype) (u >> WORD_SIZE);
1076   d *= HIGH_HALFWORD_COEFF;
1077   d *= HIGH_HALFWORD_COEFF;
1078   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1079
1080   return d;
1081 }
1082 #endif
1083
1084 #ifdef L_floatdidf
1085 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1086 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1087 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1088
1089 DFtype
1090 __floatdidf (DWtype u)
1091 {
1092   DFtype d;
1093
1094   d = (Wtype) (u >> WORD_SIZE);
1095   d *= HIGH_HALFWORD_COEFF;
1096   d *= HIGH_HALFWORD_COEFF;
1097   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1098
1099   return d;
1100 }
1101 #endif
1102
1103 #ifdef L_floatdisf
1104 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1105 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1106 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1107 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1108
1109 /* Define codes for all the float formats that we know of.  Note
1110    that this is copied from real.h.  */
1111    
1112 #define UNKNOWN_FLOAT_FORMAT 0
1113 #define IEEE_FLOAT_FORMAT 1
1114 #define VAX_FLOAT_FORMAT 2
1115 #define IBM_FLOAT_FORMAT 3
1116
1117 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1118 #ifndef HOST_FLOAT_FORMAT
1119 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1120 #endif
1121
1122 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1123 #define DF_SIZE 53
1124 #define SF_SIZE 24
1125 #endif
1126
1127 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1128 #define DF_SIZE 56
1129 #define SF_SIZE 24
1130 #endif
1131
1132 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1133 #define DF_SIZE 56
1134 #define SF_SIZE 24
1135 #endif
1136
1137 SFtype
1138 __floatdisf (DWtype u)
1139 {
1140   /* Do the calculation in DFmode
1141      so that we don't lose any of the precision of the high word
1142      while multiplying it.  */
1143   DFtype f;
1144
1145   /* Protect against double-rounding error.
1146      Represent any low-order bits, that might be truncated in DFmode,
1147      by a bit that won't be lost.  The bit can go in anywhere below the
1148      rounding position of the SFmode.  A fixed mask and bit position
1149      handles all usual configurations.  It doesn't handle the case
1150      of 128-bit DImode, however.  */
1151   if (DF_SIZE < DI_SIZE
1152       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1153     {
1154 #define REP_BIT ((UWtype) 1 << (DI_SIZE - DF_SIZE))
1155       if (! (- ((DWtype) 1 << DF_SIZE) < u
1156              && u < ((DWtype) 1 << DF_SIZE)))
1157         {
1158           if ((UWtype) u & (REP_BIT - 1))
1159             u |= REP_BIT;
1160         }
1161     }
1162   f = (Wtype) (u >> WORD_SIZE);
1163   f *= HIGH_HALFWORD_COEFF;
1164   f *= HIGH_HALFWORD_COEFF;
1165   f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1166
1167   return (SFtype) f;
1168 }
1169 #endif
1170
1171 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1172 /* Reenable the normal types, in case limits.h needs them.  */
1173 #undef char
1174 #undef short
1175 #undef int
1176 #undef long
1177 #undef unsigned
1178 #undef float
1179 #undef double
1180 #undef MIN
1181 #undef MAX
1182 #include <limits.h>
1183
1184 UWtype
1185 __fixunsxfsi (XFtype a)
1186 {
1187   if (a >= - (DFtype) LONG_MIN)
1188     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1189   return (Wtype) a;
1190 }
1191 #endif
1192
1193 #ifdef L_fixunsdfsi
1194 /* Reenable the normal types, in case limits.h needs them.  */
1195 #undef char
1196 #undef short
1197 #undef int
1198 #undef long
1199 #undef unsigned
1200 #undef float
1201 #undef double
1202 #undef MIN
1203 #undef MAX
1204 #include <limits.h>
1205
1206 UWtype
1207 __fixunsdfsi (DFtype a)
1208 {
1209   if (a >= - (DFtype) LONG_MIN)
1210     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1211   return (Wtype) a;
1212 }
1213 #endif
1214
1215 #ifdef L_fixunssfsi
1216 /* Reenable the normal types, in case limits.h needs them.  */
1217 #undef char
1218 #undef short
1219 #undef int
1220 #undef long
1221 #undef unsigned
1222 #undef float
1223 #undef double
1224 #undef MIN
1225 #undef MAX
1226 #include <limits.h>
1227
1228 UWtype
1229 __fixunssfsi (SFtype a)
1230 {
1231   if (a >= - (SFtype) LONG_MIN)
1232     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1233   return (Wtype) a;
1234 }
1235 #endif
1236 \f
1237 /* From here on down, the routines use normal data types.  */
1238
1239 #define SItype bogus_type
1240 #define USItype bogus_type
1241 #define DItype bogus_type
1242 #define UDItype bogus_type
1243 #define SFtype bogus_type
1244 #define DFtype bogus_type
1245 #undef Wtype
1246 #undef UWtype
1247 #undef HWtype
1248 #undef UHWtype
1249 #undef DWtype
1250 #undef UDWtype
1251
1252 #undef char
1253 #undef short
1254 #undef int
1255 #undef long
1256 #undef unsigned
1257 #undef float
1258 #undef double
1259 \f
1260 #ifdef L__gcc_bcmp
1261
1262 /* Like bcmp except the sign is meaningful.
1263    Result is negative if S1 is less than S2,
1264    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1265
1266 int
1267 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1268 {
1269   while (size > 0)
1270     {
1271       unsigned char c1 = *s1++, c2 = *s2++;
1272       if (c1 != c2)
1273         return c1 - c2;
1274       size--;
1275     }
1276   return 0;
1277 }
1278
1279 #endif
1280 \f\f
1281 #ifdef L__dummy
1282 void
1283 __dummy (void) {}
1284 #endif
1285
1286 #ifdef L_varargs
1287 #ifdef __i860__
1288 #if defined(__svr4__) || defined(__alliant__)
1289         asm ("  .text");
1290         asm ("  .align  4");
1291
1292 /* The Alliant needs the added underscore.  */
1293         asm (".globl    __builtin_saveregs");
1294 asm ("__builtin_saveregs:");
1295         asm (".globl    ___builtin_saveregs");
1296 asm ("___builtin_saveregs:");
1297
1298         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1299         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1300                                            area and also for a new va_list
1301                                            structure */
1302         /* Save all argument registers in the arg reg save area.  The
1303            arg reg save area must have the following layout (according
1304            to the svr4 ABI):
1305
1306                 struct {
1307                   union  {
1308                     float freg[8];
1309                     double dreg[4];
1310                   } float_regs;
1311                   long  ireg[12];
1312                 };
1313         */
1314
1315         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1316         asm ("  fst.q   %f12,16(%sp)"); 
1317
1318         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1319         asm ("  st.l    %r17,36(%sp)"); 
1320         asm ("  st.l    %r18,40(%sp)");
1321         asm ("  st.l    %r19,44(%sp)");
1322         asm ("  st.l    %r20,48(%sp)");
1323         asm ("  st.l    %r21,52(%sp)");
1324         asm ("  st.l    %r22,56(%sp)");
1325         asm ("  st.l    %r23,60(%sp)");
1326         asm ("  st.l    %r24,64(%sp)");
1327         asm ("  st.l    %r25,68(%sp)");
1328         asm ("  st.l    %r26,72(%sp)");
1329         asm ("  st.l    %r27,76(%sp)");
1330
1331         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1332                                            va_list structure.  Put in into
1333                                            r16 so that it will be returned
1334                                            to the caller.  */
1335
1336         /* Initialize all fields of the new va_list structure.  This
1337            structure looks like:
1338
1339                 typedef struct {
1340                     unsigned long       ireg_used;
1341                     unsigned long       freg_used;
1342                     long                *reg_base;
1343                     long                *mem_ptr;
1344                 } va_list;
1345         */
1346
1347         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1348         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1349         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1350         asm ("  bri     %r1");          /* delayed return */
1351         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1352
1353 #else /* not __svr4__ */
1354 #if defined(__PARAGON__)
1355         /*
1356          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1357          *      and we stand a better chance of hooking into libraries
1358          *      compiled by PGI.  [andyp@ssd.intel.com]
1359          */
1360         asm ("  .text");
1361         asm ("  .align  4");
1362         asm (".globl    __builtin_saveregs");
1363 asm ("__builtin_saveregs:");
1364         asm (".globl    ___builtin_saveregs");
1365 asm ("___builtin_saveregs:");
1366
1367         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1368         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1369                                            area and also for a new va_list
1370                                            structure */
1371         /* Save all argument registers in the arg reg save area.  The
1372            arg reg save area must have the following layout (according
1373            to the svr4 ABI):
1374
1375                 struct {
1376                   union  {
1377                     float freg[8];
1378                     double dreg[4];
1379                   } float_regs;
1380                   long  ireg[12];
1381                 };
1382         */
1383
1384         asm ("  fst.q   f8,  0(sp)");
1385         asm ("  fst.q   f12,16(sp)"); 
1386         asm ("  st.l    r16,32(sp)");
1387         asm ("  st.l    r17,36(sp)"); 
1388         asm ("  st.l    r18,40(sp)");
1389         asm ("  st.l    r19,44(sp)");
1390         asm ("  st.l    r20,48(sp)");
1391         asm ("  st.l    r21,52(sp)");
1392         asm ("  st.l    r22,56(sp)");
1393         asm ("  st.l    r23,60(sp)");
1394         asm ("  st.l    r24,64(sp)");
1395         asm ("  st.l    r25,68(sp)");
1396         asm ("  st.l    r26,72(sp)");
1397         asm ("  st.l    r27,76(sp)");
1398
1399         asm ("  adds    80,sp,r16");  /* compute the address of the new
1400                                            va_list structure.  Put in into
1401                                            r16 so that it will be returned
1402                                            to the caller.  */
1403
1404         /* Initialize all fields of the new va_list structure.  This
1405            structure looks like:
1406
1407                 typedef struct {
1408                     unsigned long       ireg_used;
1409                     unsigned long       freg_used;
1410                     long                *reg_base;
1411                     long                *mem_ptr;
1412                 } va_list;
1413         */
1414
1415         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1416         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1417         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1418         asm ("  bri     r1");           /* delayed return */
1419         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1420 #else /* not __PARAGON__ */
1421         asm ("  .text");
1422         asm ("  .align  4");
1423
1424         asm (".globl    ___builtin_saveregs");
1425         asm ("___builtin_saveregs:");
1426         asm ("  mov     sp,r30");
1427         asm ("  andnot  0x0f,sp,sp");
1428         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1429
1430 /* Fill in the __va_struct.  */
1431         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1432         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1433         asm ("  st.l    r18, 8(sp)");
1434         asm ("  st.l    r19,12(sp)");
1435         asm ("  st.l    r20,16(sp)");
1436         asm ("  st.l    r21,20(sp)");
1437         asm ("  st.l    r22,24(sp)");
1438         asm ("  st.l    r23,28(sp)");
1439         asm ("  st.l    r24,32(sp)");
1440         asm ("  st.l    r25,36(sp)");
1441         asm ("  st.l    r26,40(sp)");
1442         asm ("  st.l    r27,44(sp)");
1443
1444         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1445         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1446
1447 /* Fill in the __va_ctl.  */
1448         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1449         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1450         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1451         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1452
1453         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1454         asm ("  bri     r1");
1455         asm ("  mov     r30,sp");
1456                                 /* recover stack and pass address to start 
1457                                    of data.  */
1458 #endif /* not __PARAGON__ */
1459 #endif /* not __svr4__ */
1460 #else /* not __i860__ */
1461 #ifdef __sparc__
1462         asm (".global __builtin_saveregs");
1463         asm ("__builtin_saveregs:");
1464         asm (".global ___builtin_saveregs");
1465         asm ("___builtin_saveregs:");
1466 #ifdef NEED_PROC_COMMAND
1467         asm (".proc 020");
1468 #endif
1469         asm ("st %i0,[%fp+68]");
1470         asm ("st %i1,[%fp+72]");
1471         asm ("st %i2,[%fp+76]");
1472         asm ("st %i3,[%fp+80]");
1473         asm ("st %i4,[%fp+84]");
1474         asm ("retl");
1475         asm ("st %i5,[%fp+88]");
1476 #ifdef NEED_TYPE_COMMAND
1477         asm (".type __builtin_saveregs,#function");
1478         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1479 #endif
1480 #else /* not __sparc__ */
1481 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1482
1483   asm ("        .text");
1484 #ifdef __mips16
1485   asm ("        .set nomips16");
1486 #endif
1487   asm ("        .ent __builtin_saveregs");
1488   asm ("        .globl __builtin_saveregs");
1489   asm ("__builtin_saveregs:");
1490   asm ("        sw      $4,0($30)");
1491   asm ("        sw      $5,4($30)");
1492   asm ("        sw      $6,8($30)");
1493   asm ("        sw      $7,12($30)");
1494   asm ("        j       $31");
1495   asm ("        .end __builtin_saveregs");
1496 #else /* not __mips__, etc.  */
1497
1498 void *
1499 __builtin_saveregs (void)
1500 {
1501   abort ();
1502 }
1503
1504 #endif /* not __mips__ */
1505 #endif /* not __sparc__ */
1506 #endif /* not __i860__ */
1507 #endif
1508 \f
1509 #ifdef L_eprintf
1510 #ifndef inhibit_libc
1511
1512 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1513 #include <stdio.h>
1514 /* This is used by the `assert' macro.  */
1515 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1516   __attribute__ ((__noreturn__));
1517
1518 void
1519 __eprintf (const char *string, const char *expression,
1520            unsigned int line, const char *filename)
1521 {
1522   fprintf (stderr, string, expression, line, filename);
1523   fflush (stderr);
1524   abort ();
1525 }
1526
1527 #endif
1528 #endif
1529
1530 #ifdef L_bb
1531
1532 /* Structure emitted by -a  */
1533 struct bb
1534 {
1535   long zero_word;
1536   const char *filename;
1537   long *counts;
1538   long ncounts;
1539   struct bb *next;
1540   const unsigned long *addresses;
1541
1542   /* Older GCC's did not emit these fields.  */
1543   long nwords;
1544   const char **functions;
1545   const long *line_nums;
1546   const char **filenames;
1547   char *flags;
1548 };
1549
1550 #ifdef BLOCK_PROFILER_CODE
1551 BLOCK_PROFILER_CODE
1552 #else
1553 #ifndef inhibit_libc
1554
1555 /* Simple minded basic block profiling output dumper for
1556    systems that don't provide tcov support.  At present,
1557    it requires atexit and stdio.  */
1558
1559 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1560 #include <stdio.h>
1561 char *ctime ();
1562
1563 #include "gbl-ctors.h"
1564 #include "gcov-io.h"
1565 #include <string.h>
1566
1567 static struct bb *bb_head;
1568
1569 static int num_digits (long value, int base) __attribute__ ((const));
1570
1571 /* Return the number of digits needed to print a value */
1572 /* __inline__ */ static int num_digits (long value, int base)
1573 {
1574   int minus = (value < 0 && base != 16);
1575   unsigned long v = (minus) ? -value : value;
1576   int ret = minus;
1577
1578   do
1579     {
1580       v /= base;
1581       ret++;
1582     }
1583   while (v);
1584
1585   return ret;
1586 }
1587
1588 void
1589 __bb_exit_func (void)
1590 {
1591   FILE *da_file, *file;
1592   long time_value;
1593   int i;
1594
1595   if (bb_head == 0)
1596     return;
1597
1598   i = strlen (bb_head->filename) - 3;
1599
1600   if (!strcmp (bb_head->filename+i, ".da"))
1601     {
1602       /* Must be -fprofile-arcs not -a.
1603          Dump data in a form that gcov expects.  */
1604
1605       struct bb *ptr;
1606
1607       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1608         {
1609           /* If the file exists, and the number of counts in it is the same,
1610              then merge them in.  */
1611              
1612           if ((da_file = fopen (ptr->filename, "rb")) != 0)
1613             {
1614               long n_counts = 0;
1615               
1616               if (__read_long (&n_counts, da_file, 8) != 0)
1617                 {
1618                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1619                            ptr->filename);
1620                   continue;
1621                 }
1622
1623               if (n_counts == ptr->ncounts)
1624                 {
1625                   int i;
1626
1627                   for (i = 0; i < n_counts; i++)
1628                     {
1629                       long v = 0;
1630
1631                       if (__read_long (&v, da_file, 8) != 0)
1632                         {
1633                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1634                                    ptr->filename);
1635                           break;
1636                         }
1637                       ptr->counts[i] += v;
1638                     }
1639                 }
1640
1641               if (fclose (da_file) == EOF)
1642                 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1643                          ptr->filename);
1644             }
1645           if ((da_file = fopen (ptr->filename, "wb")) == 0)
1646             {
1647               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1648                        ptr->filename);
1649               continue;
1650             }
1651
1652           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1653              magic number, 4 bytes containing the time the program was
1654              compiled, 4 bytes containing the last modification time of the
1655              source file, and 4 bytes indicating the compiler options used.
1656
1657              That way we can easily verify that the proper source/executable/
1658              data file combination is being used from gcov.  */
1659
1660           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1661             {
1662               
1663               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1664                        ptr->filename);
1665             }
1666           else
1667             {
1668               int j;
1669               long *count_ptr = ptr->counts;
1670               int ret = 0;
1671               for (j = ptr->ncounts; j > 0; j--)
1672                 {
1673                   if (__write_long (*count_ptr, da_file, 8) != 0)
1674                     {
1675                       ret=1;
1676                       break;
1677                     }
1678                   count_ptr++;
1679                 }
1680               if (ret)
1681                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1682                          ptr->filename);
1683             }
1684           
1685           if (fclose (da_file) == EOF)
1686             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1687                      ptr->filename);
1688         }
1689
1690       return;
1691     }
1692
1693   /* Must be basic block profiling.  Emit a human readable output file.  */
1694
1695   file = fopen ("bb.out", "a");
1696
1697   if (!file)
1698     perror ("bb.out");
1699
1700   else
1701     {
1702       struct bb *ptr;
1703
1704       /* This is somewhat type incorrect, but it avoids worrying about
1705          exactly where time.h is included from.  It should be ok unless
1706          a void * differs from other pointer formats, or if sizeof (long)
1707          is < sizeof (time_t).  It would be nice if we could assume the
1708          use of rationale standards here.  */
1709
1710       time ((void *) &time_value);
1711       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1712
1713       /* We check the length field explicitly in order to allow compatibility
1714          with older GCC's which did not provide it.  */
1715
1716       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1717         {
1718           int i;
1719           int func_p    = (ptr->nwords >= (long) sizeof (struct bb)
1720                            && ptr->nwords <= 1000
1721                            && ptr->functions);
1722           int line_p    = (func_p && ptr->line_nums);
1723           int file_p    = (func_p && ptr->filenames);
1724           int addr_p    = (ptr->addresses != 0);
1725           long ncounts  = ptr->ncounts;
1726           long cnt_max  = 0;
1727           long line_max = 0;
1728           long addr_max = 0;
1729           int file_len  = 0;
1730           int func_len  = 0;
1731           int blk_len   = num_digits (ncounts, 10);
1732           int cnt_len;
1733           int line_len;
1734           int addr_len;
1735
1736           fprintf (file, "File %s, %ld basic blocks \n\n",
1737                    ptr->filename, ncounts);
1738
1739           /* Get max values for each field.  */
1740           for (i = 0; i < ncounts; i++)
1741             {
1742               const char *p;
1743               int len;
1744
1745               if (cnt_max < ptr->counts[i])
1746                 cnt_max = ptr->counts[i];
1747
1748               if (addr_p && (unsigned long) addr_max < ptr->addresses[i])
1749                 addr_max = ptr->addresses[i];
1750
1751               if (line_p && line_max < ptr->line_nums[i])
1752                 line_max = ptr->line_nums[i];
1753
1754               if (func_p)
1755                 {
1756                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1757                   len = strlen (p);
1758                   if (func_len < len)
1759                     func_len = len;
1760                 }
1761
1762               if (file_p)
1763                 {
1764                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1765                   len = strlen (p);
1766                   if (file_len < len)
1767                     file_len = len;
1768                 }
1769             }
1770
1771           addr_len = num_digits (addr_max, 16);
1772           cnt_len  = num_digits (cnt_max, 10);
1773           line_len = num_digits (line_max, 10);
1774
1775           /* Now print out the basic block information.  */
1776           for (i = 0; i < ncounts; i++)
1777             {
1778               fprintf (file,
1779                        "    Block #%*d: executed %*ld time(s)",
1780                        blk_len, i+1,
1781                        cnt_len, ptr->counts[i]);
1782
1783               if (addr_p)
1784                 fprintf (file, " address= 0x%.*lx", addr_len,
1785                          ptr->addresses[i]);
1786
1787               if (func_p)
1788                 fprintf (file, " function= %-*s", func_len,
1789                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1790
1791               if (line_p)
1792                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1793
1794               if (file_p)
1795                 fprintf (file, " file= %s",
1796                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1797
1798               fprintf (file, "\n");
1799             }
1800
1801           fprintf (file, "\n");
1802           fflush (file);
1803         }
1804
1805       fprintf (file, "\n\n");
1806       fclose (file);
1807     }
1808 }
1809
1810 void
1811 __bb_init_func (struct bb *blocks)
1812 {
1813   /* User is supposed to check whether the first word is non-0,
1814      but just in case....  */
1815
1816   if (blocks->zero_word)
1817     return;
1818
1819   /* Initialize destructor.  */
1820   if (!bb_head)
1821     atexit (__bb_exit_func);
1822
1823   /* Set up linked list.  */
1824   blocks->zero_word = 1;
1825   blocks->next = bb_head;
1826   bb_head = blocks;
1827 }
1828
1829 #ifndef MACHINE_STATE_SAVE
1830 #define MACHINE_STATE_SAVE(ID)
1831 #endif
1832 #ifndef MACHINE_STATE_RESTORE
1833 #define MACHINE_STATE_RESTORE(ID)
1834 #endif
1835
1836 /* Number of buckets in hashtable of basic block addresses.  */
1837
1838 #define BB_BUCKETS 311
1839
1840 /* Maximum length of string in file bb.in.  */
1841
1842 #define BBINBUFSIZE 500
1843
1844 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1845    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1846
1847 #define BBINBUFSIZESTR "499"
1848
1849 struct bb_edge
1850 {
1851   struct bb_edge *next;
1852   unsigned long src_addr;
1853   unsigned long dst_addr;
1854   unsigned long count;
1855 };
1856
1857 enum bb_func_mode
1858 {
1859   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1860 };
1861
1862 struct bb_func
1863 {
1864   struct bb_func *next;
1865   char *funcname;
1866   char *filename;
1867   enum bb_func_mode mode;
1868 };
1869
1870 /* This is the connection to the outside world.
1871    The BLOCK_PROFILER macro must set __bb.blocks
1872    and __bb.blockno.  */
1873
1874 struct {
1875   unsigned long blockno;
1876   struct bb *blocks;
1877 } __bb;
1878
1879 /* Vars to store addrs of source and destination basic blocks 
1880    of a jump.  */
1881
1882 static unsigned long bb_src = 0;
1883 static unsigned long bb_dst = 0;
1884
1885 static FILE *bb_tracefile = (FILE *) 0;
1886 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1887 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1888 static unsigned long bb_callcount = 0;
1889 static int bb_mode = 0;
1890
1891 static unsigned long *bb_stack = (unsigned long *) 0;
1892 static size_t bb_stacksize = 0;
1893
1894 static int reported = 0;
1895
1896 /* Trace modes:
1897 Always             :   Print execution frequencies of basic blocks
1898                        to file bb.out.
1899 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1900 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1901 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1902 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1903 */
1904
1905 #ifdef HAVE_POPEN
1906
1907 /*#include <sys/types.h>*/
1908 #include <sys/stat.h>
1909 /*#include <malloc.h>*/
1910
1911 /* Commands executed by gopen.  */
1912
1913 #define GOPENDECOMPRESS "gzip -cd "
1914 #define GOPENCOMPRESS "gzip -c >"
1915
1916 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1917    If it does not compile, simply replace gopen by fopen and delete
1918    '.gz' from any first parameter to gopen.  */
1919
1920 static FILE *
1921 gopen (char *fn, char *mode)
1922 {
1923   int use_gzip;
1924   char *p;
1925
1926   if (mode[1])
1927     return (FILE *) 0;
1928
1929   if (mode[0] != 'r' && mode[0] != 'w') 
1930     return (FILE *) 0;
1931
1932   p = fn + strlen (fn)-1;
1933   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1934               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1935
1936   if (use_gzip)
1937     {
1938       if (mode[0]=='r')
1939         {
1940           FILE *f;
1941           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1942                                      + sizeof (GOPENDECOMPRESS));
1943           strcpy (s, GOPENDECOMPRESS);
1944           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1945           f = popen (s, mode);
1946           free (s);
1947           return f;
1948         }
1949
1950       else
1951         {
1952           FILE *f;
1953           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1954                                      + sizeof (GOPENCOMPRESS));
1955           strcpy (s, GOPENCOMPRESS);
1956           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1957           if (!(f = popen (s, mode)))
1958             f = fopen (s, mode);
1959           free (s);
1960           return f;
1961         }
1962     }
1963
1964   else
1965     return fopen (fn, mode);
1966 }
1967
1968 static int
1969 gclose (FILE *f)
1970 {
1971   struct stat buf;
1972
1973   if (f != 0)
1974     {
1975       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1976         return pclose (f);
1977
1978       return fclose (f);
1979     }
1980   return 0;
1981 }
1982
1983 #endif /* HAVE_POPEN */
1984
1985 /* Called once per program.  */
1986
1987 static void
1988 __bb_exit_trace_func (void)
1989 {
1990   FILE *file = fopen ("bb.out", "a");
1991   struct bb_func *f;
1992   struct bb *b;
1993         
1994   if (!file)
1995     perror ("bb.out");
1996
1997   if (bb_mode & 1)
1998     {
1999       if (!bb_tracefile)
2000         perror ("bbtrace");
2001       else
2002 #ifdef HAVE_POPEN
2003         gclose (bb_tracefile);
2004 #else
2005         fclose (bb_tracefile);
2006 #endif /* HAVE_POPEN */
2007     }
2008
2009   /* Check functions in `bb.in'.  */
2010
2011   if (file)
2012     {
2013       long time_value;
2014       const struct bb_func *p;
2015       int printed_something = 0;
2016       struct bb *ptr;
2017       long blk;
2018
2019       /* This is somewhat type incorrect.  */
2020       time ((void *) &time_value);
2021
2022       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
2023         {
2024           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
2025             {
2026               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
2027                 continue;
2028               for (blk = 0; blk < ptr->ncounts; blk++)
2029                 {
2030                   if (!strcmp (p->funcname, ptr->functions[blk]))
2031                     goto found;
2032                 }
2033             }
2034   
2035           if (!printed_something)
2036             {
2037               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
2038               printed_something = 1;
2039             }
2040
2041           fprintf (file, "\tFunction %s", p->funcname);
2042           if (p->filename)
2043               fprintf (file, " of file %s", p->filename);
2044           fprintf (file, "\n" );
2045   
2046 found:        ;
2047         }
2048
2049       if (printed_something)
2050        fprintf (file, "\n");
2051
2052     }
2053
2054   if (bb_mode & 2)
2055     {
2056       if (!bb_hashbuckets)
2057         {
2058           if (!reported)
2059             {
2060               fprintf (stderr, "Profiler: out of memory\n");
2061               reported = 1;
2062             }
2063           return;
2064         }
2065     
2066       else if (file)
2067         {
2068           long time_value;
2069           int i;
2070           unsigned long addr_max = 0;
2071           unsigned long cnt_max  = 0;
2072           int cnt_len;
2073           int addr_len;
2074     
2075           /* This is somewhat type incorrect, but it avoids worrying about
2076              exactly where time.h is included from.  It should be ok unless
2077              a void * differs from other pointer formats, or if sizeof (long)
2078              is < sizeof (time_t).  It would be nice if we could assume the
2079              use of rationale standards here.  */
2080     
2081           time ((void *) &time_value);
2082           fprintf (file, "Basic block jump tracing");
2083
2084           switch (bb_mode & 12)
2085             {
2086               case 0:
2087                 fprintf (file, " (with call)");
2088               break;
2089
2090               case 4:
2091                 /* Print nothing.  */
2092               break;
2093
2094               case 8:
2095                 fprintf (file, " (with call & ret)");
2096               break;
2097
2098               case 12:
2099                 fprintf (file, " (with ret)");
2100               break;
2101             }
2102
2103           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2104     
2105           for (i = 0; i < BB_BUCKETS; i++)
2106             {
2107                struct bb_edge *bucket = bb_hashbuckets[i];
2108                for ( ; bucket; bucket = bucket->next )
2109                  {
2110                    if (addr_max < bucket->src_addr) 
2111                      addr_max = bucket->src_addr;
2112                    if (addr_max < bucket->dst_addr) 
2113                      addr_max = bucket->dst_addr;
2114                    if (cnt_max < bucket->count) 
2115                      cnt_max = bucket->count;
2116                  }
2117             }
2118           addr_len = num_digits (addr_max, 16);
2119           cnt_len  = num_digits (cnt_max, 10);
2120     
2121           for ( i = 0; i < BB_BUCKETS; i++)
2122             {
2123                struct bb_edge *bucket = bb_hashbuckets[i];
2124                for ( ; bucket; bucket = bucket->next )
2125                  {
2126                    fprintf (file, "Jump from block 0x%.*lx to "
2127                                   "block 0x%.*lx executed %*lu time(s)\n", 
2128                             addr_len, bucket->src_addr, 
2129                             addr_len, bucket->dst_addr, 
2130                             cnt_len, bucket->count);
2131                  }
2132             }
2133   
2134           fprintf (file, "\n");
2135
2136         }
2137     }
2138
2139    if (file)
2140      fclose (file);
2141
2142    /* Free allocated memory.  */
2143
2144    f = bb_func_head;
2145    while (f)
2146      {
2147        struct bb_func *old = f;
2148
2149        f = f->next;
2150        if (old->funcname) free (old->funcname);
2151        if (old->filename) free (old->filename);
2152        free (old);
2153      }
2154
2155    if (bb_stack)
2156      free (bb_stack);
2157
2158    if (bb_hashbuckets)
2159      {
2160        int i;
2161
2162        for (i = 0; i < BB_BUCKETS; i++)
2163          {
2164            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2165
2166            while (bucket)
2167              {
2168                old = bucket;
2169                bucket = bucket->next;
2170                free (old);
2171              }
2172          }
2173        free (bb_hashbuckets);
2174      }
2175
2176    for (b = bb_head; b; b = b->next)
2177      if (b->flags) free (b->flags);
2178 }
2179
2180 /* Called once per program.  */
2181
2182 static void
2183 __bb_init_prg (void)
2184 {
2185   FILE *file;
2186   char buf[BBINBUFSIZE];
2187   const char *p;
2188   const char *pos;
2189   enum bb_func_mode m;
2190   int i;
2191
2192   /* Initialize destructor.  */
2193   atexit (__bb_exit_func);
2194
2195   if (!(file = fopen ("bb.in", "r")))
2196     return;
2197
2198   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2199     {
2200       p = buf;
2201       if (*p == '-') 
2202         { 
2203           m = TRACE_OFF; 
2204           p++; 
2205         }
2206       else 
2207         { 
2208           m = TRACE_ON; 
2209         }
2210       if (!strcmp (p, "__bb_trace__"))
2211         bb_mode |= 1;
2212       else if (!strcmp (p, "__bb_jumps__"))
2213         bb_mode |= 2;
2214       else if (!strcmp (p, "__bb_hidecall__"))
2215         bb_mode |= 4;
2216       else if (!strcmp (p, "__bb_showret__"))
2217         bb_mode |= 8;
2218       else 
2219         {
2220           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2221           if (f)
2222             {
2223               unsigned long l;
2224               f->next = bb_func_head;
2225               if ((pos = strchr (p, ':')))
2226                 {
2227                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2228                     continue;
2229                   strcpy (f->funcname, pos+1);
2230                   l = pos-p;
2231                   if ((f->filename = (char *) malloc (l+1)))
2232                     {
2233                       strncpy (f->filename, p, l);
2234                       f->filename[l] = '\0';
2235                     }
2236                   else
2237                     f->filename = (char *) 0;
2238                 }
2239               else
2240                 {
2241                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2242                     continue;
2243                   strcpy (f->funcname, p);
2244                   f->filename = (char *) 0;
2245                 }
2246               f->mode = m;
2247               bb_func_head = f;
2248             }
2249          }
2250     }
2251   fclose (file);
2252
2253 #ifdef HAVE_POPEN 
2254
2255   if (bb_mode & 1)
2256       bb_tracefile = gopen ("bbtrace.gz", "w");
2257
2258 #else
2259
2260   if (bb_mode & 1)
2261       bb_tracefile = fopen ("bbtrace", "w");
2262
2263 #endif /* HAVE_POPEN */
2264
2265   if (bb_mode & 2)
2266     {
2267       bb_hashbuckets = (struct bb_edge **) 
2268                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2269       if (bb_hashbuckets)
2270         /* Use a loop here rather than calling bzero to avoid having to
2271            conditionalize its existance.  */
2272         for (i = 0; i < BB_BUCKETS; i++)
2273           bb_hashbuckets[i] = 0;
2274     }
2275
2276   if (bb_mode & 12)
2277     {
2278       bb_stacksize = 10;
2279       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2280     }
2281
2282   /* Initialize destructor.  */
2283   atexit (__bb_exit_trace_func);
2284 }
2285
2286 /* Called upon entering a basic block.  */
2287
2288 void
2289 __bb_trace_func (void)
2290 {
2291   struct bb_edge *bucket;
2292
2293   MACHINE_STATE_SAVE("1")
2294
2295   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2296     goto skip;
2297
2298   bb_dst = __bb.blocks->addresses[__bb.blockno];
2299   __bb.blocks->counts[__bb.blockno]++;
2300
2301   if (bb_tracefile)
2302     {
2303       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2304     }
2305
2306   if (bb_hashbuckets)
2307     {
2308       struct bb_edge **startbucket, **oldnext;
2309
2310       oldnext = startbucket
2311         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2312       bucket = *startbucket;
2313
2314       for (bucket = *startbucket; bucket; 
2315            oldnext = &(bucket->next), bucket = *oldnext)
2316         {
2317           if (bucket->src_addr == bb_src
2318               && bucket->dst_addr == bb_dst)
2319             {
2320               bucket->count++;
2321               *oldnext = bucket->next;
2322               bucket->next = *startbucket;
2323               *startbucket = bucket;
2324               goto ret;
2325             }
2326         }
2327
2328       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2329
2330       if (!bucket)
2331         {
2332           if (!reported)
2333             {
2334               fprintf (stderr, "Profiler: out of memory\n");
2335               reported = 1;
2336             }
2337         }
2338
2339       else
2340         {
2341           bucket->src_addr = bb_src;
2342           bucket->dst_addr = bb_dst;
2343           bucket->next = *startbucket;
2344           *startbucket = bucket;
2345           bucket->count = 1;
2346         }
2347     }
2348
2349 ret:
2350   bb_src = bb_dst;
2351
2352 skip:
2353   ;
2354
2355   MACHINE_STATE_RESTORE("1")
2356
2357 }
2358
2359 /* Called when returning from a function and `__bb_showret__' is set.  */
2360
2361 static void
2362 __bb_trace_func_ret (void)
2363 {
2364   struct bb_edge *bucket;
2365
2366   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2367     goto skip;
2368
2369   if (bb_hashbuckets)
2370     {
2371       struct bb_edge **startbucket, **oldnext;
2372
2373       oldnext = startbucket
2374         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2375       bucket = *startbucket;
2376
2377       for (bucket = *startbucket; bucket; 
2378            oldnext = &(bucket->next), bucket = *oldnext)
2379         {
2380           if (bucket->src_addr == bb_dst
2381                && bucket->dst_addr == bb_src)
2382             {
2383               bucket->count++;
2384               *oldnext = bucket->next;
2385               bucket->next = *startbucket;
2386               *startbucket = bucket;
2387               goto ret;
2388             }
2389         }
2390
2391       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2392
2393       if (!bucket)
2394         {
2395           if (!reported)
2396             {
2397               fprintf (stderr, "Profiler: out of memory\n");
2398               reported = 1;
2399             }
2400         }
2401
2402       else
2403         {
2404           bucket->src_addr = bb_dst;
2405           bucket->dst_addr = bb_src;
2406           bucket->next = *startbucket;
2407           *startbucket = bucket;
2408           bucket->count = 1;
2409         }
2410     }
2411
2412 ret:
2413   bb_dst = bb_src;
2414
2415 skip:
2416   ;
2417
2418 }
2419
2420 /* Called upon entering the first function of a file.  */
2421
2422 static void
2423 __bb_init_file (struct bb *blocks)
2424 {
2425
2426   const struct bb_func *p;
2427   long blk, ncounts = blocks->ncounts;
2428   const char **functions = blocks->functions;
2429
2430   /* Set up linked list.  */
2431   blocks->zero_word = 1;
2432   blocks->next = bb_head;
2433   bb_head = blocks;
2434
2435   blocks->flags = 0;
2436   if (!bb_func_head
2437       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2438     return;
2439
2440   for (blk = 0; blk < ncounts; blk++)
2441     blocks->flags[blk] = 0;
2442
2443   for (blk = 0; blk < ncounts; blk++)
2444     {
2445       for (p = bb_func_head; p; p = p->next)
2446         {
2447           if (!strcmp (p->funcname, functions[blk])
2448               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2449             {
2450               blocks->flags[blk] |= p->mode;
2451             }
2452         }
2453     }
2454
2455 }
2456
2457 /* Called when exiting from a function.  */
2458
2459 void
2460 __bb_trace_ret (void)
2461 {
2462
2463   MACHINE_STATE_SAVE("2")
2464
2465   if (bb_callcount)
2466     {
2467       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2468         {
2469           bb_src = bb_stack[bb_callcount];
2470           if (bb_mode & 8)
2471             __bb_trace_func_ret ();
2472         }
2473
2474       bb_callcount -= 1;
2475     }
2476
2477   MACHINE_STATE_RESTORE("2")
2478
2479 }
2480
2481 /* Called when entering a function.  */
2482
2483 void
2484 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2485 {
2486   static int trace_init = 0;
2487
2488   MACHINE_STATE_SAVE("3")
2489
2490   if (!blocks->zero_word)
2491     { 
2492       if (!trace_init)
2493         { 
2494           trace_init = 1;
2495           __bb_init_prg ();
2496         }
2497       __bb_init_file (blocks);
2498     }
2499
2500   if (bb_callcount)
2501     {
2502
2503       bb_callcount += 1;
2504
2505       if (bb_mode & 12)
2506         {
2507           if (bb_callcount >= bb_stacksize)
2508             {
2509               size_t newsize = bb_callcount + 100;
2510
2511               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2512               if (! bb_stack)
2513                 {
2514                   if (!reported)
2515                     {
2516                       fprintf (stderr, "Profiler: out of memory\n");
2517                       reported = 1;
2518                     }
2519                   bb_stacksize = 0;
2520                   goto stack_overflow;
2521                 }
2522               bb_stacksize = newsize;
2523             }
2524           bb_stack[bb_callcount] = bb_src;
2525
2526           if (bb_mode & 4)
2527             bb_src = 0;
2528
2529         }
2530
2531 stack_overflow:;
2532
2533     }
2534
2535   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2536     {
2537       bb_callcount = 1;
2538       bb_src = 0;
2539
2540       if (bb_stack)
2541           bb_stack[bb_callcount] = bb_src;
2542     }
2543
2544   MACHINE_STATE_RESTORE("3")
2545 }
2546
2547 #endif /* not inhibit_libc */
2548 #endif /* not BLOCK_PROFILER_CODE */
2549 #endif /* L_bb */
2550 \f
2551 #ifdef L_shtab
2552 unsigned int __shtab[] = {
2553     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2554     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2555     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2556     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2557     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2558     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2559     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2560     0x10000000, 0x20000000, 0x40000000, 0x80000000
2561   };
2562 #endif
2563 \f
2564 #ifdef L_clear_cache
2565 /* Clear part of an instruction cache.  */
2566
2567 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2568
2569 void
2570 __clear_cache (char *beg __attribute__((__unused__)),
2571                char *end __attribute__((__unused__)))
2572 {
2573 #ifdef CLEAR_INSN_CACHE 
2574   CLEAR_INSN_CACHE (beg, end);
2575 #else
2576 #ifdef INSN_CACHE_SIZE
2577   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2578   static int initialized;
2579   int offset;
2580   void *start_addr
2581   void *end_addr;
2582   typedef (*function_ptr) (void);
2583
2584 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2585   /* It's cheaper to clear the whole cache.
2586      Put in a series of jump instructions so that calling the beginning
2587      of the cache will clear the whole thing.  */
2588
2589   if (! initialized)
2590     {
2591       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2592                  & -INSN_CACHE_LINE_WIDTH);
2593       int end_ptr = ptr + INSN_CACHE_SIZE;
2594
2595       while (ptr < end_ptr)
2596         {
2597           *(INSTRUCTION_TYPE *)ptr
2598             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2599           ptr += INSN_CACHE_LINE_WIDTH;
2600         }
2601       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2602
2603       initialized = 1;
2604     }
2605
2606   /* Call the beginning of the sequence.  */
2607   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2608                     & -INSN_CACHE_LINE_WIDTH))
2609    ());
2610
2611 #else /* Cache is large.  */
2612
2613   if (! initialized)
2614     {
2615       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2616                  & -INSN_CACHE_LINE_WIDTH);
2617
2618       while (ptr < (int) array + sizeof array)
2619         {
2620           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2621           ptr += INSN_CACHE_LINE_WIDTH;
2622         }
2623
2624       initialized = 1;
2625     }
2626
2627   /* Find the location in array that occupies the same cache line as BEG.  */
2628
2629   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2630   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2631                  & -INSN_CACHE_PLANE_SIZE)
2632                 + offset);
2633
2634   /* Compute the cache alignment of the place to stop clearing.  */
2635 #if 0  /* This is not needed for gcc's purposes.  */
2636   /* If the block to clear is bigger than a cache plane,
2637      we clear the entire cache, and OFFSET is already correct.  */ 
2638   if (end < beg + INSN_CACHE_PLANE_SIZE)
2639 #endif
2640     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2641                & -INSN_CACHE_LINE_WIDTH)
2642               & (INSN_CACHE_PLANE_SIZE - 1));
2643
2644 #if INSN_CACHE_DEPTH > 1
2645   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2646   if (end_addr <= start_addr)
2647     end_addr += INSN_CACHE_PLANE_SIZE;
2648
2649   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2650     {
2651       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2652       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2653
2654       while (addr != stop)
2655         {
2656           /* Call the return instruction at ADDR.  */
2657           ((function_ptr) addr) ();
2658
2659           addr += INSN_CACHE_LINE_WIDTH;
2660         }
2661     }
2662 #else /* just one plane */
2663   do
2664     {
2665       /* Call the return instruction at START_ADDR.  */
2666       ((function_ptr) start_addr) ();
2667
2668       start_addr += INSN_CACHE_LINE_WIDTH;
2669     }
2670   while ((start_addr % INSN_CACHE_SIZE) != offset);
2671 #endif /* just one plane */
2672 #endif /* Cache is large */
2673 #endif /* Cache exists */
2674 #endif /* CLEAR_INSN_CACHE */
2675 }
2676
2677 #endif /* L_clear_cache */
2678 \f
2679 #ifdef L_trampoline
2680
2681 /* Jump to a trampoline, loading the static chain address.  */
2682
2683 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2684
2685 long
2686 getpagesize (void)
2687 {
2688 #ifdef _ALPHA_
2689   return 8192;
2690 #else
2691   return 4096;
2692 #endif
2693 }
2694
2695 #ifdef __i386__
2696 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2697 #endif
2698
2699 int
2700 mprotect (char *addr, int len, int prot)
2701 {
2702   int np, op;
2703
2704   if (prot == 7)
2705     np = 0x40;
2706   else if (prot == 5)
2707     np = 0x20;
2708   else if (prot == 4)
2709     np = 0x10;
2710   else if (prot == 3)
2711     np = 0x04;
2712   else if (prot == 1)
2713     np = 0x02;
2714   else if (prot == 0)
2715     np = 0x01;
2716
2717   if (VirtualProtect (addr, len, np, &op))
2718     return 0;
2719   else
2720     return -1;
2721 }
2722
2723 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2724
2725 #ifdef TRANSFER_FROM_TRAMPOLINE 
2726 TRANSFER_FROM_TRAMPOLINE 
2727 #endif
2728
2729 #if defined (NeXT) && defined (__MACH__)
2730
2731 /* Make stack executable so we can call trampolines on stack.
2732    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2733 #ifdef NeXTStep21
2734  #include <mach.h>
2735 #else
2736  #include <mach/mach.h>
2737 #endif
2738
2739 void
2740 __enable_execute_stack (char *addr)
2741 {
2742   kern_return_t r;
2743   char *eaddr = addr + TRAMPOLINE_SIZE;
2744   vm_address_t a = (vm_address_t) addr;
2745
2746   /* turn on execute access on stack */
2747   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2748   if (r != KERN_SUCCESS)
2749     {
2750       mach_error("vm_protect VM_PROT_ALL", r);
2751       exit(1);
2752     }
2753
2754   /* We inline the i-cache invalidation for speed */
2755
2756 #ifdef CLEAR_INSN_CACHE
2757   CLEAR_INSN_CACHE (addr, eaddr);
2758 #else
2759   __clear_cache ((int) addr, (int) eaddr);
2760 #endif
2761
2762
2763 #endif /* defined (NeXT) && defined (__MACH__) */
2764
2765 #ifdef __convex__
2766
2767 /* Make stack executable so we can call trampolines on stack.
2768    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2769
2770 #include <sys/mman.h>
2771 #include <sys/vmparam.h>
2772 #include <machine/machparam.h>
2773
2774 void
2775 __enable_execute_stack (void)
2776 {
2777   int fp;
2778   static unsigned lowest = USRSTACK;
2779   unsigned current = (unsigned) &fp & -NBPG;
2780
2781   if (lowest > current)
2782     {
2783       unsigned len = lowest - current;
2784       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2785       lowest = current;
2786     }
2787
2788   /* Clear instruction cache in case an old trampoline is in it.  */
2789   asm ("pich");
2790 }
2791 #endif /* __convex__ */
2792
2793 #ifdef __sysV88__
2794
2795 /* Modified from the convex -code above.  */
2796
2797 #include <sys/param.h>
2798 #include <errno.h>
2799 #include <sys/m88kbcs.h>
2800
2801 void
2802 __enable_execute_stack (void)
2803 {
2804   int save_errno;
2805   static unsigned long lowest = USRSTACK;
2806   unsigned long current = (unsigned long) &save_errno & -NBPC;
2807   
2808   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2809      address is seen as 'negative'. That is the case with the stack.   */
2810
2811   save_errno=errno;
2812   if (lowest > current)
2813     {
2814       unsigned len=lowest-current;
2815       memctl(current,len,MCT_TEXT);
2816       lowest = current;
2817     }
2818   else
2819     memctl(current,NBPC,MCT_TEXT);
2820   errno=save_errno;
2821 }
2822
2823 #endif /* __sysV88__ */
2824
2825 #ifdef __sysV68__
2826
2827 #include <sys/signal.h>
2828 #include <errno.h>
2829
2830 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2831    so define it here, because we need it in __clear_insn_cache below */
2832 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2833    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2834
2835 #ifdef MCT_TEXT
2836 asm("\n\
2837         global memctl\n\
2838 memctl:\n\
2839         movq &75,%d0\n\
2840         trap &0\n\
2841         bcc.b noerror\n\
2842         jmp cerror%\n\
2843 noerror:\n\
2844         movq &0,%d0\n\
2845         rts");
2846 #endif
2847
2848 /* Clear instruction cache so we can call trampolines on stack.
2849    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2850
2851 void
2852 __clear_insn_cache (void)
2853 {
2854 #ifdef MCT_TEXT
2855   int save_errno;
2856
2857   /* Preserve errno, because users would be surprised to have
2858   errno changing without explicitly calling any system-call. */
2859   save_errno = errno;
2860
2861   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2862      No need to use an address derived from _start or %sp, as 0 works also. */
2863   memctl(0, 4096, MCT_TEXT);
2864   errno = save_errno;
2865 #endif
2866 }
2867
2868 #endif /* __sysV68__ */
2869
2870 #ifdef __pyr__
2871
2872 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2873 #include <stdio.h>
2874 #include <sys/mman.h>
2875 #include <sys/types.h>
2876 #include <sys/param.h>
2877 #include <sys/vmmac.h>
2878
2879 /* Modified from the convex -code above.
2880    mremap promises to clear the i-cache.  */
2881
2882 void
2883 __enable_execute_stack (void)
2884 {
2885   int fp;
2886   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2887                 PROT_READ|PROT_WRITE|PROT_EXEC))
2888     {
2889       perror ("mprotect in __enable_execute_stack");
2890       fflush (stderr);
2891       abort ();
2892     }
2893 }
2894 #endif /* __pyr__ */
2895
2896 #if defined (sony_news) && defined (SYSTYPE_BSD)
2897
2898 #include <stdio.h>
2899 #include <sys/types.h>
2900 #include <sys/param.h>
2901 #include <syscall.h>
2902 #include <machine/sysnews.h>
2903
2904 /* cacheflush function for NEWS-OS 4.2.
2905    This function is called from trampoline-initialize code
2906    defined in config/mips/mips.h.  */
2907
2908 void
2909 cacheflush (char *beg, int size, int flag)
2910 {
2911   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2912     {
2913       perror ("cache_flush");
2914       fflush (stderr);
2915       abort ();
2916     }
2917 }
2918
2919 #endif /* sony_news */
2920 #endif /* L_trampoline */
2921 \f
2922 #ifndef __CYGWIN__
2923 #ifdef L__main
2924
2925 #include "gbl-ctors.h"
2926 /* Some systems use __main in a way incompatible with its use in gcc, in these
2927    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2928    give the same symbol without quotes for an alternative entry point.  You
2929    must define both, or neither.  */
2930 #ifndef NAME__MAIN
2931 #define NAME__MAIN "__main"
2932 #define SYMBOL__MAIN __main
2933 #endif
2934
2935 #ifdef INIT_SECTION_ASM_OP
2936 #undef HAS_INIT_SECTION
2937 #define HAS_INIT_SECTION
2938 #endif
2939
2940 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2941
2942 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2943    code to run constructors.  In that case, we need to handle EH here, too.  */
2944
2945 #ifdef EH_FRAME_SECTION
2946 #include "frame.h"
2947 extern unsigned char __EH_FRAME_BEGIN__[];
2948 #endif
2949
2950 /* Run all the global destructors on exit from the program.  */
2951
2952 void
2953 __do_global_dtors (void)
2954 {
2955 #ifdef DO_GLOBAL_DTORS_BODY
2956   DO_GLOBAL_DTORS_BODY;
2957 #else
2958   static func_ptr *p = __DTOR_LIST__ + 1;
2959   while (*p)
2960     {
2961       p++;
2962       (*(p-1)) ();
2963     }
2964 #endif
2965 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2966   {
2967     static int completed = 0;
2968     if (! completed)
2969       {
2970         completed = 1;
2971         __deregister_frame_info (__EH_FRAME_BEGIN__);
2972       }
2973   }
2974 #endif
2975 }
2976 #endif
2977
2978 #ifndef HAS_INIT_SECTION
2979 /* Run all the global constructors on entry to the program.  */
2980
2981 void
2982 __do_global_ctors (void)
2983 {
2984 #ifdef EH_FRAME_SECTION
2985   {
2986     static struct object object;
2987     __register_frame_info (__EH_FRAME_BEGIN__, &object);
2988   }
2989 #endif
2990   DO_GLOBAL_CTORS_BODY;
2991   atexit (__do_global_dtors);
2992 }
2993 #endif /* no HAS_INIT_SECTION */
2994
2995 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2996 /* Subroutine called automatically by `main'.
2997    Compiling a global function named `main'
2998    produces an automatic call to this function at the beginning.
2999
3000    For many systems, this routine calls __do_global_ctors.
3001    For systems which support a .init section we use the .init section
3002    to run __do_global_ctors, so we need not do anything here.  */
3003
3004 void
3005 SYMBOL__MAIN ()
3006 {
3007   /* Support recursive calls to `main': run initializers just once.  */
3008   static int initialized;
3009   if (! initialized)
3010     {
3011       initialized = 1;
3012       __do_global_ctors ();
3013     }
3014 }
3015 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3016
3017 #endif /* L__main */
3018 #endif /* __CYGWIN__ */
3019 \f
3020 #ifdef L_ctors
3021
3022 #include "gbl-ctors.h"
3023
3024 /* Provide default definitions for the lists of constructors and
3025    destructors, so that we don't get linker errors.  These symbols are
3026    intentionally bss symbols, so that gld and/or collect will provide
3027    the right values.  */
3028
3029 /* We declare the lists here with two elements each,
3030    so that they are valid empty lists if no other definition is loaded.
3031
3032    If we are using the old "set" extensions to have the gnu linker
3033    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3034    must be in the bss/common section.
3035
3036    Long term no port should use those extensions.  But many still do.  */
3037 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3038 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3039 func_ptr __CTOR_LIST__[2] = {0, 0};
3040 func_ptr __DTOR_LIST__[2] = {0, 0};
3041 #else
3042 func_ptr __CTOR_LIST__[2];
3043 func_ptr __DTOR_LIST__[2];
3044 #endif
3045 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3046 #endif /* L_ctors */
3047 \f
3048 #ifdef L_exit
3049
3050 #include "gbl-ctors.h"
3051
3052 #ifdef NEED_ATEXIT
3053
3054 #ifndef ON_EXIT
3055
3056 # include <errno.h>
3057
3058 static func_ptr *atexit_chain = 0;
3059 static long atexit_chain_length = 0;
3060 static volatile long last_atexit_chain_slot = -1;
3061
3062 int
3063 atexit (func_ptr func)
3064 {
3065   if (++last_atexit_chain_slot == atexit_chain_length)
3066     {
3067       atexit_chain_length += 32;
3068       if (atexit_chain)
3069         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3070                                              * sizeof (func_ptr));
3071       else
3072         atexit_chain = (func_ptr *) malloc (atexit_chain_length
3073                                             * sizeof (func_ptr));
3074       if (! atexit_chain)
3075         {
3076           atexit_chain_length = 0;
3077           last_atexit_chain_slot = -1;
3078           errno = ENOMEM;
3079           return (-1);
3080         }
3081     }
3082   atexit_chain[last_atexit_chain_slot] = func;
3083   return (0);
3084 }
3085
3086 extern void _cleanup (void);
3087 extern void _exit (int) __attribute__ ((__noreturn__));
3088
3089 void 
3090 exit (int status)
3091 {
3092   if (atexit_chain)
3093     {
3094       for ( ; last_atexit_chain_slot-- >= 0; )
3095         {
3096           (*atexit_chain[last_atexit_chain_slot + 1]) ();
3097           atexit_chain[last_atexit_chain_slot + 1] = 0;
3098         }
3099       free (atexit_chain);
3100       atexit_chain = 0;
3101     }
3102 #ifdef EXIT_BODY
3103   EXIT_BODY;
3104 #else
3105   _cleanup ();
3106 #endif
3107   _exit (status);
3108 }
3109
3110 #else /* ON_EXIT */
3111
3112 /* Simple; we just need a wrapper for ON_EXIT.  */
3113 int
3114 atexit (func_ptr func)
3115 {
3116   return ON_EXIT (func);
3117 }
3118
3119 #endif /* ON_EXIT */
3120 #endif /* NEED_ATEXIT */
3121
3122 #endif /* L_exit */
3123 \f
3124 #ifdef L_eh
3125
3126 #include "gthr.h"
3127
3128 /* Shared exception handling support routines.  */
3129
3130 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3131
3132 void
3133 __default_terminate (void)
3134 {
3135   abort ();
3136 }
3137
3138 void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
3139   __default_terminate;
3140
3141 void
3142 __terminate (void)
3143 {
3144   (*__terminate_func)();
3145 }
3146
3147 void *
3148 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3149 {
3150 #if 0
3151  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3152          catch_type, throw_type);
3153 #endif
3154  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3155    return obj;
3156  return 0;
3157 }
3158
3159 void
3160 __empty (void)
3161 {
3162 }
3163 \f
3164
3165 /* Include definitions of EH context and table layout */
3166
3167 #include "eh-common.h"
3168 #ifndef inhibit_libc
3169 #include <stdio.h>
3170 #endif
3171
3172 /* Allocate and return a new EH context structure. */
3173
3174 extern void __throw (void);
3175
3176 #if __GTHREADS
3177 static void *
3178 new_eh_context (void)
3179 {
3180   struct eh_full_context {
3181     struct eh_context c;
3182     void *top_elt[2];
3183   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3184
3185   if (! ehfc)
3186     __terminate ();
3187
3188   memset (ehfc, 0, sizeof *ehfc);
3189
3190   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3191
3192   /* This should optimize out entirely.  This should always be true,
3193      but just in case it ever isn't, don't allow bogus code to be
3194      generated.  */
3195
3196   if ((void*)(&ehfc->c) != (void*)ehfc)
3197     __terminate ();
3198
3199   return &ehfc->c;
3200 }
3201
3202 static __gthread_key_t eh_context_key;
3203
3204 /* Destructor for struct eh_context. */
3205 static void
3206 eh_context_free (void *ptr)
3207 {
3208   __gthread_key_dtor (eh_context_key, ptr);
3209   if (ptr)
3210     free (ptr);
3211 }
3212 #endif
3213
3214 /* Pointer to function to return EH context. */
3215
3216 static struct eh_context *eh_context_initialize (void);
3217 static struct eh_context *eh_context_static (void);
3218 #if __GTHREADS
3219 static struct eh_context *eh_context_specific (void);
3220 #endif
3221
3222 static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
3223
3224 /* Routine to get EH context.
3225    This one will simply call the function pointer. */
3226
3227 void *
3228 __get_eh_context (void)
3229 {
3230   return (void *) (*get_eh_context) ();
3231 }
3232
3233 /* Get and set the language specific info pointer. */
3234
3235 void **
3236 __get_eh_info (void)
3237 {
3238   struct eh_context *eh = (*get_eh_context) ();
3239   return &eh->info;
3240 }
3241 \f
3242 #ifdef DWARF2_UNWIND_INFO
3243 static int dwarf_reg_size_table_initialized = 0;
3244 static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER];
3245
3246 static void
3247 init_reg_size_table (void)
3248 {
3249   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3250   dwarf_reg_size_table_initialized = 1;
3251 }
3252 #endif
3253
3254 #if __GTHREADS
3255 static void
3256 eh_threads_initialize (void)
3257 {
3258   /* Try to create the key.  If it fails, revert to static method,
3259      otherwise start using thread specific EH contexts. */
3260   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3261     get_eh_context = &eh_context_specific;
3262   else
3263     get_eh_context = &eh_context_static;
3264 }
3265 #endif /* no __GTHREADS */
3266
3267 /* Initialize EH context.
3268    This will be called only once, since we change GET_EH_CONTEXT
3269    pointer to another routine. */
3270
3271 static struct eh_context *
3272 eh_context_initialize (void)
3273 {
3274 #if __GTHREADS
3275
3276   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3277   /* Make sure that get_eh_context does not point to us anymore.
3278      Some systems have dummy thread routines in their libc that
3279      return a success (Solaris 2.6 for example). */
3280   if (__gthread_once (&once, eh_threads_initialize) != 0
3281       || get_eh_context == &eh_context_initialize)
3282     {
3283       /* Use static version of EH context. */
3284       get_eh_context = &eh_context_static;
3285     }
3286 #ifdef DWARF2_UNWIND_INFO
3287   {
3288     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3289     if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3290         || ! dwarf_reg_size_table_initialized)
3291       init_reg_size_table ();
3292   }
3293 #endif
3294
3295 #else /* no __GTHREADS */
3296
3297   /* Use static version of EH context. */
3298   get_eh_context = &eh_context_static;
3299
3300 #ifdef DWARF2_UNWIND_INFO
3301   init_reg_size_table ();
3302 #endif
3303
3304 #endif /* no __GTHREADS */
3305
3306   return (*get_eh_context) ();
3307 }
3308
3309 /* Return a static EH context. */
3310
3311 static struct eh_context *
3312 eh_context_static (void)
3313 {
3314   static struct eh_context eh;
3315   static int initialized;
3316   static void *top_elt[2];
3317
3318   if (! initialized)
3319     {
3320       initialized = 1;
3321       memset (&eh, 0, sizeof eh);
3322       eh.dynamic_handler_chain = top_elt;
3323     }
3324   return &eh;
3325 }
3326
3327 #if __GTHREADS
3328 /* Return a thread specific EH context. */
3329
3330 static struct eh_context *
3331 eh_context_specific (void)
3332 {
3333   struct eh_context *eh;
3334   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3335   if (! eh)
3336     {
3337       eh = new_eh_context ();
3338       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3339         __terminate ();
3340     }
3341
3342   return eh;
3343 }
3344 #endif __GTHREADS
3345 \f
3346 /* Support routines for setjmp/longjmp exception handling.  */
3347
3348 /* Calls to __sjthrow are generated by the compiler when an exception
3349    is raised when using the setjmp/longjmp exception handling codegen
3350    method.  */
3351
3352 #ifdef DONT_USE_BUILTIN_SETJMP
3353 extern void longjmp (void *, int);
3354 #endif
3355
3356 /* Routine to get the head of the current thread's dynamic handler chain
3357    use for exception handling. */
3358
3359 void ***
3360 __get_dynamic_handler_chain (void)
3361 {
3362   struct eh_context *eh = (*get_eh_context) ();
3363   return &eh->dynamic_handler_chain;
3364 }
3365
3366 /* This is used to throw an exception when the setjmp/longjmp codegen
3367    method is used for exception handling.
3368
3369    We call __terminate if there are no handlers left.  Otherwise we run the
3370    cleanup actions off the dynamic cleanup stack, and pop the top of the
3371    dynamic handler chain, and use longjmp to transfer back to the associated
3372    handler.  */
3373
3374 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3375
3376 void
3377 __sjthrow (void)
3378 {
3379   struct eh_context *eh = (*get_eh_context) ();
3380   void ***dhc = &eh->dynamic_handler_chain;
3381   void *jmpbuf;
3382   void (*func)(void *, int);
3383   void *arg;
3384   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3385   void ***cleanup = (void***)&(*dhc)[1];
3386
3387   /* If there are any cleanups in the chain, run them now.  */
3388   if (cleanup[0])
3389     {
3390       double store[200];
3391       void **buf = (void**)store;
3392       buf[1] = 0;
3393       buf[0] = (*dhc);
3394
3395       /* try { */
3396 #ifdef DONT_USE_BUILTIN_SETJMP
3397       if (! setjmp (&buf[2]))
3398 #else
3399       if (! __builtin_setjmp (&buf[2]))
3400 #endif
3401         {
3402           *dhc = buf;
3403           while (cleanup[0])
3404             {
3405               func = (void(*)(void*, int))cleanup[0][1];
3406               arg = (void*)cleanup[0][2];
3407
3408               /* Update this before running the cleanup.  */
3409               cleanup[0] = (void **)cleanup[0][0];
3410
3411               (*func)(arg, 2);
3412             }
3413           *dhc = buf[0];
3414         }
3415       /* catch (...) */
3416       else
3417         {
3418           __terminate ();
3419         }
3420     }
3421   
3422   /* We must call terminate if we try and rethrow an exception, when
3423      there is no exception currently active and when there are no
3424      handlers left.  */
3425   if (! eh->info || (*dhc)[0] == 0)
3426     __terminate ();
3427     
3428   /* Find the jmpbuf associated with the top element of the dynamic
3429      handler chain.  The jumpbuf starts two words into the buffer.  */
3430   jmpbuf = &(*dhc)[2];
3431
3432   /* Then we pop the top element off the dynamic handler chain.  */
3433   *dhc = (void**)(*dhc)[0];
3434
3435   /* And then we jump to the handler.  */
3436
3437 #ifdef DONT_USE_BUILTIN_SETJMP
3438   longjmp (jmpbuf, 1);
3439 #else
3440   __builtin_longjmp (jmpbuf, 1);
3441 #endif
3442 }
3443
3444 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3445    handler, then pop the handler off the dynamic handler stack, and
3446    then throw.  This is used to skip the first handler, and transfer
3447    control to the next handler in the dynamic handler stack.  */
3448
3449 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3450
3451 void
3452 __sjpopnthrow (void)
3453 {
3454   struct eh_context *eh = (*get_eh_context) ();
3455   void ***dhc = &eh->dynamic_handler_chain;
3456   void (*func)(void *, int);
3457   void *arg;
3458   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3459   void ***cleanup = (void***)&(*dhc)[1];
3460
3461   /* If there are any cleanups in the chain, run them now.  */
3462   if (cleanup[0])
3463     {
3464       double store[200];
3465       void **buf = (void**)store;
3466       buf[1] = 0;
3467       buf[0] = (*dhc);
3468
3469       /* try { */
3470 #ifdef DONT_USE_BUILTIN_SETJMP
3471       if (! setjmp (&buf[2]))
3472 #else
3473       if (! __builtin_setjmp (&buf[2]))
3474 #endif
3475         {
3476           *dhc = buf;
3477           while (cleanup[0])
3478             {
3479               func = (void(*)(void*, int))cleanup[0][1];
3480               arg = (void*)cleanup[0][2];
3481
3482               /* Update this before running the cleanup.  */
3483               cleanup[0] = (void **)cleanup[0][0];
3484
3485               (*func)(arg, 2);
3486             }
3487           *dhc = buf[0];
3488         }
3489       /* catch (...) */
3490       else
3491         {
3492           __terminate ();
3493         }
3494     }
3495
3496   /* Then we pop the top element off the dynamic handler chain.  */
3497   *dhc = (void**)(*dhc)[0];
3498
3499   __sjthrow ();
3500 }
3501 \f
3502 /* Support code for all exception region-based exception handling.  */
3503
3504 int
3505 __eh_rtime_match (void *rtime)
3506 {
3507   void *info;
3508   __eh_matcher matcher;
3509   void *ret;
3510
3511   info = *(__get_eh_info ());
3512   matcher = ((__eh_info *)info)->match_function;
3513   if (! matcher)
3514     {
3515 #ifndef inhibit_libc
3516       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3517 #endif
3518       return 0;
3519     }
3520   ret = (*matcher) (info, rtime, (void *)0);
3521   return (ret != NULL);
3522 }
3523
3524 /* This value identifies the place from which an exception is being
3525    thrown.  */
3526
3527 #ifdef EH_TABLE_LOOKUP
3528
3529 EH_TABLE_LOOKUP
3530
3531 #else
3532
3533 #ifdef DWARF2_UNWIND_INFO
3534
3535 /* Return the table version of an exception descriptor */
3536
3537 short 
3538 __get_eh_table_version (exception_descriptor *table) 
3539 {
3540   return table->lang.version;
3541 }
3542
3543 /* Return the originating table language of an exception descriptor */
3544
3545 short 
3546 __get_eh_table_language (exception_descriptor *table)
3547 {
3548   return table->lang.language;
3549 }
3550
3551 /* This routine takes a PC and a pointer to the exception region TABLE for
3552    its translation unit, and returns the address of the exception handler
3553    associated with the closest exception table handler entry associated
3554    with that PC, or 0 if there are no table entries the PC fits in.
3555
3556    In the advent of a tie, we have to give the last entry, as it represents
3557    an inner block.  */
3558
3559 static void *
3560 old_find_exception_handler (void *pc, old_exception_table *table)
3561 {
3562   if (table)
3563     {
3564       int pos;
3565       int best = -1;
3566
3567       /* We can't do a binary search because the table isn't guaranteed
3568          to be sorted from function to function.  */
3569       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3570         {
3571           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3572             {
3573               /* This can apply.  Make sure it is at least as small as
3574                  the previous best.  */
3575               if (best == -1 || (table[pos].end_region <= table[best].end_region
3576                         && table[pos].start_region >= table[best].start_region))
3577                 best = pos;
3578             }
3579           /* But it is sorted by starting PC within a function.  */
3580           else if (best >= 0 && table[pos].start_region > pc)
3581             break;
3582         }
3583       if (best != -1)
3584         return table[best].exception_handler;
3585     }
3586
3587   return (void *) 0;
3588 }
3589
3590 /* find_exception_handler finds the correct handler, if there is one, to
3591    handle an exception.
3592    returns a pointer to the handler which controlled should be transferred
3593    to, or NULL if there is nothing left.
3594    Parameters:
3595    PC - pc where the exception originates. If this is a rethrow, 
3596         then this starts out as a pointer to the exception table
3597         entry we wish to rethrow out of.
3598    TABLE - exception table for the current module.
3599    EH_INFO - eh info pointer for this exception.
3600    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3601    CLEANUP - returned flag indicating whether this is a cleanup handler.
3602 */
3603 static void *
3604 find_exception_handler (void *pc, exception_descriptor *table, 
3605                         __eh_info *eh_info, int rethrow, int *cleanup)
3606 {
3607
3608   void *retval = NULL;
3609   *cleanup = 1;
3610   if (table)
3611     {
3612       int pos = 0;
3613       /* The new model assumed the table is sorted inner-most out so the
3614          first region we find which matches is the correct one */
3615
3616       exception_table *tab = &(table->table[0]);
3617
3618       /* Subtract 1 from the PC to avoid hitting the next region */
3619       if (rethrow) 
3620         {
3621           /* pc is actually the region table entry to rethrow out of */
3622           pos = ((exception_table *) pc) - tab;
3623           pc = ((exception_table *) pc)->end_region - 1;
3624
3625           /* The label is always on the LAST handler entry for a region, 
3626              so we know the next entry is a different region, even if the
3627              addresses are the same. Make sure its not end of table tho. */
3628           if (tab[pos].start_region != (void *) -1)
3629             pos++;
3630         }
3631       else
3632         pc--;
3633       
3634       /* We can't do a binary search because the table is in inner-most
3635          to outermost address ranges within functions */
3636       for ( ; tab[pos].start_region != (void *) -1; pos++)
3637         { 
3638           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3639             {
3640               if (tab[pos].match_info)
3641                 {
3642                   __eh_matcher matcher = eh_info->match_function;
3643                   /* match info but no matcher is NOT a match */
3644                   if (matcher) 
3645                     {
3646                       void *ret = (*matcher)((void *) eh_info, 
3647                                              tab[pos].match_info, table);
3648                       if (ret) 
3649                         {
3650                           if (retval == NULL)
3651                             retval = tab[pos].exception_handler;
3652                           *cleanup = 0;
3653                           break;
3654                         }
3655                     }
3656                 }
3657               else
3658                 {
3659                   if (retval == NULL)
3660                     retval = tab[pos].exception_handler;
3661                 }
3662             }
3663         }
3664     }
3665   return retval;
3666 }
3667 #endif /* DWARF2_UNWIND_INFO */
3668 #endif /* EH_TABLE_LOOKUP */
3669 \f
3670 #ifdef DWARF2_UNWIND_INFO
3671 /* Support code for exception handling using static unwind information.  */
3672
3673 #include "frame.h"
3674
3675 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3676    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3677    avoid a warning about casting between int and pointer of different
3678    sizes.  */
3679
3680 typedef int ptr_type __attribute__ ((mode (pointer)));
3681
3682 #ifdef INCOMING_REGNO
3683 /* Is the saved value for register REG in frame UDATA stored in a register
3684    window in the previous frame?  */
3685
3686 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3687    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3688    compiled functions won't work with the frame-unwind stuff here.  
3689    Perhaps the entireity of in_reg_window should be conditional on having
3690    seen a DW_CFA_GNU_window_save?  */
3691 #define target_flags 0
3692
3693 static int
3694 in_reg_window (int reg, frame_state *udata)
3695 {
3696   if (udata->saved[reg] == REG_SAVED_REG)
3697     return INCOMING_REGNO (reg) == reg;
3698   if (udata->saved[reg] != REG_SAVED_OFFSET)
3699     return 0;
3700
3701 #ifdef STACK_GROWS_DOWNWARD
3702   return udata->reg_or_offset[reg] > 0;
3703 #else
3704   return udata->reg_or_offset[reg] < 0;
3705 #endif
3706 }
3707 #else
3708 static inline int
3709 in_reg_window (int reg __attribute__ ((__unused__)),
3710                frame_state *udata __attribute__ ((__unused__)))
3711 {
3712   return 0;
3713 }
3714 #endif /* INCOMING_REGNO */
3715
3716 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3717    frame called by UDATA or 0.  */
3718
3719 static word_type *
3720 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3721 {
3722   while (udata->saved[reg] == REG_SAVED_REG)
3723     {
3724       reg = udata->reg_or_offset[reg];
3725       if (in_reg_window (reg, udata))
3726         {
3727           udata = sub_udata;
3728           sub_udata = NULL;
3729         }
3730     }
3731   if (udata->saved[reg] == REG_SAVED_OFFSET)
3732     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3733   else
3734     abort ();
3735 }
3736
3737 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3738    frame called by UDATA or 0.  */
3739
3740 static inline void *
3741 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3742 {
3743   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3744 }
3745
3746 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3747
3748 static inline void
3749 put_reg (unsigned reg, void *val, frame_state *udata)
3750 {
3751   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3752 }
3753
3754 /* Copy the saved value for register REG from frame UDATA to frame
3755    TARGET_UDATA.  Unlike the previous two functions, this can handle
3756    registers that are not one word large.  */
3757
3758 static void
3759 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3760 {
3761   word_type *preg = get_reg_addr (reg, udata, NULL);
3762   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3763
3764   memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3765 }
3766
3767 /* Retrieve the return address for frame UDATA.  */
3768
3769 static inline void *
3770 get_return_addr (frame_state *udata, frame_state *sub_udata)
3771 {
3772   return __builtin_extract_return_addr
3773     (get_reg (udata->retaddr_column, udata, sub_udata));
3774 }
3775
3776 /* Overwrite the return address for frame UDATA with VAL.  */
3777
3778 static inline void
3779 put_return_addr (void *val, frame_state *udata)
3780 {
3781   val = __builtin_frob_return_addr (val);
3782   put_reg (udata->retaddr_column, val, udata);
3783 }
3784
3785 /* Given the current frame UDATA and its return address PC, return the
3786    information about the calling frame in CALLER_UDATA.  */
3787
3788 static void *
3789 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3790 {
3791   caller_udata = __frame_state_for (pc, caller_udata);
3792   if (! caller_udata)
3793     return 0;
3794
3795   /* Now go back to our caller's stack frame.  If our caller's CFA register
3796      was saved in our stack frame, restore it; otherwise, assume the CFA
3797      register is SP and restore it to our CFA value.  */
3798   if (udata->saved[caller_udata->cfa_reg])
3799     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3800   else
3801     caller_udata->cfa = udata->cfa;
3802   caller_udata->cfa += caller_udata->cfa_offset;
3803
3804   return caller_udata;
3805 }
3806
3807 /* Hook to call before __terminate if only cleanup handlers remain. */
3808 void 
3809 __unwinding_cleanup (void)
3810 {
3811 }
3812
3813 /* throw_helper performs some of the common grunt work for a throw. This
3814    routine is called by throw and rethrows. This is pretty much split 
3815    out from the old __throw routine. An addition has been added which allows
3816    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3817    but cleanups remaining. This allows a debugger to examine the state
3818    at which the throw was executed, before any cleanups, rather than
3819    at the terminate point after the stack has been unwound.
3820
3821    EH is the current eh_context structure.
3822    PC is the address of the call to __throw.
3823    MY_UDATA is the unwind information for __throw.
3824    OFFSET_P is where we return the SP adjustment offset.  */
3825
3826 static void *
3827 throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
3828               long *offset_p)
3829 {
3830   frame_state ustruct2, *udata = &ustruct2;
3831   frame_state ustruct;
3832   frame_state *sub_udata = &ustruct;
3833   void *saved_pc = pc;
3834   void *handler;
3835   void *handler_p = 0;
3836   void *pc_p = 0;
3837   frame_state saved_ustruct;
3838   int new_eh_model;
3839   int cleanup = 0;
3840   int only_cleanup = 0;
3841   int rethrow = 0;
3842   int saved_state = 0;
3843   long args_size;
3844   __eh_info *eh_info = (__eh_info *)eh->info;
3845
3846   /* Do we find a handler based on a re-throw PC? */
3847   if (eh->table_index != (void *) 0)
3848     rethrow = 1;
3849
3850   memcpy (udata, my_udata, sizeof (*udata));
3851
3852   handler = (void *) 0;
3853   for (;;)
3854     { 
3855       frame_state *p = udata;
3856       udata = next_stack_level (pc, udata, sub_udata);
3857       sub_udata = p;
3858
3859       /* If we couldn't find the next frame, we lose.  */
3860       if (! udata)
3861         break;
3862
3863       if (udata->eh_ptr == NULL)
3864         new_eh_model = 0;
3865       else
3866         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3867                                           runtime_id_field == NEW_EH_RUNTIME);
3868
3869       if (rethrow) 
3870         {
3871           rethrow = 0;
3872           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3873                                           eh_info, 1, &cleanup);
3874           eh->table_index = (void *)0;
3875         }
3876       else
3877         if (new_eh_model)
3878           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3879                                             0, &cleanup);
3880         else
3881           handler = old_find_exception_handler (pc, udata->eh_ptr);
3882
3883       /* If we found one, we can stop searching, if its not a cleanup. 
3884          for cleanups, we save the state, and keep looking. This allows
3885          us to call a debug hook if there are nothing but cleanups left. */
3886       if (handler)
3887         {
3888           if (cleanup)
3889             {
3890               if (!saved_state)
3891                 {
3892                   saved_ustruct = *udata;
3893                   handler_p = handler;
3894                   pc_p = pc;
3895                   saved_state = 1;
3896                   only_cleanup = 1;
3897                 }
3898             }
3899           else
3900             {
3901               only_cleanup = 0;
3902               break;
3903             }
3904         }
3905
3906       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3907          hitting the beginning of the next region.  */
3908       pc = get_return_addr (udata, sub_udata) - 1;
3909     }
3910
3911   if (saved_state) 
3912     {
3913       udata = &saved_ustruct;
3914       handler = handler_p;
3915       pc = pc_p;
3916       if (only_cleanup)
3917         __unwinding_cleanup ();
3918     }
3919
3920   /* If we haven't found a handler by now, this is an unhandled
3921      exception.  */
3922   if (! handler) 
3923     __terminate();
3924
3925   eh->handler_label = handler;
3926
3927   args_size = udata->args_size;
3928
3929   if (pc == saved_pc)
3930     /* We found a handler in the throw context, no need to unwind.  */
3931     udata = my_udata;
3932   else
3933     {
3934       int i;
3935
3936       /* Unwind all the frames between this one and the handler by copying
3937          their saved register values into our register save slots.  */
3938
3939       /* Remember the PC where we found the handler.  */
3940       void *handler_pc = pc;
3941
3942       /* Start from the throw context again.  */
3943       pc = saved_pc;
3944       memcpy (udata, my_udata, sizeof (*udata));
3945
3946       while (pc != handler_pc)
3947         {
3948           frame_state *p = udata;
3949           udata = next_stack_level (pc, udata, sub_udata);
3950           sub_udata = p;
3951
3952           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3953             if (i != udata->retaddr_column && udata->saved[i])
3954               {
3955                 /* If you modify the saved value of the return address
3956                    register on the SPARC, you modify the return address for
3957                    your caller's frame.  Don't do that here, as it will
3958                    confuse get_return_addr.  */
3959                 if (in_reg_window (i, udata)
3960                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3961                     && udata->reg_or_offset[udata->retaddr_column] == i)
3962                   continue;
3963                 copy_reg (i, udata, my_udata);
3964               }
3965
3966           pc = get_return_addr (udata, sub_udata) - 1;
3967         }
3968
3969       /* But we do need to update the saved return address register from
3970          the last frame we unwind, or the handler frame will have the wrong
3971          return address.  */
3972       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3973         {
3974           i = udata->reg_or_offset[udata->retaddr_column];
3975           if (in_reg_window (i, udata))
3976             copy_reg (i, udata, my_udata);
3977         }
3978     }
3979   /* udata now refers to the frame called by the handler frame.  */
3980
3981   /* We adjust SP by the difference between __throw's CFA and the CFA for
3982      the frame called by the handler frame, because those CFAs correspond
3983      to the SP values at the two call sites.  We need to further adjust by
3984      the args_size of the handler frame itself to get the handler frame's
3985      SP from before the args were pushed for that call.  */
3986 #ifdef STACK_GROWS_DOWNWARD
3987   *offset_p = udata->cfa - my_udata->cfa + args_size;
3988 #else
3989   *offset_p = my_udata->cfa - udata->cfa - args_size;
3990 #endif
3991                        
3992   return handler;
3993 }
3994
3995
3996 /* We first search for an exception handler, and if we don't find
3997    it, we call __terminate on the current stack frame so that we may
3998    use the debugger to walk the stack and understand why no handler
3999    was found.
4000
4001    If we find one, then we unwind the frames down to the one that
4002    has the handler and transfer control into the handler.  */
4003
4004 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4005
4006 void
4007 __throw (void)
4008 {
4009   struct eh_context *eh = (*get_eh_context) ();
4010   void *pc, *handler;
4011   long offset;
4012
4013   /* XXX maybe make my_ustruct static so we don't have to look it up for
4014      each throw.  */
4015   frame_state my_ustruct, *my_udata = &my_ustruct;
4016
4017   /* This is required for C++ semantics.  We must call terminate if we
4018      try and rethrow an exception, when there is no exception currently
4019      active.  */
4020   if (! eh->info)
4021     __terminate ();
4022     
4023   /* Start at our stack frame.  */
4024 label:
4025   my_udata = __frame_state_for (&&label, my_udata);
4026   if (! my_udata)
4027     __terminate ();
4028
4029   /* We need to get the value from the CFA register. */
4030   my_udata->cfa = __builtin_dwarf_cfa ();
4031
4032   /* Do any necessary initialization to access arbitrary stack frames.
4033      On the SPARC, this means flushing the register windows.  */
4034   __builtin_unwind_init ();
4035
4036   /* Now reset pc to the right throw point.  */
4037   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4038
4039   handler = throw_helper (eh, pc, my_udata, &offset);
4040
4041   /* Now go!  */
4042
4043   __builtin_eh_return ((void *)eh, offset, handler);
4044
4045   /* Epilogue:  restore the handler frame's register values and return
4046      to the stub.  */
4047 }
4048
4049 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4050
4051 void
4052 __rethrow (void *index)
4053 {
4054   struct eh_context *eh = (*get_eh_context) ();
4055   void *pc, *handler;
4056   long offset;
4057
4058   /* XXX maybe make my_ustruct static so we don't have to look it up for
4059      each throw.  */
4060   frame_state my_ustruct, *my_udata = &my_ustruct;
4061
4062   /* This is required for C++ semantics.  We must call terminate if we
4063      try and rethrow an exception, when there is no exception currently
4064      active.  */
4065   if (! eh->info)
4066     __terminate ();
4067
4068   /* This is the table index we want to rethrow from. The value of
4069      the END_REGION label is used for the PC of the throw, and the
4070      search begins with the next table entry. */
4071   eh->table_index = index;
4072     
4073   /* Start at our stack frame.  */
4074 label:
4075   my_udata = __frame_state_for (&&label, my_udata);
4076   if (! my_udata)
4077     __terminate ();
4078
4079   /* We need to get the value from the CFA register. */
4080   my_udata->cfa = __builtin_dwarf_cfa ();
4081
4082   /* Do any necessary initialization to access arbitrary stack frames.
4083      On the SPARC, this means flushing the register windows.  */
4084   __builtin_unwind_init ();
4085
4086   /* Now reset pc to the right throw point.  */
4087   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4088
4089   handler = throw_helper (eh, pc, my_udata, &offset);
4090
4091   /* Now go!  */
4092
4093   __builtin_eh_return ((void *)eh, offset, handler);
4094
4095   /* Epilogue:  restore the handler frame's register values and return
4096      to the stub.  */
4097 }
4098 #endif /* DWARF2_UNWIND_INFO */
4099
4100 #endif /* L_eh */
4101 \f
4102 #ifdef L_pure
4103 #ifndef inhibit_libc
4104 /* This gets us __GNU_LIBRARY__.  */
4105 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
4106 #include <stdio.h>
4107
4108 #ifdef __GNU_LIBRARY__
4109   /* Avoid forcing the library's meaning of `write' on the user program
4110      by using the "internal" name (for use within the library)  */
4111 #define write(fd, buf, n)       __write((fd), (buf), (n))
4112 #endif
4113 #endif /* inhibit_libc */
4114
4115 #define MESSAGE "pure virtual method called\n"
4116
4117 extern void __terminate (void) __attribute__ ((__noreturn__));
4118
4119 void
4120 __pure_virtual (void)
4121 {
4122 #ifndef inhibit_libc
4123   write (2, MESSAGE, sizeof (MESSAGE) - 1);
4124 #endif
4125   __terminate ();
4126 }
4127 #endif