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