OSDN Git Service

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