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