OSDN Git Service

2775751aca9e79eae0c3cfdc28044b25a6b1f0cc
[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 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1885    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1886
1887 #define BBINBUFSIZESTR "499"
1888
1889 struct bb_edge
1890 {
1891   struct bb_edge *next;
1892   unsigned long src_addr;
1893   unsigned long dst_addr;
1894   unsigned long count;
1895 };
1896
1897 enum bb_func_mode
1898 {
1899   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1900 };
1901
1902 struct bb_func
1903 {
1904   struct bb_func *next;
1905   char *funcname;
1906   char *filename;
1907   enum bb_func_mode mode;
1908 };
1909
1910 /* This is the connection to the outside world.
1911    The BLOCK_PROFILER macro must set __bb.blocks
1912    and __bb.blockno.  */
1913
1914 struct {
1915   unsigned long blockno;
1916   struct bb *blocks;
1917 } __bb;
1918
1919 /* Vars to store addrs of source and destination basic blocks 
1920    of a jump.  */
1921
1922 static unsigned long bb_src = 0;
1923 static unsigned long bb_dst = 0;
1924
1925 static FILE *bb_tracefile = (FILE *) 0;
1926 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1927 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1928 static unsigned long bb_callcount = 0;
1929 static int bb_mode = 0;
1930
1931 static unsigned long *bb_stack = (unsigned long *) 0;
1932 static size_t bb_stacksize = 0;
1933
1934 static int reported = 0;
1935
1936 /* Trace modes:
1937 Always             :   Print execution frequencies of basic blocks
1938                        to file bb.out.
1939 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1940 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1941 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1942 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1943 */
1944
1945 #ifdef HAVE_POPEN
1946
1947 /*#include <sys/types.h>*/
1948 #include <sys/stat.h>
1949 /*#include <malloc.h>*/
1950
1951 /* Commands executed by gopen.  */
1952
1953 #define GOPENDECOMPRESS "gzip -cd "
1954 #define GOPENCOMPRESS "gzip -c >"
1955
1956 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1957    If it does not compile, simply replace gopen by fopen and delete
1958    '.gz' from any first parameter to gopen.  */
1959
1960 static FILE *
1961 gopen (char *fn, char *mode)
1962 {
1963   int use_gzip;
1964   char *p;
1965
1966   if (mode[1])
1967     return (FILE *) 0;
1968
1969   if (mode[0] != 'r' && mode[0] != 'w') 
1970     return (FILE *) 0;
1971
1972   p = fn + strlen (fn)-1;
1973   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1974               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1975
1976   if (use_gzip)
1977     {
1978       if (mode[0]=='r')
1979         {
1980           FILE *f;
1981           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1982                                      + sizeof (GOPENDECOMPRESS));
1983           strcpy (s, GOPENDECOMPRESS);
1984           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1985           f = popen (s, mode);
1986           free (s);
1987           return f;
1988         }
1989
1990       else
1991         {
1992           FILE *f;
1993           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1994                                      + sizeof (GOPENCOMPRESS));
1995           strcpy (s, GOPENCOMPRESS);
1996           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1997           if (!(f = popen (s, mode)))
1998             f = fopen (s, mode);
1999           free (s);
2000           return f;
2001         }
2002     }
2003
2004   else
2005     return fopen (fn, mode);
2006 }
2007
2008 static int
2009 gclose (FILE *f)
2010 {
2011   struct stat buf;
2012
2013   if (f != 0)
2014     {
2015       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
2016         return pclose (f);
2017
2018       return fclose (f);
2019     }
2020   return 0;
2021 }
2022
2023 #endif /* HAVE_POPEN */
2024
2025 /* Called once per program.  */
2026
2027 static void
2028 __bb_exit_trace_func (void)
2029 {
2030   FILE *file = fopen ("bb.out", "a");
2031   struct bb_func *f;
2032   struct bb *b;
2033         
2034   if (!file)
2035     perror ("bb.out");
2036
2037   if (bb_mode & 1)
2038     {
2039       if (!bb_tracefile)
2040         perror ("bbtrace");
2041       else
2042 #ifdef HAVE_POPEN
2043         gclose (bb_tracefile);
2044 #else
2045         fclose (bb_tracefile);
2046 #endif /* HAVE_POPEN */
2047     }
2048
2049   /* Check functions in `bb.in'.  */
2050
2051   if (file)
2052     {
2053       long time_value;
2054       const struct bb_func *p;
2055       int printed_something = 0;
2056       struct bb *ptr;
2057       long blk;
2058
2059       /* This is somewhat type incorrect.  */
2060       time ((void *) &time_value);
2061
2062       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
2063         {
2064           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
2065             {
2066               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
2067                 continue;
2068               for (blk = 0; blk < ptr->ncounts; blk++)
2069                 {
2070                   if (!strcmp (p->funcname, ptr->functions[blk]))
2071                     goto found;
2072                 }
2073             }
2074   
2075           if (!printed_something)
2076             {
2077               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
2078               printed_something = 1;
2079             }
2080
2081           fprintf (file, "\tFunction %s", p->funcname);
2082           if (p->filename)
2083               fprintf (file, " of file %s", p->filename);
2084           fprintf (file, "\n" );
2085   
2086 found:        ;
2087         }
2088
2089       if (printed_something)
2090        fprintf (file, "\n");
2091
2092     }
2093
2094   if (bb_mode & 2)
2095     {
2096       if (!bb_hashbuckets)
2097         {
2098           if (!reported)
2099             {
2100               fprintf (stderr, "Profiler: out of memory\n");
2101               reported = 1;
2102             }
2103           return;
2104         }
2105     
2106       else if (file)
2107         {
2108           long time_value;
2109           int i;
2110           unsigned long addr_max = 0;
2111           unsigned long cnt_max  = 0;
2112           int cnt_len;
2113           int addr_len;
2114     
2115           /* This is somewhat type incorrect, but it avoids worrying about
2116              exactly where time.h is included from.  It should be ok unless
2117              a void * differs from other pointer formats, or if sizeof (long)
2118              is < sizeof (time_t).  It would be nice if we could assume the
2119              use of rationale standards here.  */
2120     
2121           time ((void *) &time_value);
2122           fprintf (file, "Basic block jump tracing");
2123
2124           switch (bb_mode & 12)
2125             {
2126               case 0:
2127                 fprintf (file, " (with call)");
2128               break;
2129
2130               case 4:
2131                 /* Print nothing.  */
2132               break;
2133
2134               case 8:
2135                 fprintf (file, " (with call & ret)");
2136               break;
2137
2138               case 12:
2139                 fprintf (file, " (with ret)");
2140               break;
2141             }
2142
2143           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2144     
2145           for (i = 0; i < BB_BUCKETS; i++)
2146             {
2147                struct bb_edge *bucket = bb_hashbuckets[i];
2148                for ( ; bucket; bucket = bucket->next )
2149                  {
2150                    if (addr_max < bucket->src_addr) 
2151                      addr_max = bucket->src_addr;
2152                    if (addr_max < bucket->dst_addr) 
2153                      addr_max = bucket->dst_addr;
2154                    if (cnt_max < bucket->count) 
2155                      cnt_max = bucket->count;
2156                  }
2157             }
2158           addr_len = num_digits (addr_max, 16);
2159           cnt_len  = num_digits (cnt_max, 10);
2160     
2161           for ( i = 0; i < BB_BUCKETS; i++)
2162             {
2163                struct bb_edge *bucket = bb_hashbuckets[i];
2164                for ( ; bucket; bucket = bucket->next )
2165                  {
2166                    fprintf (file, "Jump from block 0x%.*lx to "
2167                                   "block 0x%.*lx executed %*lu time(s)\n", 
2168                             addr_len, bucket->src_addr, 
2169                             addr_len, bucket->dst_addr, 
2170                             cnt_len, bucket->count);
2171                  }
2172             }
2173   
2174           fprintf (file, "\n");
2175
2176         }
2177     }
2178
2179    if (file)
2180      fclose (file);
2181
2182    /* Free allocated memory.  */
2183
2184    f = bb_func_head;
2185    while (f)
2186      {
2187        struct bb_func *old = f;
2188
2189        f = f->next;
2190        if (old->funcname) free (old->funcname);
2191        if (old->filename) free (old->filename);
2192        free (old);
2193      }
2194
2195    if (bb_stack)
2196      free (bb_stack);
2197
2198    if (bb_hashbuckets)
2199      {
2200        int i;
2201
2202        for (i = 0; i < BB_BUCKETS; i++)
2203          {
2204            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2205
2206            while (bucket)
2207              {
2208                old = bucket;
2209                bucket = bucket->next;
2210                free (old);
2211              }
2212          }
2213        free (bb_hashbuckets);
2214      }
2215
2216    for (b = bb_head; b; b = b->next)
2217      if (b->flags) free (b->flags);
2218 }
2219
2220 /* Called once per program.  */
2221
2222 static void
2223 __bb_init_prg (void)
2224 {
2225   FILE *file;
2226   char buf[BBINBUFSIZE];
2227   const char *p;
2228   const char *pos;
2229   enum bb_func_mode m;
2230   int i;
2231
2232   /* Initialize destructor.  */
2233   atexit (__bb_exit_func);
2234
2235   if (!(file = fopen ("bb.in", "r")))
2236     return;
2237
2238   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2239     {
2240       p = buf;
2241       if (*p == '-') 
2242         { 
2243           m = TRACE_OFF; 
2244           p++; 
2245         }
2246       else 
2247         { 
2248           m = TRACE_ON; 
2249         }
2250       if (!strcmp (p, "__bb_trace__"))
2251         bb_mode |= 1;
2252       else if (!strcmp (p, "__bb_jumps__"))
2253         bb_mode |= 2;
2254       else if (!strcmp (p, "__bb_hidecall__"))
2255         bb_mode |= 4;
2256       else if (!strcmp (p, "__bb_showret__"))
2257         bb_mode |= 8;
2258       else 
2259         {
2260           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2261           if (f)
2262             {
2263               unsigned long l;
2264               f->next = bb_func_head;
2265               if ((pos = strchr (p, ':')))
2266                 {
2267                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2268                     continue;
2269                   strcpy (f->funcname, pos+1);
2270                   l = pos-p;
2271                   if ((f->filename = (char *) malloc (l+1)))
2272                     {
2273                       strncpy (f->filename, p, l);
2274                       f->filename[l] = '\0';
2275                     }
2276                   else
2277                     f->filename = (char *) 0;
2278                 }
2279               else
2280                 {
2281                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2282                     continue;
2283                   strcpy (f->funcname, p);
2284                   f->filename = (char *) 0;
2285                 }
2286               f->mode = m;
2287               bb_func_head = f;
2288             }
2289          }
2290     }
2291   fclose (file);
2292
2293 #ifdef HAVE_POPEN 
2294
2295   if (bb_mode & 1)
2296       bb_tracefile = gopen ("bbtrace.gz", "w");
2297
2298 #else
2299
2300   if (bb_mode & 1)
2301       bb_tracefile = fopen ("bbtrace", "w");
2302
2303 #endif /* HAVE_POPEN */
2304
2305   if (bb_mode & 2)
2306     {
2307       bb_hashbuckets = (struct bb_edge **) 
2308                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2309       if (bb_hashbuckets)
2310         /* Use a loop here rather than calling bzero to avoid having to
2311            conditionalize its existance.  */
2312         for (i = 0; i < BB_BUCKETS; i++)
2313           bb_hashbuckets[i] = 0;
2314     }
2315
2316   if (bb_mode & 12)
2317     {
2318       bb_stacksize = 10;
2319       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2320     }
2321
2322   /* Initialize destructor.  */
2323   atexit (__bb_exit_trace_func);
2324 }
2325
2326 /* Called upon entering a basic block.  */
2327
2328 void
2329 __bb_trace_func (void)
2330 {
2331   struct bb_edge *bucket;
2332
2333   MACHINE_STATE_SAVE("1")
2334
2335   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2336     goto skip;
2337
2338   bb_dst = __bb.blocks->addresses[__bb.blockno];
2339   __bb.blocks->counts[__bb.blockno]++;
2340
2341   if (bb_tracefile)
2342     {
2343       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2344     }
2345
2346   if (bb_hashbuckets)
2347     {
2348       struct bb_edge **startbucket, **oldnext;
2349
2350       oldnext = startbucket
2351         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2352       bucket = *startbucket;
2353
2354       for (bucket = *startbucket; bucket; 
2355            oldnext = &(bucket->next), bucket = *oldnext)
2356         {
2357           if (bucket->src_addr == bb_src
2358               && bucket->dst_addr == bb_dst)
2359             {
2360               bucket->count++;
2361               *oldnext = bucket->next;
2362               bucket->next = *startbucket;
2363               *startbucket = bucket;
2364               goto ret;
2365             }
2366         }
2367
2368       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2369
2370       if (!bucket)
2371         {
2372           if (!reported)
2373             {
2374               fprintf (stderr, "Profiler: out of memory\n");
2375               reported = 1;
2376             }
2377         }
2378
2379       else
2380         {
2381           bucket->src_addr = bb_src;
2382           bucket->dst_addr = bb_dst;
2383           bucket->next = *startbucket;
2384           *startbucket = bucket;
2385           bucket->count = 1;
2386         }
2387     }
2388
2389 ret:
2390   bb_src = bb_dst;
2391
2392 skip:
2393   ;
2394
2395   MACHINE_STATE_RESTORE("1")
2396
2397 }
2398
2399 /* Called when returning from a function and `__bb_showret__' is set.  */
2400
2401 static void
2402 __bb_trace_func_ret (void)
2403 {
2404   struct bb_edge *bucket;
2405
2406   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2407     goto skip;
2408
2409   if (bb_hashbuckets)
2410     {
2411       struct bb_edge **startbucket, **oldnext;
2412
2413       oldnext = startbucket
2414         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2415       bucket = *startbucket;
2416
2417       for (bucket = *startbucket; bucket; 
2418            oldnext = &(bucket->next), bucket = *oldnext)
2419         {
2420           if (bucket->src_addr == bb_dst
2421                && bucket->dst_addr == bb_src)
2422             {
2423               bucket->count++;
2424               *oldnext = bucket->next;
2425               bucket->next = *startbucket;
2426               *startbucket = bucket;
2427               goto ret;
2428             }
2429         }
2430
2431       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2432
2433       if (!bucket)
2434         {
2435           if (!reported)
2436             {
2437               fprintf (stderr, "Profiler: out of memory\n");
2438               reported = 1;
2439             }
2440         }
2441
2442       else
2443         {
2444           bucket->src_addr = bb_dst;
2445           bucket->dst_addr = bb_src;
2446           bucket->next = *startbucket;
2447           *startbucket = bucket;
2448           bucket->count = 1;
2449         }
2450     }
2451
2452 ret:
2453   bb_dst = bb_src;
2454
2455 skip:
2456   ;
2457
2458 }
2459
2460 /* Called upon entering the first function of a file.  */
2461
2462 static void
2463 __bb_init_file (struct bb *blocks)
2464 {
2465
2466   const struct bb_func *p;
2467   long blk, ncounts = blocks->ncounts;
2468   const char **functions = blocks->functions;
2469
2470   /* Set up linked list.  */
2471   blocks->zero_word = 1;
2472   blocks->next = bb_head;
2473   bb_head = blocks;
2474
2475   blocks->flags = 0;
2476   if (!bb_func_head
2477       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2478     return;
2479
2480   for (blk = 0; blk < ncounts; blk++)
2481     blocks->flags[blk] = 0;
2482
2483   for (blk = 0; blk < ncounts; blk++)
2484     {
2485       for (p = bb_func_head; p; p = p->next)
2486         {
2487           if (!strcmp (p->funcname, functions[blk])
2488               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2489             {
2490               blocks->flags[blk] |= p->mode;
2491             }
2492         }
2493     }
2494
2495 }
2496
2497 /* Called when exiting from a function.  */
2498
2499 void
2500 __bb_trace_ret (void)
2501 {
2502
2503   MACHINE_STATE_SAVE("2")
2504
2505   if (bb_callcount)
2506     {
2507       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2508         {
2509           bb_src = bb_stack[bb_callcount];
2510           if (bb_mode & 8)
2511             __bb_trace_func_ret ();
2512         }
2513
2514       bb_callcount -= 1;
2515     }
2516
2517   MACHINE_STATE_RESTORE("2")
2518
2519 }
2520
2521 /* Called when entering a function.  */
2522
2523 void
2524 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2525 {
2526   static int trace_init = 0;
2527
2528   MACHINE_STATE_SAVE("3")
2529
2530   if (!blocks->zero_word)
2531     { 
2532       if (!trace_init)
2533         { 
2534           trace_init = 1;
2535           __bb_init_prg ();
2536         }
2537       __bb_init_file (blocks);
2538     }
2539
2540   if (bb_callcount)
2541     {
2542
2543       bb_callcount += 1;
2544
2545       if (bb_mode & 12)
2546         {
2547           if (bb_callcount >= bb_stacksize)
2548             {
2549               size_t newsize = bb_callcount + 100;
2550
2551               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2552               if (! bb_stack)
2553                 {
2554                   if (!reported)
2555                     {
2556                       fprintf (stderr, "Profiler: out of memory\n");
2557                       reported = 1;
2558                     }
2559                   bb_stacksize = 0;
2560                   goto stack_overflow;
2561                 }
2562               bb_stacksize = newsize;
2563             }
2564           bb_stack[bb_callcount] = bb_src;
2565
2566           if (bb_mode & 4)
2567             bb_src = 0;
2568
2569         }
2570
2571 stack_overflow:;
2572
2573     }
2574
2575   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2576     {
2577       bb_callcount = 1;
2578       bb_src = 0;
2579
2580       if (bb_stack)
2581           bb_stack[bb_callcount] = bb_src;
2582     }
2583
2584   MACHINE_STATE_RESTORE("3")
2585 }
2586
2587 #endif /* not inhibit_libc */
2588 #endif /* not BLOCK_PROFILER_CODE */
2589 #endif /* L_bb */
2590 \f
2591 #ifdef L_shtab
2592 unsigned int __shtab[] = {
2593     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2594     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2595     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2596     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2597     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2598     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2599     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2600     0x10000000, 0x20000000, 0x40000000, 0x80000000
2601   };
2602 #endif
2603 \f
2604 #ifdef L_clear_cache
2605 /* Clear part of an instruction cache.  */
2606
2607 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2608
2609 void
2610 __clear_cache (char *beg __attribute__((__unused__)),
2611                char *end __attribute__((__unused__)))
2612 {
2613 #ifdef CLEAR_INSN_CACHE 
2614   CLEAR_INSN_CACHE (beg, end);
2615 #else
2616 #ifdef INSN_CACHE_SIZE
2617   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2618   static int initialized;
2619   int offset;
2620   void *start_addr
2621   void *end_addr;
2622   typedef (*function_ptr) (void);
2623
2624 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2625   /* It's cheaper to clear the whole cache.
2626      Put in a series of jump instructions so that calling the beginning
2627      of the cache will clear the whole thing.  */
2628
2629   if (! initialized)
2630     {
2631       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2632                  & -INSN_CACHE_LINE_WIDTH);
2633       int end_ptr = ptr + INSN_CACHE_SIZE;
2634
2635       while (ptr < end_ptr)
2636         {
2637           *(INSTRUCTION_TYPE *)ptr
2638             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2639           ptr += INSN_CACHE_LINE_WIDTH;
2640         }
2641       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2642
2643       initialized = 1;
2644     }
2645
2646   /* Call the beginning of the sequence.  */
2647   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2648                     & -INSN_CACHE_LINE_WIDTH))
2649    ());
2650
2651 #else /* Cache is large.  */
2652
2653   if (! initialized)
2654     {
2655       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2656                  & -INSN_CACHE_LINE_WIDTH);
2657
2658       while (ptr < (int) array + sizeof array)
2659         {
2660           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2661           ptr += INSN_CACHE_LINE_WIDTH;
2662         }
2663
2664       initialized = 1;
2665     }
2666
2667   /* Find the location in array that occupies the same cache line as BEG.  */
2668
2669   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2670   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2671                  & -INSN_CACHE_PLANE_SIZE)
2672                 + offset);
2673
2674   /* Compute the cache alignment of the place to stop clearing.  */
2675 #if 0  /* This is not needed for gcc's purposes.  */
2676   /* If the block to clear is bigger than a cache plane,
2677      we clear the entire cache, and OFFSET is already correct.  */ 
2678   if (end < beg + INSN_CACHE_PLANE_SIZE)
2679 #endif
2680     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2681                & -INSN_CACHE_LINE_WIDTH)
2682               & (INSN_CACHE_PLANE_SIZE - 1));
2683
2684 #if INSN_CACHE_DEPTH > 1
2685   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2686   if (end_addr <= start_addr)
2687     end_addr += INSN_CACHE_PLANE_SIZE;
2688
2689   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2690     {
2691       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2692       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2693
2694       while (addr != stop)
2695         {
2696           /* Call the return instruction at ADDR.  */
2697           ((function_ptr) addr) ();
2698
2699           addr += INSN_CACHE_LINE_WIDTH;
2700         }
2701     }
2702 #else /* just one plane */
2703   do
2704     {
2705       /* Call the return instruction at START_ADDR.  */
2706       ((function_ptr) start_addr) ();
2707
2708       start_addr += INSN_CACHE_LINE_WIDTH;
2709     }
2710   while ((start_addr % INSN_CACHE_SIZE) != offset);
2711 #endif /* just one plane */
2712 #endif /* Cache is large */
2713 #endif /* Cache exists */
2714 #endif /* CLEAR_INSN_CACHE */
2715 }
2716
2717 #endif /* L_clear_cache */
2718 \f
2719 #ifdef L_trampoline
2720
2721 /* Jump to a trampoline, loading the static chain address.  */
2722
2723 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2724
2725 long
2726 getpagesize (void)
2727 {
2728 #ifdef _ALPHA_
2729   return 8192;
2730 #else
2731   return 4096;
2732 #endif
2733 }
2734
2735 #ifdef __i386__
2736 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2737 #endif
2738
2739 int
2740 mprotect (char *addr, int len, int prot)
2741 {
2742   int np, op;
2743
2744   if (prot == 7)
2745     np = 0x40;
2746   else if (prot == 5)
2747     np = 0x20;
2748   else if (prot == 4)
2749     np = 0x10;
2750   else if (prot == 3)
2751     np = 0x04;
2752   else if (prot == 1)
2753     np = 0x02;
2754   else if (prot == 0)
2755     np = 0x01;
2756
2757   if (VirtualProtect (addr, len, np, &op))
2758     return 0;
2759   else
2760     return -1;
2761 }
2762
2763 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2764
2765 #ifdef TRANSFER_FROM_TRAMPOLINE 
2766 TRANSFER_FROM_TRAMPOLINE 
2767 #endif
2768
2769 #if defined (NeXT) && defined (__MACH__)
2770
2771 /* Make stack executable so we can call trampolines on stack.
2772    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2773 #ifdef NeXTStep21
2774  #include <mach.h>
2775 #else
2776  #include <mach/mach.h>
2777 #endif
2778
2779 void
2780 __enable_execute_stack (char *addr)
2781 {
2782   kern_return_t r;
2783   char *eaddr = addr + TRAMPOLINE_SIZE;
2784   vm_address_t a = (vm_address_t) addr;
2785
2786   /* turn on execute access on stack */
2787   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2788   if (r != KERN_SUCCESS)
2789     {
2790       mach_error("vm_protect VM_PROT_ALL", r);
2791       exit(1);
2792     }
2793
2794   /* We inline the i-cache invalidation for speed */
2795
2796 #ifdef CLEAR_INSN_CACHE
2797   CLEAR_INSN_CACHE (addr, eaddr);
2798 #else
2799   __clear_cache ((int) addr, (int) eaddr);
2800 #endif
2801
2802
2803 #endif /* defined (NeXT) && defined (__MACH__) */
2804
2805 #ifdef __convex__
2806
2807 /* Make stack executable so we can call trampolines on stack.
2808    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2809
2810 #include <sys/mman.h>
2811 #include <sys/vmparam.h>
2812 #include <machine/machparam.h>
2813
2814 void
2815 __enable_execute_stack (void)
2816 {
2817   int fp;
2818   static unsigned lowest = USRSTACK;
2819   unsigned current = (unsigned) &fp & -NBPG;
2820
2821   if (lowest > current)
2822     {
2823       unsigned len = lowest - current;
2824       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2825       lowest = current;
2826     }
2827
2828   /* Clear instruction cache in case an old trampoline is in it.  */
2829   asm ("pich");
2830 }
2831 #endif /* __convex__ */
2832
2833 #ifdef __sysV88__
2834
2835 /* Modified from the convex -code above.  */
2836
2837 #include <sys/param.h>
2838 #include <errno.h>
2839 #include <sys/m88kbcs.h>
2840
2841 void
2842 __enable_execute_stack (void)
2843 {
2844   int save_errno;
2845   static unsigned long lowest = USRSTACK;
2846   unsigned long current = (unsigned long) &save_errno & -NBPC;
2847   
2848   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2849      address is seen as 'negative'. That is the case with the stack.   */
2850
2851   save_errno=errno;
2852   if (lowest > current)
2853     {
2854       unsigned len=lowest-current;
2855       memctl(current,len,MCT_TEXT);
2856       lowest = current;
2857     }
2858   else
2859     memctl(current,NBPC,MCT_TEXT);
2860   errno=save_errno;
2861 }
2862
2863 #endif /* __sysV88__ */
2864
2865 #ifdef __sysV68__
2866
2867 #include <sys/signal.h>
2868 #include <errno.h>
2869
2870 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2871    so define it here, because we need it in __clear_insn_cache below */
2872 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2873    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2874
2875 #ifdef MCT_TEXT
2876 asm("\n\
2877         global memctl\n\
2878 memctl:\n\
2879         movq &75,%d0\n\
2880         trap &0\n\
2881         bcc.b noerror\n\
2882         jmp cerror%\n\
2883 noerror:\n\
2884         movq &0,%d0\n\
2885         rts");
2886 #endif
2887
2888 /* Clear instruction cache so we can call trampolines on stack.
2889    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2890
2891 void
2892 __clear_insn_cache (void)
2893 {
2894 #ifdef MCT_TEXT
2895   int save_errno;
2896
2897   /* Preserve errno, because users would be surprised to have
2898   errno changing without explicitly calling any system-call. */
2899   save_errno = errno;
2900
2901   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2902      No need to use an address derived from _start or %sp, as 0 works also. */
2903   memctl(0, 4096, MCT_TEXT);
2904   errno = save_errno;
2905 #endif
2906 }
2907
2908 #endif /* __sysV68__ */
2909
2910 #ifdef __pyr__
2911
2912 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2913 #include <stdio.h>
2914 #include <sys/mman.h>
2915 #include <sys/types.h>
2916 #include <sys/param.h>
2917 #include <sys/vmmac.h>
2918
2919 /* Modified from the convex -code above.
2920    mremap promises to clear the i-cache.  */
2921
2922 void
2923 __enable_execute_stack (void)
2924 {
2925   int fp;
2926   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2927                 PROT_READ|PROT_WRITE|PROT_EXEC))
2928     {
2929       perror ("mprotect in __enable_execute_stack");
2930       fflush (stderr);
2931       abort ();
2932     }
2933 }
2934 #endif /* __pyr__ */
2935
2936 #if defined (sony_news) && defined (SYSTYPE_BSD)
2937
2938 #include <stdio.h>
2939 #include <sys/types.h>
2940 #include <sys/param.h>
2941 #include <syscall.h>
2942 #include <machine/sysnews.h>
2943
2944 /* cacheflush function for NEWS-OS 4.2.
2945    This function is called from trampoline-initialize code
2946    defined in config/mips/mips.h.  */
2947
2948 void
2949 cacheflush (char *beg, int size, int flag)
2950 {
2951   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2952     {
2953       perror ("cache_flush");
2954       fflush (stderr);
2955       abort ();
2956     }
2957 }
2958
2959 #endif /* sony_news */
2960 #endif /* L_trampoline */
2961 \f
2962 #ifndef __CYGWIN__
2963 #ifdef L__main
2964
2965 #include "gbl-ctors.h"
2966 /* Some systems use __main in a way incompatible with its use in gcc, in these
2967    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2968    give the same symbol without quotes for an alternative entry point.  You
2969    must define both, or neither.  */
2970 #ifndef NAME__MAIN
2971 #define NAME__MAIN "__main"
2972 #define SYMBOL__MAIN __main
2973 #endif
2974
2975 #ifdef INIT_SECTION_ASM_OP
2976 #undef HAS_INIT_SECTION
2977 #define HAS_INIT_SECTION
2978 #endif
2979
2980 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2981
2982 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2983    code to run constructors.  In that case, we need to handle EH here, too.  */
2984
2985 #ifdef EH_FRAME_SECTION
2986 #include "frame.h"
2987 extern unsigned char __EH_FRAME_BEGIN__[];
2988 #endif
2989
2990 /* Run all the global destructors on exit from the program.  */
2991
2992 void
2993 __do_global_dtors (void)
2994 {
2995 #ifdef DO_GLOBAL_DTORS_BODY
2996   DO_GLOBAL_DTORS_BODY;
2997 #else
2998   static func_ptr *p = __DTOR_LIST__ + 1;
2999   while (*p)
3000     {
3001       p++;
3002       (*(p-1)) ();
3003     }
3004 #endif
3005 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
3006   {
3007     static int completed = 0;
3008     if (! completed)
3009       {
3010         completed = 1;
3011         __deregister_frame_info (__EH_FRAME_BEGIN__);
3012       }
3013   }
3014 #endif
3015 }
3016 #endif
3017
3018 #ifndef HAS_INIT_SECTION
3019 /* Run all the global constructors on entry to the program.  */
3020
3021 void
3022 __do_global_ctors (void)
3023 {
3024 #ifdef EH_FRAME_SECTION
3025   {
3026     static struct object object;
3027     __register_frame_info (__EH_FRAME_BEGIN__, &object);
3028   }
3029 #endif
3030   DO_GLOBAL_CTORS_BODY;
3031   atexit (__do_global_dtors);
3032 }
3033 #endif /* no HAS_INIT_SECTION */
3034
3035 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
3036 /* Subroutine called automatically by `main'.
3037    Compiling a global function named `main'
3038    produces an automatic call to this function at the beginning.
3039
3040    For many systems, this routine calls __do_global_ctors.
3041    For systems which support a .init section we use the .init section
3042    to run __do_global_ctors, so we need not do anything here.  */
3043
3044 void
3045 SYMBOL__MAIN ()
3046 {
3047   /* Support recursive calls to `main': run initializers just once.  */
3048   static int initialized;
3049   if (! initialized)
3050     {
3051       initialized = 1;
3052       __do_global_ctors ();
3053     }
3054 }
3055 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3056
3057 #endif /* L__main */
3058 #endif /* __CYGWIN__ */
3059 \f
3060 #ifdef L_ctors
3061
3062 #include "gbl-ctors.h"
3063
3064 /* Provide default definitions for the lists of constructors and
3065    destructors, so that we don't get linker errors.  These symbols are
3066    intentionally bss symbols, so that gld and/or collect will provide
3067    the right values.  */
3068
3069 /* We declare the lists here with two elements each,
3070    so that they are valid empty lists if no other definition is loaded.
3071
3072    If we are using the old "set" extensions to have the gnu linker
3073    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3074    must be in the bss/common section.
3075
3076    Long term no port should use those extensions.  But many still do.  */
3077 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3078 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3079 func_ptr __CTOR_LIST__[2] = {0, 0};
3080 func_ptr __DTOR_LIST__[2] = {0, 0};
3081 #else
3082 func_ptr __CTOR_LIST__[2];
3083 func_ptr __DTOR_LIST__[2];
3084 #endif
3085 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3086 #endif /* L_ctors */
3087 \f
3088 #ifdef L_exit
3089
3090 #include "gbl-ctors.h"
3091
3092 #ifdef NEED_ATEXIT
3093
3094 #ifndef ON_EXIT
3095
3096 # include <errno.h>
3097
3098 static func_ptr *atexit_chain = 0;
3099 static long atexit_chain_length = 0;
3100 static volatile long last_atexit_chain_slot = -1;
3101
3102 int
3103 atexit (func_ptr func)
3104 {
3105   if (++last_atexit_chain_slot == atexit_chain_length)
3106     {
3107       atexit_chain_length += 32;
3108       if (atexit_chain)
3109         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3110                                              * sizeof (func_ptr));
3111       else
3112         atexit_chain = (func_ptr *) malloc (atexit_chain_length
3113                                             * sizeof (func_ptr));
3114       if (! atexit_chain)
3115         {
3116           atexit_chain_length = 0;
3117           last_atexit_chain_slot = -1;
3118           errno = ENOMEM;
3119           return (-1);
3120         }
3121     }
3122   atexit_chain[last_atexit_chain_slot] = func;
3123   return (0);
3124 }
3125
3126 extern void _cleanup (void);
3127 extern void _exit (int) __attribute__ ((__noreturn__));
3128
3129 void 
3130 exit (int status)
3131 {
3132   if (atexit_chain)
3133     {
3134       for ( ; last_atexit_chain_slot-- >= 0; )
3135         {
3136           (*atexit_chain[last_atexit_chain_slot + 1]) ();
3137           atexit_chain[last_atexit_chain_slot + 1] = 0;
3138         }
3139       free (atexit_chain);
3140       atexit_chain = 0;
3141     }
3142 #ifdef EXIT_BODY
3143   EXIT_BODY;
3144 #else
3145   _cleanup ();
3146 #endif
3147   _exit (status);
3148 }
3149
3150 #else /* ON_EXIT */
3151
3152 /* Simple; we just need a wrapper for ON_EXIT.  */
3153 int
3154 atexit (func_ptr func)
3155 {
3156   return ON_EXIT (func);
3157 }
3158
3159 #endif /* ON_EXIT */
3160 #endif /* NEED_ATEXIT */
3161
3162 #endif /* L_exit */
3163 \f
3164 #ifdef L_eh
3165
3166 #include "gthr.h"
3167
3168 /* Shared exception handling support routines.  */
3169
3170 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3171
3172 void
3173 __default_terminate (void)
3174 {
3175   abort ();
3176 }
3177
3178 void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
3179   __default_terminate;
3180
3181 void
3182 __terminate (void)
3183 {
3184   (*__terminate_func)();
3185 }
3186
3187 void *
3188 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3189 {
3190 #if 0
3191  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3192          catch_type, throw_type);
3193 #endif
3194  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3195    return obj;
3196  return 0;
3197 }
3198
3199 void
3200 __empty (void)
3201 {
3202 }
3203 \f
3204
3205 /* Include definitions of EH context and table layout */
3206
3207 #include "eh-common.h"
3208 #ifndef inhibit_libc
3209 #include <stdio.h>
3210 #endif
3211
3212 /* Allocate and return a new EH context structure. */
3213
3214 extern void __throw (void);
3215
3216 #if __GTHREADS
3217 static void *
3218 new_eh_context (void)
3219 {
3220   struct eh_full_context {
3221     struct eh_context c;
3222     void *top_elt[2];
3223   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3224
3225   if (! ehfc)
3226     __terminate ();
3227
3228   memset (ehfc, 0, sizeof *ehfc);
3229
3230   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3231
3232   /* This should optimize out entirely.  This should always be true,
3233      but just in case it ever isn't, don't allow bogus code to be
3234      generated.  */
3235
3236   if ((void*)(&ehfc->c) != (void*)ehfc)
3237     __terminate ();
3238
3239   return &ehfc->c;
3240 }
3241
3242 static __gthread_key_t eh_context_key;
3243
3244 /* Destructor for struct eh_context. */
3245 static void
3246 eh_context_free (void *ptr)
3247 {
3248   __gthread_key_dtor (eh_context_key, ptr);
3249   if (ptr)
3250     free (ptr);
3251 }
3252 #endif
3253
3254 /* Pointer to function to return EH context. */
3255
3256 static struct eh_context *eh_context_initialize (void);
3257 static struct eh_context *eh_context_static (void);
3258 #if __GTHREADS
3259 static struct eh_context *eh_context_specific (void);
3260 #endif
3261
3262 static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
3263
3264 /* Routine to get EH context.
3265    This one will simply call the function pointer. */
3266
3267 void *
3268 __get_eh_context (void)
3269 {
3270   return (void *) (*get_eh_context) ();
3271 }
3272
3273 /* Get and set the language specific info pointer. */
3274
3275 void **
3276 __get_eh_info (void)
3277 {
3278   struct eh_context *eh = (*get_eh_context) ();
3279   return &eh->info;
3280 }
3281 \f
3282 #ifdef DWARF2_UNWIND_INFO
3283 static int dwarf_reg_size_table_initialized = 0;
3284 static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
3285
3286 static void
3287 init_reg_size_table (void)
3288 {
3289   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3290   dwarf_reg_size_table_initialized = 1;
3291 }
3292 #endif
3293
3294 #if __GTHREADS
3295 static void
3296 eh_threads_initialize (void)
3297 {
3298   /* Try to create the key.  If it fails, revert to static method,
3299      otherwise start using thread specific EH contexts. */
3300   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3301     get_eh_context = &eh_context_specific;
3302   else
3303     get_eh_context = &eh_context_static;
3304 }
3305 #endif /* no __GTHREADS */
3306
3307 /* Initialize EH context.
3308    This will be called only once, since we change GET_EH_CONTEXT
3309    pointer to another routine. */
3310
3311 static struct eh_context *
3312 eh_context_initialize (void)
3313 {
3314 #if __GTHREADS
3315
3316   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3317   /* Make sure that get_eh_context does not point to us anymore.
3318      Some systems have dummy thread routines in their libc that
3319      return a success (Solaris 2.6 for example). */
3320   if (__gthread_once (&once, eh_threads_initialize) != 0
3321       || get_eh_context == &eh_context_initialize)
3322     {
3323       /* Use static version of EH context. */
3324       get_eh_context = &eh_context_static;
3325     }
3326 #ifdef DWARF2_UNWIND_INFO
3327   {
3328     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3329     if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3330         || ! dwarf_reg_size_table_initialized)
3331       init_reg_size_table ();
3332   }
3333 #endif
3334
3335 #else /* no __GTHREADS */
3336
3337   /* Use static version of EH context. */
3338   get_eh_context = &eh_context_static;
3339
3340 #ifdef DWARF2_UNWIND_INFO
3341   init_reg_size_table ();
3342 #endif
3343
3344 #endif /* no __GTHREADS */
3345
3346   return (*get_eh_context) ();
3347 }
3348
3349 /* Return a static EH context. */
3350
3351 static struct eh_context *
3352 eh_context_static (void)
3353 {
3354   static struct eh_context eh;
3355   static int initialized;
3356   static void *top_elt[2];
3357
3358   if (! initialized)
3359     {
3360       initialized = 1;
3361       memset (&eh, 0, sizeof eh);
3362       eh.dynamic_handler_chain = top_elt;
3363     }
3364   return &eh;
3365 }
3366
3367 #if __GTHREADS
3368 /* Return a thread specific EH context. */
3369
3370 static struct eh_context *
3371 eh_context_specific (void)
3372 {
3373   struct eh_context *eh;
3374   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3375   if (! eh)
3376     {
3377       eh = new_eh_context ();
3378       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3379         __terminate ();
3380     }
3381
3382   return eh;
3383 }
3384 #endif __GTHREADS
3385 \f
3386 /* Support routines for setjmp/longjmp exception handling.  */
3387
3388 /* Calls to __sjthrow are generated by the compiler when an exception
3389    is raised when using the setjmp/longjmp exception handling codegen
3390    method.  */
3391
3392 #ifdef DONT_USE_BUILTIN_SETJMP
3393 extern void longjmp (void *, int);
3394 #endif
3395
3396 /* Routine to get the head of the current thread's dynamic handler chain
3397    use for exception handling. */
3398
3399 void ***
3400 __get_dynamic_handler_chain (void)
3401 {
3402   struct eh_context *eh = (*get_eh_context) ();
3403   return &eh->dynamic_handler_chain;
3404 }
3405
3406 /* This is used to throw an exception when the setjmp/longjmp codegen
3407    method is used for exception handling.
3408
3409    We call __terminate if there are no handlers left.  Otherwise we run the
3410    cleanup actions off the dynamic cleanup stack, and pop the top of the
3411    dynamic handler chain, and use longjmp to transfer back to the associated
3412    handler.  */
3413
3414 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3415
3416 void
3417 __sjthrow (void)
3418 {
3419   struct eh_context *eh = (*get_eh_context) ();
3420   void ***dhc = &eh->dynamic_handler_chain;
3421   void *jmpbuf;
3422   void (*func)(void *, int);
3423   void *arg;
3424   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3425   void ***cleanup = (void***)&(*dhc)[1];
3426
3427   /* If there are any cleanups in the chain, run them now.  */
3428   if (cleanup[0])
3429     {
3430       double store[200];
3431       void **buf = (void**)store;
3432       buf[1] = 0;
3433       buf[0] = (*dhc);
3434
3435       /* try { */
3436 #ifdef DONT_USE_BUILTIN_SETJMP
3437       if (! setjmp (&buf[2]))
3438 #else
3439       if (! __builtin_setjmp (&buf[2]))
3440 #endif
3441         {
3442           *dhc = buf;
3443           while (cleanup[0])
3444             {
3445               func = (void(*)(void*, int))cleanup[0][1];
3446               arg = (void*)cleanup[0][2];
3447
3448               /* Update this before running the cleanup.  */
3449               cleanup[0] = (void **)cleanup[0][0];
3450
3451               (*func)(arg, 2);
3452             }
3453           *dhc = buf[0];
3454         }
3455       /* catch (...) */
3456       else
3457         {
3458           __terminate ();
3459         }
3460     }
3461   
3462   /* We must call terminate if we try and rethrow an exception, when
3463      there is no exception currently active and when there are no
3464      handlers left.  */
3465   if (! eh->info || (*dhc)[0] == 0)
3466     __terminate ();
3467     
3468   /* Find the jmpbuf associated with the top element of the dynamic
3469      handler chain.  The jumpbuf starts two words into the buffer.  */
3470   jmpbuf = &(*dhc)[2];
3471
3472   /* Then we pop the top element off the dynamic handler chain.  */
3473   *dhc = (void**)(*dhc)[0];
3474
3475   /* And then we jump to the handler.  */
3476
3477 #ifdef DONT_USE_BUILTIN_SETJMP
3478   longjmp (jmpbuf, 1);
3479 #else
3480   __builtin_longjmp (jmpbuf, 1);
3481 #endif
3482 }
3483
3484 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3485    handler, then pop the handler off the dynamic handler stack, and
3486    then throw.  This is used to skip the first handler, and transfer
3487    control to the next handler in the dynamic handler stack.  */
3488
3489 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3490
3491 void
3492 __sjpopnthrow (void)
3493 {
3494   struct eh_context *eh = (*get_eh_context) ();
3495   void ***dhc = &eh->dynamic_handler_chain;
3496   void (*func)(void *, int);
3497   void *arg;
3498   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3499   void ***cleanup = (void***)&(*dhc)[1];
3500
3501   /* If there are any cleanups in the chain, run them now.  */
3502   if (cleanup[0])
3503     {
3504       double store[200];
3505       void **buf = (void**)store;
3506       buf[1] = 0;
3507       buf[0] = (*dhc);
3508
3509       /* try { */
3510 #ifdef DONT_USE_BUILTIN_SETJMP
3511       if (! setjmp (&buf[2]))
3512 #else
3513       if (! __builtin_setjmp (&buf[2]))
3514 #endif
3515         {
3516           *dhc = buf;
3517           while (cleanup[0])
3518             {
3519               func = (void(*)(void*, int))cleanup[0][1];
3520               arg = (void*)cleanup[0][2];
3521
3522               /* Update this before running the cleanup.  */
3523               cleanup[0] = (void **)cleanup[0][0];
3524
3525               (*func)(arg, 2);
3526             }
3527           *dhc = buf[0];
3528         }
3529       /* catch (...) */
3530       else
3531         {
3532           __terminate ();
3533         }
3534     }
3535
3536   /* Then we pop the top element off the dynamic handler chain.  */
3537   *dhc = (void**)(*dhc)[0];
3538
3539   __sjthrow ();
3540 }
3541 \f
3542 /* Support code for all exception region-based exception handling.  */
3543
3544 int
3545 __eh_rtime_match (void *rtime)
3546 {
3547   void *info;
3548   __eh_matcher matcher;
3549   void *ret;
3550
3551   info = *(__get_eh_info ());
3552   matcher = ((__eh_info *)info)->match_function;
3553   if (! matcher)
3554     {
3555 #ifndef inhibit_libc
3556       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3557 #endif
3558       return 0;
3559     }
3560   ret = (*matcher) (info, rtime, (void *)0);
3561   return (ret != NULL);
3562 }
3563
3564 /* This value identifies the place from which an exception is being
3565    thrown.  */
3566
3567 #ifdef EH_TABLE_LOOKUP
3568
3569 EH_TABLE_LOOKUP
3570
3571 #else
3572
3573 #ifdef DWARF2_UNWIND_INFO
3574
3575 /* Return the table version of an exception descriptor */
3576
3577 short 
3578 __get_eh_table_version (exception_descriptor *table) 
3579 {
3580   return table->lang.version;
3581 }
3582
3583 /* Return the originating table language of an exception descriptor */
3584
3585 short 
3586 __get_eh_table_language (exception_descriptor *table)
3587 {
3588   return table->lang.language;
3589 }
3590
3591 /* This routine takes a PC and a pointer to the exception region TABLE for
3592    its translation unit, and returns the address of the exception handler
3593    associated with the closest exception table handler entry associated
3594    with that PC, or 0 if there are no table entries the PC fits in.
3595
3596    In the advent of a tie, we have to give the last entry, as it represents
3597    an inner block.  */
3598
3599 static void *
3600 old_find_exception_handler (void *pc, old_exception_table *table)
3601 {
3602   if (table)
3603     {
3604       int pos;
3605       int best = -1;
3606
3607       /* We can't do a binary search because the table isn't guaranteed
3608          to be sorted from function to function.  */
3609       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3610         {
3611           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3612             {
3613               /* This can apply.  Make sure it is at least as small as
3614                  the previous best.  */
3615               if (best == -1 || (table[pos].end_region <= table[best].end_region
3616                         && table[pos].start_region >= table[best].start_region))
3617                 best = pos;
3618             }
3619           /* But it is sorted by starting PC within a function.  */
3620           else if (best >= 0 && table[pos].start_region > pc)
3621             break;
3622         }
3623       if (best != -1)
3624         return table[best].exception_handler;
3625     }
3626
3627   return (void *) 0;
3628 }
3629
3630 /* find_exception_handler finds the correct handler, if there is one, to
3631    handle an exception.
3632    returns a pointer to the handler which controlled should be transferred
3633    to, or NULL if there is nothing left.
3634    Parameters:
3635    PC - pc where the exception originates. If this is a rethrow, 
3636         then this starts out as a pointer to the exception table
3637         entry we wish to rethrow out of.
3638    TABLE - exception table for the current module.
3639    EH_INFO - eh info pointer for this exception.
3640    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3641    CLEANUP - returned flag indicating whether this is a cleanup handler.
3642 */
3643 static void *
3644 find_exception_handler (void *pc, exception_descriptor *table, 
3645                         __eh_info *eh_info, int rethrow, int *cleanup)
3646 {
3647
3648   void *retval = NULL;
3649   *cleanup = 1;
3650   if (table)
3651     {
3652       int pos = 0;
3653       /* The new model assumed the table is sorted inner-most out so the
3654          first region we find which matches is the correct one */
3655
3656       exception_table *tab = &(table->table[0]);
3657
3658       /* Subtract 1 from the PC to avoid hitting the next region */
3659       if (rethrow) 
3660         {
3661           /* pc is actually the region table entry to rethrow out of */
3662           pos = ((exception_table *) pc) - tab;
3663           pc = ((exception_table *) pc)->end_region - 1;
3664
3665           /* The label is always on the LAST handler entry for a region, 
3666              so we know the next entry is a different region, even if the
3667              addresses are the same. Make sure its not end of table tho. */
3668           if (tab[pos].start_region != (void *) -1)
3669             pos++;
3670         }
3671       else
3672         pc--;
3673       
3674       /* We can't do a binary search because the table is in inner-most
3675          to outermost address ranges within functions */
3676       for ( ; tab[pos].start_region != (void *) -1; pos++)
3677         { 
3678           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3679             {
3680               if (tab[pos].match_info)
3681                 {
3682                   __eh_matcher matcher = eh_info->match_function;
3683                   /* match info but no matcher is NOT a match */
3684                   if (matcher) 
3685                     {
3686                       void *ret = (*matcher)((void *) eh_info, 
3687                                              tab[pos].match_info, table);
3688                       if (ret) 
3689                         {
3690                           if (retval == NULL)
3691                             retval = tab[pos].exception_handler;
3692                           *cleanup = 0;
3693                           break;
3694                         }
3695                     }
3696                 }
3697               else
3698                 {
3699                   if (retval == NULL)
3700                     retval = tab[pos].exception_handler;
3701                 }
3702             }
3703         }
3704     }
3705   return retval;
3706 }
3707 #endif /* DWARF2_UNWIND_INFO */
3708 #endif /* EH_TABLE_LOOKUP */
3709 \f
3710 #ifdef DWARF2_UNWIND_INFO
3711 /* Support code for exception handling using static unwind information.  */
3712
3713 #include "frame.h"
3714
3715 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3716    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3717    avoid a warning about casting between int and pointer of different
3718    sizes.  */
3719
3720 typedef int ptr_type __attribute__ ((mode (pointer)));
3721
3722 #ifdef INCOMING_REGNO
3723 /* Is the saved value for register REG in frame UDATA stored in a register
3724    window in the previous frame?  */
3725
3726 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3727    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3728    compiled functions won't work with the frame-unwind stuff here.  
3729    Perhaps the entireity of in_reg_window should be conditional on having
3730    seen a DW_CFA_GNU_window_save?  */
3731 #define target_flags 0
3732
3733 static int
3734 in_reg_window (int reg, frame_state *udata)
3735 {
3736   if (udata->saved[reg] == REG_SAVED_REG)
3737     return INCOMING_REGNO (reg) == reg;
3738   if (udata->saved[reg] != REG_SAVED_OFFSET)
3739     return 0;
3740
3741 #ifdef STACK_GROWS_DOWNWARD
3742   return udata->reg_or_offset[reg] > 0;
3743 #else
3744   return udata->reg_or_offset[reg] < 0;
3745 #endif
3746 }
3747 #else
3748 static inline int
3749 in_reg_window (int reg __attribute__ ((__unused__)),
3750                frame_state *udata __attribute__ ((__unused__)))
3751 {
3752   return 0;
3753 }
3754 #endif /* INCOMING_REGNO */
3755
3756 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3757    frame called by UDATA or 0.  */
3758
3759 static word_type *
3760 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3761 {
3762   while (udata->saved[reg] == REG_SAVED_REG)
3763     {
3764       reg = udata->reg_or_offset[reg];
3765       if (in_reg_window (reg, udata))
3766         {
3767           udata = sub_udata;
3768           sub_udata = NULL;
3769         }
3770     }
3771   if (udata->saved[reg] == REG_SAVED_OFFSET)
3772     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3773   else
3774     abort ();
3775 }
3776
3777 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3778    frame called by UDATA or 0.  */
3779
3780 static inline void *
3781 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3782 {
3783   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3784 }
3785
3786 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3787
3788 static inline void
3789 put_reg (unsigned reg, void *val, frame_state *udata)
3790 {
3791   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3792 }
3793
3794 /* Copy the saved value for register REG from frame UDATA to frame
3795    TARGET_UDATA.  Unlike the previous two functions, this can handle
3796    registers that are not one word large.  */
3797
3798 static void
3799 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3800 {
3801   word_type *preg = get_reg_addr (reg, udata, NULL);
3802   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3803
3804   memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3805 }
3806
3807 /* Retrieve the return address for frame UDATA.  */
3808
3809 static inline void *
3810 get_return_addr (frame_state *udata, frame_state *sub_udata)
3811 {
3812   return __builtin_extract_return_addr
3813     (get_reg (udata->retaddr_column, udata, sub_udata));
3814 }
3815
3816 /* Overwrite the return address for frame UDATA with VAL.  */
3817
3818 static inline void
3819 put_return_addr (void *val, frame_state *udata)
3820 {
3821   val = __builtin_frob_return_addr (val);
3822   put_reg (udata->retaddr_column, val, udata);
3823 }
3824
3825 /* Given the current frame UDATA and its return address PC, return the
3826    information about the calling frame in CALLER_UDATA.  */
3827
3828 static void *
3829 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3830 {
3831   caller_udata = __frame_state_for (pc, caller_udata);
3832   if (! caller_udata)
3833     return 0;
3834
3835   /* Now go back to our caller's stack frame.  If our caller's CFA register
3836      was saved in our stack frame, restore it; otherwise, assume the CFA
3837      register is SP and restore it to our CFA value.  */
3838   if (udata->saved[caller_udata->cfa_reg])
3839     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3840   else
3841     caller_udata->cfa = udata->cfa;
3842   caller_udata->cfa += caller_udata->cfa_offset;
3843
3844   return caller_udata;
3845 }
3846
3847 /* Hook to call before __terminate if only cleanup handlers remain. */
3848 void 
3849 __unwinding_cleanup (void)
3850 {
3851 }
3852
3853 /* throw_helper performs some of the common grunt work for a throw. This
3854    routine is called by throw and rethrows. This is pretty much split 
3855    out from the old __throw routine. An addition has been added which allows
3856    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3857    but cleanups remaining. This allows a debugger to examine the state
3858    at which the throw was executed, before any cleanups, rather than
3859    at the terminate point after the stack has been unwound.
3860
3861    EH is the current eh_context structure.
3862    PC is the address of the call to __throw.
3863    MY_UDATA is the unwind information for __throw.
3864    OFFSET_P is where we return the SP adjustment offset.  */
3865
3866 static void *
3867 throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
3868               long *offset_p)
3869 {
3870   frame_state ustruct2, *udata = &ustruct2;
3871   frame_state ustruct;
3872   frame_state *sub_udata = &ustruct;
3873   void *saved_pc = pc;
3874   void *handler;
3875   void *handler_p = 0;
3876   void *pc_p = 0;
3877   frame_state saved_ustruct;
3878   int new_eh_model;
3879   int cleanup = 0;
3880   int only_cleanup = 0;
3881   int rethrow = 0;
3882   int saved_state = 0;
3883   long args_size;
3884   __eh_info *eh_info = (__eh_info *)eh->info;
3885
3886   /* Do we find a handler based on a re-throw PC? */
3887   if (eh->table_index != (void *) 0)
3888     rethrow = 1;
3889
3890   memcpy (udata, my_udata, sizeof (*udata));
3891
3892   handler = (void *) 0;
3893   for (;;)
3894     { 
3895       frame_state *p = udata;
3896       udata = next_stack_level (pc, udata, sub_udata);
3897       sub_udata = p;
3898
3899       /* If we couldn't find the next frame, we lose.  */
3900       if (! udata)
3901         break;
3902
3903       if (udata->eh_ptr == NULL)
3904         new_eh_model = 0;
3905       else
3906         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3907                                           runtime_id_field == NEW_EH_RUNTIME);
3908
3909       if (rethrow) 
3910         {
3911           rethrow = 0;
3912           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3913                                           eh_info, 1, &cleanup);
3914           eh->table_index = (void *)0;
3915         }
3916       else
3917         if (new_eh_model)
3918           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3919                                             0, &cleanup);
3920         else
3921           handler = old_find_exception_handler (pc, udata->eh_ptr);
3922
3923       /* If we found one, we can stop searching, if its not a cleanup. 
3924          for cleanups, we save the state, and keep looking. This allows
3925          us to call a debug hook if there are nothing but cleanups left. */
3926       if (handler)
3927         {
3928           if (cleanup)
3929             {
3930               if (!saved_state)
3931                 {
3932                   saved_ustruct = *udata;
3933                   handler_p = handler;
3934                   pc_p = pc;
3935                   saved_state = 1;
3936                   only_cleanup = 1;
3937                 }
3938             }
3939           else
3940             {
3941               only_cleanup = 0;
3942               break;
3943             }
3944         }
3945
3946       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3947          hitting the beginning of the next region.  */
3948       pc = get_return_addr (udata, sub_udata) - 1;
3949     }
3950
3951   if (saved_state) 
3952     {
3953       udata = &saved_ustruct;
3954       handler = handler_p;
3955       pc = pc_p;
3956       if (only_cleanup)
3957         __unwinding_cleanup ();
3958     }
3959
3960   /* If we haven't found a handler by now, this is an unhandled
3961      exception.  */
3962   if (! handler) 
3963     __terminate();
3964
3965   eh->handler_label = handler;
3966
3967   args_size = udata->args_size;
3968
3969   if (pc == saved_pc)
3970     /* We found a handler in the throw context, no need to unwind.  */
3971     udata = my_udata;
3972   else
3973     {
3974       int i;
3975
3976       /* Unwind all the frames between this one and the handler by copying
3977          their saved register values into our register save slots.  */
3978
3979       /* Remember the PC where we found the handler.  */
3980       void *handler_pc = pc;
3981
3982       /* Start from the throw context again.  */
3983       pc = saved_pc;
3984       memcpy (udata, my_udata, sizeof (*udata));
3985
3986       while (pc != handler_pc)
3987         {
3988           frame_state *p = udata;
3989           udata = next_stack_level (pc, udata, sub_udata);
3990           sub_udata = p;
3991
3992           for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
3993             if (i != udata->retaddr_column && udata->saved[i])
3994               {
3995                 /* If you modify the saved value of the return address
3996                    register on the SPARC, you modify the return address for
3997                    your caller's frame.  Don't do that here, as it will
3998                    confuse get_return_addr.  */
3999                 if (in_reg_window (i, udata)
4000                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
4001                     && udata->reg_or_offset[udata->retaddr_column] == i)
4002                   continue;
4003                 copy_reg (i, udata, my_udata);
4004               }
4005
4006           pc = get_return_addr (udata, sub_udata) - 1;
4007         }
4008
4009       /* But we do need to update the saved return address register from
4010          the last frame we unwind, or the handler frame will have the wrong
4011          return address.  */
4012       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
4013         {
4014           i = udata->reg_or_offset[udata->retaddr_column];
4015           if (in_reg_window (i, udata))
4016             copy_reg (i, udata, my_udata);
4017         }
4018     }
4019   /* udata now refers to the frame called by the handler frame.  */
4020
4021   /* We adjust SP by the difference between __throw's CFA and the CFA for
4022      the frame called by the handler frame, because those CFAs correspond
4023      to the SP values at the two call sites.  We need to further adjust by
4024      the args_size of the handler frame itself to get the handler frame's
4025      SP from before the args were pushed for that call.  */
4026 #ifdef STACK_GROWS_DOWNWARD
4027   *offset_p = udata->cfa - my_udata->cfa + args_size;
4028 #else
4029   *offset_p = my_udata->cfa - udata->cfa - args_size;
4030 #endif
4031                        
4032   return handler;
4033 }
4034
4035
4036 /* We first search for an exception handler, and if we don't find
4037    it, we call __terminate on the current stack frame so that we may
4038    use the debugger to walk the stack and understand why no handler
4039    was found.
4040
4041    If we find one, then we unwind the frames down to the one that
4042    has the handler and transfer control into the handler.  */
4043
4044 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4045
4046 void
4047 __throw (void)
4048 {
4049   struct eh_context *eh = (*get_eh_context) ();
4050   void *pc, *handler;
4051   long offset;
4052
4053   /* XXX maybe make my_ustruct static so we don't have to look it up for
4054      each throw.  */
4055   frame_state my_ustruct, *my_udata = &my_ustruct;
4056
4057   /* This is required for C++ semantics.  We must call terminate if we
4058      try and rethrow an exception, when there is no exception currently
4059      active.  */
4060   if (! eh->info)
4061     __terminate ();
4062     
4063   /* Start at our stack frame.  */
4064 label:
4065   my_udata = __frame_state_for (&&label, my_udata);
4066   if (! my_udata)
4067     __terminate ();
4068
4069   /* We need to get the value from the CFA register. */
4070   my_udata->cfa = __builtin_dwarf_cfa ();
4071
4072   /* Do any necessary initialization to access arbitrary stack frames.
4073      On the SPARC, this means flushing the register windows.  */
4074   __builtin_unwind_init ();
4075
4076   /* Now reset pc to the right throw point.  */
4077   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4078
4079   handler = throw_helper (eh, pc, my_udata, &offset);
4080
4081   /* Now go!  */
4082
4083   __builtin_eh_return ((void *)eh, offset, handler);
4084
4085   /* Epilogue:  restore the handler frame's register values and return
4086      to the stub.  */
4087 }
4088
4089 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4090
4091 void
4092 __rethrow (void *index)
4093 {
4094   struct eh_context *eh = (*get_eh_context) ();
4095   void *pc, *handler;
4096   long offset;
4097
4098   /* XXX maybe make my_ustruct static so we don't have to look it up for
4099      each throw.  */
4100   frame_state my_ustruct, *my_udata = &my_ustruct;
4101
4102   /* This is required for C++ semantics.  We must call terminate if we
4103      try and rethrow an exception, when there is no exception currently
4104      active.  */
4105   if (! eh->info)
4106     __terminate ();
4107
4108   /* This is the table index we want to rethrow from. The value of
4109      the END_REGION label is used for the PC of the throw, and the
4110      search begins with the next table entry. */
4111   eh->table_index = index;
4112     
4113   /* Start at our stack frame.  */
4114 label:
4115   my_udata = __frame_state_for (&&label, my_udata);
4116   if (! my_udata)
4117     __terminate ();
4118
4119   /* We need to get the value from the CFA register. */
4120   my_udata->cfa = __builtin_dwarf_cfa ();
4121
4122   /* Do any necessary initialization to access arbitrary stack frames.
4123      On the SPARC, this means flushing the register windows.  */
4124   __builtin_unwind_init ();
4125
4126   /* Now reset pc to the right throw point.  */
4127   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4128
4129   handler = throw_helper (eh, pc, my_udata, &offset);
4130
4131   /* Now go!  */
4132
4133   __builtin_eh_return ((void *)eh, offset, handler);
4134
4135   /* Epilogue:  restore the handler frame's register values and return
4136      to the stub.  */
4137 }
4138 #endif /* DWARF2_UNWIND_INFO */
4139
4140 #endif /* L_eh */
4141 \f
4142 #ifdef L_pure
4143 #ifndef inhibit_libc
4144 /* This gets us __GNU_LIBRARY__.  */
4145 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
4146 #include <stdio.h>
4147
4148 #ifdef __GNU_LIBRARY__
4149   /* Avoid forcing the library's meaning of `write' on the user program
4150      by using the "internal" name (for use within the library)  */
4151 #define write(fd, buf, n)       __write((fd), (buf), (n))
4152 #endif
4153 #endif /* inhibit_libc */
4154
4155 #define MESSAGE "pure virtual method called\n"
4156
4157 extern void __terminate (void) __attribute__ ((__noreturn__));
4158
4159 void
4160 __pure_virtual (void)
4161 {
4162 #ifndef inhibit_libc
4163   write (2, MESSAGE, sizeof (MESSAGE) - 1);
4164 #endif
4165   __terminate ();
4166 }
4167 #endif