source: trunk/third/gcc/libgcc2.c @ 8834

Revision 8834, 55.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* More subroutines needed by GCC output code on some machines.  */
2/* Compile this one with gcc.  */
3/* Copyright (C) 1989, 1992, 1993, 1994, 1995 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#include "machmode.h"
35#include "defaults.h"
36#ifndef L_trampoline
37#include <stddef.h>
38#endif
39
40/* Don't use `fancy_abort' here even if config.h says to use it.  */
41#ifdef abort
42#undef abort
43#endif
44
45#if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
46#define WEAK_ALIAS
47#endif
48
49/* Permit the tm.h file to select the endianness to use just for this
50   file.  This is used when the endianness is determined when the
51   compiler is run.  */
52
53#ifndef LIBGCC2_WORDS_BIG_ENDIAN
54#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
55#endif
56
57/* In the first part of this file, we are interfacing to calls generated
58   by the compiler itself.  These calls pass values into these routines
59   which have very specific modes (rather than very specific types), and
60   these compiler-generated calls also expect any return values to have
61   very specific modes (rather than very specific types).  Thus, we need
62   to avoid using regular C language type names in this part of the file
63   because the sizes for those types can be configured to be anything.
64   Instead we use the following special type names.  */
65
66typedef unsigned int UQItype    __attribute__ ((mode (QI)));
67typedef          int SItype     __attribute__ ((mode (SI)));
68typedef unsigned int USItype    __attribute__ ((mode (SI)));
69typedef          int DItype     __attribute__ ((mode (DI)));
70typedef unsigned int UDItype    __attribute__ ((mode (DI)));
71
72typedef         float SFtype    __attribute__ ((mode (SF)));
73typedef         float DFtype    __attribute__ ((mode (DF)));
74
75#if LONG_DOUBLE_TYPE_SIZE == 96
76typedef         float XFtype    __attribute__ ((mode (XF)));
77#endif
78#if LONG_DOUBLE_TYPE_SIZE == 128
79typedef         float TFtype    __attribute__ ((mode (TF)));
80#endif
81
82typedef int word_type __attribute__ ((mode (__word__)));
83
84/* Make sure that we don't accidentally use any normal C language built-in
85   type names in the first part of this file.  Instead we want to use *only*
86   the type names defined above.  The following macro definitions insure
87   that if we *do* accidentally use some normal C language built-in type name,
88   we will get a syntax error.  */
89
90#define char bogus_type
91#define short bogus_type
92#define int bogus_type
93#define long bogus_type
94#define unsigned bogus_type
95#define float bogus_type
96#define double bogus_type
97
98#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
99
100/* DIstructs are pairs of SItype values in the order determined by
101   LIBGCC2_WORDS_BIG_ENDIAN.  */
102
103#if LIBGCC2_WORDS_BIG_ENDIAN
104  struct DIstruct {SItype high, low;};
105#else
106  struct DIstruct {SItype low, high;};
107#endif
108
109/* We need this union to unpack/pack DImode values, since we don't have
110   any arithmetic yet.  Incoming DImode parameters are stored into the
111   `ll' field, and the unpacked result is read from the struct `s'.  */
112
113typedef union
114{
115  struct DIstruct s;
116  DItype ll;
117} DIunion;
118
119#if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120     || defined (L_divdi3) || defined (L_udivdi3) \
121     || defined (L_moddi3) || defined (L_umoddi3))
122
123#include "longlong.h"
124
125#endif /* udiv or mul */
126
127extern DItype __fixunssfdi (SFtype a);
128extern DItype __fixunsdfdi (DFtype a);
129#if LONG_DOUBLE_TYPE_SIZE == 96
130extern DItype __fixunsxfdi (XFtype a);
131#endif
132#if LONG_DOUBLE_TYPE_SIZE == 128
133extern DItype __fixunstfdi (TFtype a);
134#endif
135
136#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137#if defined (L_divdi3) || defined (L_moddi3)
138static inline
139#endif
140DItype
141__negdi2 (u)
142     DItype u;
143{
144  DIunion w;
145  DIunion uu;
146
147  uu.ll = u;
148
149  w.s.low = -uu.s.low;
150  w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
151
152  return w.ll;
153}
154#endif
155
156#ifdef L_lshrdi3
157DItype
158__lshrdi3 (u, b)
159     DItype u;
160     word_type b;
161{
162  DIunion w;
163  word_type bm;
164  DIunion uu;
165
166  if (b == 0)
167    return u;
168
169  uu.ll = u;
170
171  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
172  if (bm <= 0)
173    {
174      w.s.high = 0;
175      w.s.low = (USItype)uu.s.high >> -bm;
176    }
177  else
178    {
179      USItype carries = (USItype)uu.s.high << bm;
180      w.s.high = (USItype)uu.s.high >> b;
181      w.s.low = ((USItype)uu.s.low >> b) | carries;
182    }
183
184  return w.ll;
185}
186#endif
187
188#ifdef L_ashldi3
189DItype
190__ashldi3 (u, b)
191     DItype u;
192     word_type b;
193{
194  DIunion w;
195  word_type bm;
196  DIunion uu;
197
198  if (b == 0)
199    return u;
200
201  uu.ll = u;
202
203  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
204  if (bm <= 0)
205    {
206      w.s.low = 0;
207      w.s.high = (USItype)uu.s.low << -bm;
208    }
209  else
210    {
211      USItype carries = (USItype)uu.s.low >> bm;
212      w.s.low = (USItype)uu.s.low << b;
213      w.s.high = ((USItype)uu.s.high << b) | carries;
214    }
215
216  return w.ll;
217}
218#endif
219
220#ifdef L_ashrdi3
221DItype
222__ashrdi3 (u, b)
223     DItype u;
224     word_type b;
225{
226  DIunion w;
227  word_type bm;
228  DIunion uu;
229
230  if (b == 0)
231    return u;
232
233  uu.ll = u;
234
235  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
236  if (bm <= 0)
237    {
238      /* w.s.high = 1..1 or 0..0 */
239      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
240      w.s.low = uu.s.high >> -bm;
241    }
242  else
243    {
244      USItype carries = (USItype)uu.s.high << bm;
245      w.s.high = uu.s.high >> b;
246      w.s.low = ((USItype)uu.s.low >> b) | carries;
247    }
248
249  return w.ll;
250}
251#endif
252
253#ifdef L_ffsdi2
254DItype
255__ffsdi2 (u)
256     DItype u;
257{
258  DIunion uu, w;
259  uu.ll = u;
260  w.s.high = 0;
261  w.s.low = ffs (uu.s.low);
262  if (w.s.low != 0)
263    return w.ll;
264  w.s.low = ffs (uu.s.high);
265  if (w.s.low != 0)
266    {
267      w.s.low += BITS_PER_UNIT * sizeof (SItype);
268      return w.ll;
269    }
270  return w.ll;
271}
272#endif
273
274#ifdef L_muldi3
275DItype
276__muldi3 (u, v)
277     DItype u, v;
278{
279  DIunion w;
280  DIunion uu, vv;
281
282  uu.ll = u,
283  vv.ll = v;
284
285  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
286  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
287               + (USItype) uu.s.high * (USItype) vv.s.low);
288
289  return w.ll;
290}
291#endif
292
293#ifdef L_udiv_w_sdiv
294#if defined (sdiv_qrnnd)
295USItype
296__udiv_w_sdiv (rp, a1, a0, d)
297     USItype *rp, a1, a0, d;
298{
299  USItype q, r;
300  USItype c0, c1, b1;
301
302  if ((SItype) d >= 0)
303    {
304      if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
305        {
306          /* dividend, divisor, and quotient are nonnegative */
307          sdiv_qrnnd (q, r, a1, a0, d);
308        }
309      else
310        {
311          /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312          sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
313          /* Divide (c1*2^32 + c0) by d */
314          sdiv_qrnnd (q, r, c1, c0, d);
315          /* Add 2^31 to quotient */
316          q += (USItype) 1 << (SI_TYPE_SIZE - 1);
317        }
318    }
319  else
320    {
321      b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
322      c1 = a1 >> 1;                     /* A/2 */
323      c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
324
325      if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
326        {
327          sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
328
329          r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
330          if ((d & 1) != 0)
331            {
332              if (r >= q)
333                r = r - q;
334              else if (q - r <= d)
335                {
336                  r = r - q + d;
337                  q--;
338                }
339              else
340                {
341                  r = r - q + 2*d;
342                  q -= 2;
343                }
344            }
345        }
346      else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
347        {
348          c1 = (b1 - 1) - c1;
349          c0 = ~c0;                     /* logical NOT */
350
351          sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
352
353          q = ~q;                       /* (A/2)/b1 */
354          r = (b1 - 1) - r;
355
356          r = 2*r + (a0 & 1);           /* A/(2*b1) */
357
358          if ((d & 1) != 0)
359            {
360              if (r >= q)
361                r = r - q;
362              else if (q - r <= d)
363                {
364                  r = r - q + d;
365                  q--;
366                }
367              else
368                {
369                  r = r - q + 2*d;
370                  q -= 2;
371                }
372            }
373        }
374      else                              /* Implies c1 = b1 */
375        {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
376          if (a0 >= -d)
377            {
378              q = -1;
379              r = a0 + d;
380            }
381          else
382            {
383              q = -2;
384              r = a0 + 2*d;
385            }
386        }
387    }
388
389  *rp = r;
390  return q;
391}
392#else
393/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
394USItype
395__udiv_w_sdiv (rp, a1, a0, d)
396     USItype *rp, a1, a0, d;
397{}
398#endif
399#endif
400
401#if (defined (L_udivdi3) || defined (L_divdi3) || \
402     defined (L_umoddi3) || defined (L_moddi3))
403#define L_udivmoddi4
404#endif
405
406#ifdef L_udivmoddi4
407static const UQItype __clz_tab[] =
408{
409  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,
410  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,
411  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,
412  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,
413  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,
414  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,
415  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,
416  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,
417};
418
419#if (defined (L_udivdi3) || defined (L_divdi3) || \
420     defined (L_umoddi3) || defined (L_moddi3))
421static inline
422#endif
423UDItype
424__udivmoddi4 (n, d, rp)
425     UDItype n, d;
426     UDItype *rp;
427{
428  DIunion ww;
429  DIunion nn, dd;
430  DIunion rr;
431  USItype d0, d1, n0, n1, n2;
432  USItype q0, q1;
433  USItype b, bm;
434
435  nn.ll = n;
436  dd.ll = d;
437
438  d0 = dd.s.low;
439  d1 = dd.s.high;
440  n0 = nn.s.low;
441  n1 = nn.s.high;
442
443#if !UDIV_NEEDS_NORMALIZATION
444  if (d1 == 0)
445    {
446      if (d0 > n1)
447        {
448          /* 0q = nn / 0D */
449
450          udiv_qrnnd (q0, n0, n1, n0, d0);
451          q1 = 0;
452
453          /* Remainder in n0.  */
454        }
455      else
456        {
457          /* qq = NN / 0d */
458
459          if (d0 == 0)
460            d0 = 1 / d0;        /* Divide intentionally by zero.  */
461
462          udiv_qrnnd (q1, n1, 0, n1, d0);
463          udiv_qrnnd (q0, n0, n1, n0, d0);
464
465          /* Remainder in n0.  */
466        }
467
468      if (rp != 0)
469        {
470          rr.s.low = n0;
471          rr.s.high = 0;
472          *rp = rr.ll;
473        }
474    }
475
476#else /* UDIV_NEEDS_NORMALIZATION */
477
478  if (d1 == 0)
479    {
480      if (d0 > n1)
481        {
482          /* 0q = nn / 0D */
483
484          count_leading_zeros (bm, d0);
485
486          if (bm != 0)
487            {
488              /* Normalize, i.e. make the most significant bit of the
489                 denominator set.  */
490
491              d0 = d0 << bm;
492              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
493              n0 = n0 << bm;
494            }
495
496          udiv_qrnnd (q0, n0, n1, n0, d0);
497          q1 = 0;
498
499          /* Remainder in n0 >> bm.  */
500        }
501      else
502        {
503          /* qq = NN / 0d */
504
505          if (d0 == 0)
506            d0 = 1 / d0;        /* Divide intentionally by zero.  */
507
508          count_leading_zeros (bm, d0);
509
510          if (bm == 0)
511            {
512              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513                 conclude (the most significant bit of n1 is set) /\ (the
514                 leading quotient digit q1 = 1).
515
516                 This special case is necessary, not an optimization.
517                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
518
519              n1 -= d0;
520              q1 = 1;
521            }
522          else
523            {
524              /* Normalize.  */
525
526              b = SI_TYPE_SIZE - bm;
527
528              d0 = d0 << bm;
529              n2 = n1 >> b;
530              n1 = (n1 << bm) | (n0 >> b);
531              n0 = n0 << bm;
532
533              udiv_qrnnd (q1, n1, n2, n1, d0);
534            }
535
536          /* n1 != d0... */
537
538          udiv_qrnnd (q0, n0, n1, n0, d0);
539
540          /* Remainder in n0 >> bm.  */
541        }
542
543      if (rp != 0)
544        {
545          rr.s.low = n0 >> bm;
546          rr.s.high = 0;
547          *rp = rr.ll;
548        }
549    }
550#endif /* UDIV_NEEDS_NORMALIZATION */
551
552  else
553    {
554      if (d1 > n1)
555        {
556          /* 00 = nn / DD */
557
558          q0 = 0;
559          q1 = 0;
560
561          /* Remainder in n1n0.  */
562          if (rp != 0)
563            {
564              rr.s.low = n0;
565              rr.s.high = n1;
566              *rp = rr.ll;
567            }
568        }
569      else
570        {
571          /* 0q = NN / dd */
572
573          count_leading_zeros (bm, d1);
574          if (bm == 0)
575            {
576              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577                 conclude (the most significant bit of n1 is set) /\ (the
578                 quotient digit q0 = 0 or 1).
579
580                 This special case is necessary, not an optimization.  */
581
582              /* The condition on the next line takes advantage of that
583                 n1 >= d1 (true due to program flow).  */
584              if (n1 > d1 || n0 >= d0)
585                {
586                  q0 = 1;
587                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
588                }
589              else
590                q0 = 0;
591
592              q1 = 0;
593
594              if (rp != 0)
595                {
596                  rr.s.low = n0;
597                  rr.s.high = n1;
598                  *rp = rr.ll;
599                }
600            }
601          else
602            {
603              USItype m1, m0;
604              /* Normalize.  */
605
606              b = SI_TYPE_SIZE - bm;
607
608              d1 = (d1 << bm) | (d0 >> b);
609              d0 = d0 << bm;
610              n2 = n1 >> b;
611              n1 = (n1 << bm) | (n0 >> b);
612              n0 = n0 << bm;
613
614              udiv_qrnnd (q0, n1, n2, n1, d1);
615              umul_ppmm (m1, m0, q0, d0);
616
617              if (m1 > n1 || (m1 == n1 && m0 > n0))
618                {
619                  q0--;
620                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
621                }
622
623              q1 = 0;
624
625              /* Remainder in (n1n0 - m1m0) >> bm.  */
626              if (rp != 0)
627                {
628                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
629                  rr.s.low = (n1 << b) | (n0 >> bm);
630                  rr.s.high = n1 >> bm;
631                  *rp = rr.ll;
632                }
633            }
634        }
635    }
636
637  ww.s.low = q0;
638  ww.s.high = q1;
639  return ww.ll;
640}
641#endif
642
643#ifdef L_divdi3
644UDItype __udivmoddi4 ();
645
646DItype
647__divdi3 (u, v)
648     DItype u, v;
649{
650  word_type c = 0;
651  DIunion uu, vv;
652  DItype w;
653
654  uu.ll = u;
655  vv.ll = v;
656
657  if (uu.s.high < 0)
658    c = ~c,
659    uu.ll = __negdi2 (uu.ll);
660  if (vv.s.high < 0)
661    c = ~c,
662    vv.ll = __negdi2 (vv.ll);
663
664  w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
665  if (c)
666    w = __negdi2 (w);
667
668  return w;
669}
670#endif
671
672#ifdef L_moddi3
673UDItype __udivmoddi4 ();
674DItype
675__moddi3 (u, v)
676     DItype u, v;
677{
678  word_type c = 0;
679  DIunion uu, vv;
680  DItype w;
681
682  uu.ll = u;
683  vv.ll = v;
684
685  if (uu.s.high < 0)
686    c = ~c,
687    uu.ll = __negdi2 (uu.ll);
688  if (vv.s.high < 0)
689    vv.ll = __negdi2 (vv.ll);
690
691  (void) __udivmoddi4 (uu.ll, vv.ll, &w);
692  if (c)
693    w = __negdi2 (w);
694
695  return w;
696}
697#endif
698
699#ifdef L_umoddi3
700UDItype __udivmoddi4 ();
701UDItype
702__umoddi3 (u, v)
703     UDItype u, v;
704{
705  UDItype w;
706
707  (void) __udivmoddi4 (u, v, &w);
708
709  return w;
710}
711#endif
712
713#ifdef L_udivdi3
714UDItype __udivmoddi4 ();
715UDItype
716__udivdi3 (n, d)
717     UDItype n, d;
718{
719  return __udivmoddi4 (n, d, (UDItype *) 0);
720}
721#endif
722
723#ifdef L_cmpdi2
724word_type
725__cmpdi2 (a, b)
726     DItype a, b;
727{
728  DIunion au, bu;
729
730  au.ll = a, bu.ll = b;
731
732  if (au.s.high < bu.s.high)
733    return 0;
734  else if (au.s.high > bu.s.high)
735    return 2;
736  if ((USItype) au.s.low < (USItype) bu.s.low)
737    return 0;
738  else if ((USItype) au.s.low > (USItype) bu.s.low)
739    return 2;
740  return 1;
741}
742#endif
743
744#ifdef L_ucmpdi2
745word_type
746__ucmpdi2 (a, b)
747     DItype a, b;
748{
749  DIunion au, bu;
750
751  au.ll = a, bu.ll = b;
752
753  if ((USItype) au.s.high < (USItype) bu.s.high)
754    return 0;
755  else if ((USItype) au.s.high > (USItype) bu.s.high)
756    return 2;
757  if ((USItype) au.s.low < (USItype) bu.s.low)
758    return 0;
759  else if ((USItype) au.s.low > (USItype) bu.s.low)
760    return 2;
761  return 1;
762}
763#endif
764
765#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
768
769DItype
770__fixunstfdi (a)
771     TFtype a;
772{
773  TFtype b;
774  UDItype v;
775
776  if (a < 0)
777    return 0;
778
779  /* Compute high word of result, as a flonum.  */
780  b = (a / HIGH_WORD_COEFF);
781  /* Convert that to fixed (but not to DItype!),
782     and shift it into the high word.  */
783  v = (USItype) b;
784  v <<= WORD_SIZE;
785  /* Remove high part from the TFtype, leaving the low part as flonum.  */
786  a -= (TFtype)v;
787  /* Convert that to fixed (but not to DItype!) and add it in.
788     Sometimes A comes out negative.  This is significant, since
789     A has more bits than a long int does.  */
790  if (a < 0)
791    v -= (USItype) (- a);
792  else
793    v += (USItype) a;
794  return v;
795}
796#endif
797
798#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
799DItype
800__fixtfdi (a)
801     TFtype a;
802{
803  if (a < 0)
804    return - __fixunstfdi (-a);
805  return __fixunstfdi (a);
806}
807#endif
808
809#if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
812
813DItype
814__fixunsxfdi (a)
815     XFtype a;
816{
817  XFtype b;
818  UDItype v;
819
820  if (a < 0)
821    return 0;
822
823  /* Compute high word of result, as a flonum.  */
824  b = (a / HIGH_WORD_COEFF);
825  /* Convert that to fixed (but not to DItype!),
826     and shift it into the high word.  */
827  v = (USItype) b;
828  v <<= WORD_SIZE;
829  /* Remove high part from the XFtype, leaving the low part as flonum.  */
830  a -= (XFtype)v;
831  /* Convert that to fixed (but not to DItype!) and add it in.
832     Sometimes A comes out negative.  This is significant, since
833     A has more bits than a long int does.  */
834  if (a < 0)
835    v -= (USItype) (- a);
836  else
837    v += (USItype) a;
838  return v;
839}
840#endif
841
842#if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
843DItype
844__fixxfdi (a)
845     XFtype a;
846{
847  if (a < 0)
848    return - __fixunsxfdi (-a);
849  return __fixunsxfdi (a);
850}
851#endif
852
853#ifdef L_fixunsdfdi
854#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
856
857DItype
858__fixunsdfdi (a)
859     DFtype a;
860{
861  DFtype b;
862  UDItype v;
863
864  if (a < 0)
865    return 0;
866
867  /* Compute high word of result, as a flonum.  */
868  b = (a / HIGH_WORD_COEFF);
869  /* Convert that to fixed (but not to DItype!),
870     and shift it into the high word.  */
871  v = (USItype) b;
872  v <<= WORD_SIZE;
873  /* Remove high part from the DFtype, leaving the low part as flonum.  */
874  a -= (DFtype)v;
875  /* Convert that to fixed (but not to DItype!) and add it in.
876     Sometimes A comes out negative.  This is significant, since
877     A has more bits than a long int does.  */
878  if (a < 0)
879    v -= (USItype) (- a);
880  else
881    v += (USItype) a;
882  return v;
883}
884#endif
885
886#ifdef L_fixdfdi
887DItype
888__fixdfdi (a)
889     DFtype a;
890{
891  if (a < 0)
892    return - __fixunsdfdi (-a);
893  return __fixunsdfdi (a);
894}
895#endif
896
897#ifdef L_fixunssfdi
898#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
900
901DItype
902__fixunssfdi (SFtype original_a)
903{
904  /* Convert the SFtype to a DFtype, because that is surely not going
905     to lose any bits.  Some day someone else can write a faster version
906     that avoids converting to DFtype, and verify it really works right.  */
907  DFtype a = original_a;
908  DFtype b;
909  UDItype v;
910
911  if (a < 0)
912    return 0;
913
914  /* Compute high word of result, as a flonum.  */
915  b = (a / HIGH_WORD_COEFF);
916  /* Convert that to fixed (but not to DItype!),
917     and shift it into the high word.  */
918  v = (USItype) b;
919  v <<= WORD_SIZE;
920  /* Remove high part from the DFtype, leaving the low part as flonum.  */
921  a -= (DFtype)v;
922  /* Convert that to fixed (but not to DItype!) and add it in.
923     Sometimes A comes out negative.  This is significant, since
924     A has more bits than a long int does.  */
925  if (a < 0)
926    v -= (USItype) (- a);
927  else
928    v += (USItype) a;
929  return v;
930}
931#endif
932
933#ifdef L_fixsfdi
934DItype
935__fixsfdi (SFtype a)
936{
937  if (a < 0)
938    return - __fixunssfdi (-a);
939  return __fixunssfdi (a);
940}
941#endif
942
943#if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
944#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
947
948XFtype
949__floatdixf (u)
950     DItype u;
951{
952  XFtype d;
953  SItype negate = 0;
954
955  if (u < 0)
956    u = -u, negate = 1;
957
958  d = (USItype) (u >> WORD_SIZE);
959  d *= HIGH_HALFWORD_COEFF;
960  d *= HIGH_HALFWORD_COEFF;
961  d += (USItype) (u & (HIGH_WORD_COEFF - 1));
962
963  return (negate ? -d : d);
964}
965#endif
966
967#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
971
972TFtype
973__floatditf (u)
974     DItype u;
975{
976  TFtype d;
977  SItype negate = 0;
978
979  if (u < 0)
980    u = -u, negate = 1;
981
982  d = (USItype) (u >> WORD_SIZE);
983  d *= HIGH_HALFWORD_COEFF;
984  d *= HIGH_HALFWORD_COEFF;
985  d += (USItype) (u & (HIGH_WORD_COEFF - 1));
986
987  return (negate ? -d : d);
988}
989#endif
990
991#ifdef L_floatdidf
992#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
995
996DFtype
997__floatdidf (u)
998     DItype u;
999{
1000  DFtype d;
1001  SItype negate = 0;
1002
1003  if (u < 0)
1004    u = -u, negate = 1;
1005
1006  d = (USItype) (u >> WORD_SIZE);
1007  d *= HIGH_HALFWORD_COEFF;
1008  d *= HIGH_HALFWORD_COEFF;
1009  d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1010
1011  return (negate ? -d : d);
1012}
1013#endif
1014
1015#ifdef L_floatdisf
1016#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019#define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1020
1021/* Define codes for all the float formats that we know of.  Note
1022   that this is copied from real.h.  */
1023   
1024#define UNKNOWN_FLOAT_FORMAT 0
1025#define IEEE_FLOAT_FORMAT 1
1026#define VAX_FLOAT_FORMAT 2
1027#define IBM_FLOAT_FORMAT 3
1028
1029/* Default to IEEE float if not specified.  Nearly all machines use it.  */
1030#ifndef HOST_FLOAT_FORMAT
1031#define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1032#endif
1033
1034#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1035#define DF_SIZE 53
1036#define SF_SIZE 24
1037#endif
1038
1039#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1040#define DF_SIZE 56
1041#define SF_SIZE 24
1042#endif
1043
1044#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1045#define DF_SIZE 56
1046#define SF_SIZE 24
1047#endif
1048
1049SFtype
1050__floatdisf (u)
1051     DItype u;
1052{
1053  /* Do the calculation in DFmode
1054     so that we don't lose any of the precision of the high word
1055     while multiplying it.  */
1056  DFtype f;
1057  SItype negate = 0;
1058
1059  if (u < 0)
1060    u = -u, negate = 1;
1061
1062  /* Protect against double-rounding error.
1063     Represent any low-order bits, that might be truncated in DFmode,
1064     by a bit that won't be lost.  The bit can go in anywhere below the
1065     rounding position of the SFmode.  A fixed mask and bit position
1066     handles all usual configurations.  It doesn't handle the case
1067     of 128-bit DImode, however.  */
1068  if (DF_SIZE < DI_SIZE
1069      && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1070    {
1071#define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072      if (u >= ((UDItype) 1 << DF_SIZE))
1073        {
1074          if ((USItype) u & (REP_BIT - 1))
1075            u |= REP_BIT;
1076        }
1077    }
1078  f = (USItype) (u >> WORD_SIZE);
1079  f *= HIGH_HALFWORD_COEFF;
1080  f *= HIGH_HALFWORD_COEFF;
1081  f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1082
1083  return (SFtype) (negate ? -f : f);
1084}
1085#endif
1086
1087#if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088/* Reenable the normal types, in case limits.h needs them.  */
1089#undef char
1090#undef short
1091#undef int
1092#undef long
1093#undef unsigned
1094#undef float
1095#undef double
1096#undef MIN
1097#undef MAX
1098#include <limits.h>
1099
1100USItype
1101__fixunsxfsi (a)
1102     XFtype a;
1103{
1104  if (a >= - (DFtype) LONG_MIN)
1105    return (SItype) (a + LONG_MIN) - LONG_MIN;
1106  return (SItype) a;
1107}
1108#endif
1109
1110#ifdef L_fixunsdfsi
1111/* Reenable the normal types, in case limits.h needs them.  */
1112#undef char
1113#undef short
1114#undef int
1115#undef long
1116#undef unsigned
1117#undef float
1118#undef double
1119#undef MIN
1120#undef MAX
1121#include <limits.h>
1122
1123USItype
1124__fixunsdfsi (a)
1125     DFtype a;
1126{
1127  if (a >= - (DFtype) LONG_MIN)
1128    return (SItype) (a + LONG_MIN) - LONG_MIN;
1129  return (SItype) a;
1130}
1131#endif
1132
1133#ifdef L_fixunssfsi
1134/* Reenable the normal types, in case limits.h needs them.  */
1135#undef char
1136#undef short
1137#undef int
1138#undef long
1139#undef unsigned
1140#undef float
1141#undef double
1142#undef MIN
1143#undef MAX
1144#include <limits.h>
1145
1146USItype
1147__fixunssfsi (SFtype a)
1148{
1149  if (a >= - (SFtype) LONG_MIN)
1150    return (SItype) (a + LONG_MIN) - LONG_MIN;
1151  return (SItype) a;
1152}
1153#endif
1154
1155/* From here on down, the routines use normal data types.  */
1156
1157#define SItype bogus_type
1158#define USItype bogus_type
1159#define DItype bogus_type
1160#define UDItype bogus_type
1161#define SFtype bogus_type
1162#define DFtype bogus_type
1163
1164#undef char
1165#undef short
1166#undef int
1167#undef long
1168#undef unsigned
1169#undef float
1170#undef double
1171
1172#ifdef L__gcc_bcmp
1173
1174/* Like bcmp except the sign is meaningful.
1175   Result is negative if S1 is less than S2,
1176   positive if S1 is greater, 0 if S1 and S2 are equal.  */
1177
1178int
1179__gcc_bcmp (s1, s2, size)
1180     unsigned char *s1, *s2;
1181     size_t size;
1182{
1183  while (size > 0)
1184    {
1185      unsigned char c1 = *s1++, c2 = *s2++;
1186      if (c1 != c2)
1187        return c1 - c2;
1188      size--;
1189    }
1190  return 0;
1191}
1192
1193#endif
1194
1195#ifdef L_varargs
1196#ifdef __i860__
1197#if defined(__svr4__) || defined(__alliant__)
1198        asm ("  .text");
1199        asm ("  .align  4");
1200
1201/* The Alliant needs the added underscore.  */
1202        asm (".globl    __builtin_saveregs");
1203asm ("__builtin_saveregs:");
1204        asm (".globl    ___builtin_saveregs");
1205asm ("___builtin_saveregs:");
1206
1207        asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1208        asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1209                                           area and also for a new va_list
1210                                           structure */
1211        /* Save all argument registers in the arg reg save area.  The
1212           arg reg save area must have the following layout (according
1213           to the svr4 ABI):
1214
1215                struct {
1216                  union  {
1217                    float freg[8];
1218                    double dreg[4];
1219                  } float_regs;
1220                  long  ireg[12];
1221                };
1222        */
1223
1224        asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1225        asm ("  fst.q   %f12,16(%sp)");
1226
1227        asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1228        asm ("  st.l    %r17,36(%sp)");
1229        asm ("  st.l    %r18,40(%sp)");
1230        asm ("  st.l    %r19,44(%sp)");
1231        asm ("  st.l    %r20,48(%sp)");
1232        asm ("  st.l    %r21,52(%sp)");
1233        asm ("  st.l    %r22,56(%sp)");
1234        asm ("  st.l    %r23,60(%sp)");
1235        asm ("  st.l    %r24,64(%sp)");
1236        asm ("  st.l    %r25,68(%sp)");
1237        asm ("  st.l    %r26,72(%sp)");
1238        asm ("  st.l    %r27,76(%sp)");
1239
1240        asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1241                                           va_list structure.  Put in into
1242                                           r16 so that it will be returned
1243                                           to the caller.  */
1244
1245        /* Initialize all fields of the new va_list structure.  This
1246           structure looks like:
1247
1248                typedef struct {
1249                    unsigned long       ireg_used;
1250                    unsigned long       freg_used;
1251                    long                *reg_base;
1252                    long                *mem_ptr;
1253                } va_list;
1254        */
1255
1256        asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1257        asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1258        asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1259        asm ("  bri     %r1");          /* delayed return */
1260        asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1261
1262#else /* not __svr4__ */
1263#if defined(__PARAGON__)
1264        /*
1265         *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1266         *      and we stand a better chance of hooking into libraries
1267         *      compiled by PGI.  [andyp@ssd.intel.com]
1268         */
1269        asm ("  .text");
1270        asm ("  .align  4");
1271        asm (".globl    __builtin_saveregs");
1272asm ("__builtin_saveregs:");
1273        asm (".globl    ___builtin_saveregs");
1274asm ("___builtin_saveregs:");
1275
1276        asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1277        asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1278                                           area and also for a new va_list
1279                                           structure */
1280        /* Save all argument registers in the arg reg save area.  The
1281           arg reg save area must have the following layout (according
1282           to the svr4 ABI):
1283
1284                struct {
1285                  union  {
1286                    float freg[8];
1287                    double dreg[4];
1288                  } float_regs;
1289                  long  ireg[12];
1290                };
1291        */
1292
1293        asm ("  fst.q   f8,  0(sp)");
1294        asm ("  fst.q   f12,16(sp)");
1295        asm ("  st.l    r16,32(sp)");
1296        asm ("  st.l    r17,36(sp)");
1297        asm ("  st.l    r18,40(sp)");
1298        asm ("  st.l    r19,44(sp)");
1299        asm ("  st.l    r20,48(sp)");
1300        asm ("  st.l    r21,52(sp)");
1301        asm ("  st.l    r22,56(sp)");
1302        asm ("  st.l    r23,60(sp)");
1303        asm ("  st.l    r24,64(sp)");
1304        asm ("  st.l    r25,68(sp)");
1305        asm ("  st.l    r26,72(sp)");
1306        asm ("  st.l    r27,76(sp)");
1307
1308        asm ("  adds    80,sp,r16");  /* compute the address of the new
1309                                           va_list structure.  Put in into
1310                                           r16 so that it will be returned
1311                                           to the caller.  */
1312
1313        /* Initialize all fields of the new va_list structure.  This
1314           structure looks like:
1315
1316                typedef struct {
1317                    unsigned long       ireg_used;
1318                    unsigned long       freg_used;
1319                    long                *reg_base;
1320                    long                *mem_ptr;
1321                } va_list;
1322        */
1323
1324        asm ("  st.l    r0, 0(r16)"); /* nfixed */
1325        asm ("  st.l    r0, 4(r16)"); /* nfloating */
1326        asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1327        asm ("  bri     r1");           /* delayed return */
1328        asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1329#else /* not __PARAGON__ */
1330        asm ("  .text");
1331        asm ("  .align  4");
1332
1333        asm (".globl    ___builtin_saveregs");
1334        asm ("___builtin_saveregs:");
1335        asm ("  mov     sp,r30");
1336        asm ("  andnot  0x0f,sp,sp");
1337        asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1338
1339/* Fill in the __va_struct.  */
1340        asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1341        asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1342        asm ("  st.l    r18, 8(sp)");
1343        asm ("  st.l    r19,12(sp)");
1344        asm ("  st.l    r20,16(sp)");
1345        asm ("  st.l    r21,20(sp)");
1346        asm ("  st.l    r22,24(sp)");
1347        asm ("  st.l    r23,28(sp)");
1348        asm ("  st.l    r24,32(sp)");
1349        asm ("  st.l    r25,36(sp)");
1350        asm ("  st.l    r26,40(sp)");
1351        asm ("  st.l    r27,44(sp)");
1352
1353        asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1354        asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1355
1356/* Fill in the __va_ctl.  */
1357        asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1358        asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1359        asm ("  st.l    r0, 88(sp)"); /* nfixed */
1360        asm ("  st.l    r0, 92(sp)"); /* nfloating */
1361
1362        asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1363        asm ("  bri     r1");
1364        asm ("  mov     r30,sp");
1365                                /* recover stack and pass address to start
1366                                   of data.  */
1367#endif /* not __PARAGON__ */
1368#endif /* not __svr4__ */
1369#else /* not __i860__ */
1370#ifdef __sparc__
1371        asm (".global __builtin_saveregs");
1372        asm ("__builtin_saveregs:");
1373        asm (".global ___builtin_saveregs");
1374        asm ("___builtin_saveregs:");
1375#ifdef NEED_PROC_COMMAND
1376        asm (".proc 020");
1377#endif
1378        asm ("st %i0,[%fp+68]");
1379        asm ("st %i1,[%fp+72]");
1380        asm ("st %i2,[%fp+76]");
1381        asm ("st %i3,[%fp+80]");
1382        asm ("st %i4,[%fp+84]");
1383        asm ("retl");
1384        asm ("st %i5,[%fp+88]");
1385#ifdef NEED_TYPE_COMMAND
1386        asm (".type __builtin_saveregs,#function");
1387        asm (".size __builtin_saveregs,.-__builtin_saveregs");
1388#endif
1389#else /* not __sparc__ */
1390#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1391
1392  asm ("        .text");
1393  asm ("        .ent __builtin_saveregs");
1394  asm ("        .globl __builtin_saveregs");
1395  asm ("__builtin_saveregs:");
1396  asm ("        sw      $4,0($30)");
1397  asm ("        sw      $5,4($30)");
1398  asm ("        sw      $6,8($30)");
1399  asm ("        sw      $7,12($30)");
1400  asm ("        j       $31");
1401  asm ("        .end __builtin_saveregs");
1402#else /* not __mips__, etc. */
1403
1404void *
1405__builtin_saveregs ()
1406{
1407  abort ();
1408}
1409
1410#endif /* not __mips__ */
1411#endif /* not __sparc__ */
1412#endif /* not __i860__ */
1413#endif
1414
1415#ifdef L_eprintf
1416#ifndef inhibit_libc
1417
1418#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1419#include <stdio.h>
1420/* This is used by the `assert' macro.  */
1421void
1422__eprintf (string, expression, line, filename)
1423     const char *string;
1424     const char *expression;
1425     int line;
1426     const char *filename;
1427{
1428  fprintf (stderr, string, expression, line, filename);
1429  fflush (stderr);
1430  abort ();
1431}
1432
1433#endif
1434#endif
1435
1436#ifdef L_bb
1437
1438/* Structure emitted by -a  */
1439struct bb
1440{
1441  long zero_word;
1442  const char *filename;
1443  long *counts;
1444  long ncounts;
1445  struct bb *next;
1446  const unsigned long *addresses;
1447
1448  /* Older GCC's did not emit these fields.  */
1449  long nwords;
1450  const char **functions;
1451  const long *line_nums;
1452  const char **filenames;
1453};
1454
1455#ifdef BLOCK_PROFILER_CODE
1456BLOCK_PROFILER_CODE
1457#else
1458#ifndef inhibit_libc
1459
1460/* Simple minded basic block profiling output dumper for
1461   systems that don't provide tcov support.  At present,
1462   it requires atexit and stdio.  */
1463
1464#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1465#include <stdio.h>
1466char *ctime ();
1467
1468#ifdef HAVE_ATEXIT
1469#ifdef WINNT
1470extern int atexit (void (*) (void));
1471#else
1472extern void atexit (void (*) (void));
1473#endif
1474#define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1475#else
1476#ifdef sun
1477extern void on_exit (void*, void*);
1478#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1479#endif
1480#endif
1481
1482static struct bb *bb_head;
1483
1484/* Return the number of digits needed to print a value */
1485/* __inline__ */ static int num_digits (long value, int base)
1486{
1487  int minus = (value < 0 && base != 16);
1488  unsigned long v = (minus) ? -value : value;
1489  int ret = minus;
1490
1491  do
1492    {
1493      v /= base;
1494      ret++;
1495    }
1496  while (v);
1497
1498  return ret;
1499}
1500
1501void
1502__bb_exit_func (void)
1503{
1504  FILE *file = fopen ("bb.out", "a");
1505  long time_value;
1506
1507  if (!file)
1508    perror ("bb.out");
1509
1510  else
1511    {
1512      struct bb *ptr;
1513
1514      /* This is somewhat type incorrect, but it avoids worrying about
1515         exactly where time.h is included from.  It should be ok unless
1516         a void * differs from other pointer formats, or if sizeof(long)
1517         is < sizeof (time_t).  It would be nice if we could assume the
1518         use of rationale standards here.  */
1519
1520      time((void *) &time_value);
1521      fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1522
1523      /* We check the length field explicitly in order to allow compatibility
1524         with older GCC's which did not provide it.  */
1525
1526      for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1527        {
1528          int i;
1529          int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1530          int line_p    = (func_p && ptr->line_nums);
1531          int file_p    = (func_p && ptr->filenames);
1532          long ncounts  = ptr->ncounts;
1533          long cnt_max  = 0;
1534          long line_max = 0;
1535          long addr_max = 0;
1536          int file_len  = 0;
1537          int func_len  = 0;
1538          int blk_len   = num_digits (ncounts, 10);
1539          int cnt_len;
1540          int line_len;
1541          int addr_len;
1542
1543          fprintf (file, "File %s, %ld basic blocks \n\n",
1544                   ptr->filename, ncounts);
1545
1546          /* Get max values for each field.  */
1547          for (i = 0; i < ncounts; i++)
1548            {
1549              const char *p;
1550              int len;
1551
1552              if (cnt_max < ptr->counts[i])
1553                cnt_max = ptr->counts[i];
1554
1555              if (addr_max < ptr->addresses[i])
1556                addr_max = ptr->addresses[i];
1557
1558              if (line_p && line_max < ptr->line_nums[i])
1559                line_max = ptr->line_nums[i];
1560
1561              if (func_p)
1562                {
1563                  p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1564                  len = strlen (p);
1565                  if (func_len < len)
1566                    func_len = len;
1567                }
1568
1569              if (file_p)
1570                {
1571                  p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1572                  len = strlen (p);
1573                  if (file_len < len)
1574                    file_len = len;
1575                }
1576            }
1577
1578          addr_len = num_digits (addr_max, 16);
1579          cnt_len  = num_digits (cnt_max, 10);
1580          line_len = num_digits (line_max, 10);
1581
1582          /* Now print out the basic block information.  */
1583          for (i = 0; i < ncounts; i++)
1584            {
1585              fprintf (file,
1586                       "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1587                       blk_len, i+1,
1588                       cnt_len, ptr->counts[i],
1589                       addr_len, ptr->addresses[i]);
1590
1591              if (func_p)
1592                fprintf (file, " function= %-*s", func_len,
1593                         (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1594
1595              if (line_p)
1596                fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1597
1598              if (file_p)
1599                fprintf (file, " file= %s",
1600                         (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1601
1602              fprintf (file, "\n");
1603            }
1604
1605          fprintf (file, "\n");
1606          fflush (file);
1607        }
1608
1609      fprintf (file, "\n\n");
1610      fclose (file);
1611    }
1612}
1613
1614void
1615__bb_init_func (struct bb *blocks)
1616{
1617  /* User is supposed to check whether the first word is non-0,
1618     but just in case.... */
1619
1620  if (blocks->zero_word)
1621    return;
1622
1623#ifdef ON_EXIT
1624  /* Initialize destructor.  */
1625  if (!bb_head)
1626    ON_EXIT (__bb_exit_func, 0);
1627#endif
1628
1629  /* Set up linked list.  */
1630  blocks->zero_word = 1;
1631  blocks->next = bb_head;
1632  bb_head = blocks;
1633}
1634
1635#endif /* not inhibit_libc */
1636#endif /* not BLOCK_PROFILER_CODE */
1637#endif /* L_bb */
1638
1639/* Default free-store management functions for C++, per sections 12.5 and
1640   17.3.3 of the Working Paper. */
1641
1642#ifdef L_op_new
1643/* operator new (size_t), described in 17.3.3.5.  This function is used by
1644   C++ programs to allocate a block of memory to hold a single object. */
1645
1646typedef void (*vfp)(void);
1647extern vfp __new_handler;
1648extern void __default_new_handler (void);
1649
1650#ifdef WEAK_ALIAS
1651void * __builtin_new (size_t sz)
1652     __attribute__ ((weak, alias ("___builtin_new")));
1653void *
1654___builtin_new (size_t sz)
1655#else
1656void *
1657__builtin_new (size_t sz)
1658#endif
1659{
1660  void *p;
1661  vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1662
1663  /* malloc (0) is unpredictable; avoid it.  */
1664  if (sz == 0)
1665    sz = 1;
1666  p = (void *) malloc (sz);
1667  while (p == 0)
1668    {
1669      (*handler) ();
1670      p = (void *) malloc (sz);
1671    }
1672 
1673  return p;
1674}
1675#endif /* L_op_new */
1676
1677#ifdef L_op_vnew
1678/* void * operator new [] (size_t), described in 17.3.3.6.  This function
1679   is used by C++ programs to allocate a block of memory for an array.  */
1680
1681extern void * __builtin_new (size_t);
1682
1683#ifdef WEAK_ALIAS
1684void * __builtin_vec_new (size_t sz)
1685     __attribute__ ((weak, alias ("___builtin_vec_new")));
1686void *
1687___builtin_vec_new (size_t sz)
1688#else
1689void *
1690__builtin_vec_new (size_t sz)
1691#endif
1692{
1693  return __builtin_new (sz);
1694}
1695#endif /* L_op_vnew */
1696
1697#ifdef L_new_handler
1698/* set_new_handler (fvoid_t *) and the default new handler, described in
1699   17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
1700   to allocate the amount of memory requested from operator new or new []. */
1701
1702#ifndef inhibit_libc
1703/* This gets us __GNU_LIBRARY__.  */
1704#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1705#include <stdio.h>
1706
1707#ifdef __GNU_LIBRARY__
1708  /* Avoid forcing the library's meaning of `write' on the user program
1709     by using the "internal" name (for use within the library)  */
1710#define write(fd, buf, n)       __write((fd), (buf), (n))
1711#endif
1712#endif /* inhibit_libc */
1713
1714typedef void (*vfp)(void);
1715void __default_new_handler (void);
1716
1717vfp __new_handler = (vfp)0;
1718
1719vfp
1720set_new_handler (vfp handler)
1721{
1722  vfp prev_handler;
1723
1724  prev_handler = __new_handler;
1725  if (handler == 0) handler = __default_new_handler;
1726  __new_handler = handler;
1727  return prev_handler;
1728}
1729
1730#define MESSAGE "Virtual memory exceeded in `new'\n"
1731
1732void
1733__default_new_handler ()
1734{
1735#ifndef inhibit_libc
1736  /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1737  /* This should really print the name of the program, but that is hard to
1738     do.  We need a standard, clean way to get at the name.  */
1739  write (2, MESSAGE, sizeof (MESSAGE));
1740#endif
1741  /* don't call exit () because that may call global destructors which
1742     may cause a loop.  */
1743  _exit (-1);
1744}
1745#endif
1746
1747#ifdef L_op_delete
1748/* operator delete (void *), described in 17.3.3.3.  This function is used
1749   by C++ programs to return to the free store a block of memory allocated
1750   as a single object. */
1751
1752#ifdef WEAK_ALIAS
1753void __builtin_delete (void *ptr)
1754     __attribute__ ((weak, alias ("___builtin_delete")));
1755void
1756___builtin_delete (void *ptr)
1757#else
1758void
1759__builtin_delete (void *ptr)
1760#endif
1761{
1762  if (ptr)
1763    free (ptr);
1764}
1765#endif
1766
1767#ifdef L_op_vdel
1768/* operator delete [] (void *), described in 17.3.3.4.  This function is
1769   used by C++ programs to return to the free store a block of memory
1770   allocated as an array. */
1771
1772extern void __builtin_delete (void *);
1773
1774#ifdef WEAK_ALIAS
1775void __builtin_vec_delete (void *ptr)
1776     __attribute__ ((weak, alias ("___builtin_vec_delete")));
1777void
1778___builtin_vec_delete (void *ptr)
1779#else
1780void
1781__builtin_vec_delete (void *ptr)
1782#endif
1783{
1784  __builtin_delete (ptr);
1785}
1786#endif
1787
1788/* End of C++ free-store management functions */
1789
1790#ifdef L_shtab
1791unsigned int __shtab[] = {
1792    0x00000001, 0x00000002, 0x00000004, 0x00000008,
1793    0x00000010, 0x00000020, 0x00000040, 0x00000080,
1794    0x00000100, 0x00000200, 0x00000400, 0x00000800,
1795    0x00001000, 0x00002000, 0x00004000, 0x00008000,
1796    0x00010000, 0x00020000, 0x00040000, 0x00080000,
1797    0x00100000, 0x00200000, 0x00400000, 0x00800000,
1798    0x01000000, 0x02000000, 0x04000000, 0x08000000,
1799    0x10000000, 0x20000000, 0x40000000, 0x80000000
1800  };
1801#endif
1802
1803#ifdef L_clear_cache
1804/* Clear part of an instruction cache.  */
1805
1806#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1807
1808void
1809__clear_cache (beg, end)
1810     char *beg, *end;
1811{
1812#ifdef CLEAR_INSN_CACHE
1813  CLEAR_INSN_CACHE (beg, end);
1814#else
1815#ifdef INSN_CACHE_SIZE
1816  static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1817  static int initialized;
1818  int offset;
1819  void *start_addr
1820  void *end_addr;
1821  typedef (*function_ptr) ();
1822
1823#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1824  /* It's cheaper to clear the whole cache.
1825     Put in a series of jump instructions so that calling the beginning
1826     of the cache will clear the whole thing.  */
1827
1828  if (! initialized)
1829    {
1830      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1831                 & -INSN_CACHE_LINE_WIDTH);
1832      int end_ptr = ptr + INSN_CACHE_SIZE;
1833
1834      while (ptr < end_ptr)
1835        {
1836          *(INSTRUCTION_TYPE *)ptr
1837            = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1838          ptr += INSN_CACHE_LINE_WIDTH;
1839        }
1840      *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1841
1842      initialized = 1;
1843    }
1844
1845  /* Call the beginning of the sequence.  */
1846  (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1847                    & -INSN_CACHE_LINE_WIDTH))
1848   ());
1849
1850#else /* Cache is large.  */
1851
1852  if (! initialized)
1853    {
1854      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1855                 & -INSN_CACHE_LINE_WIDTH);
1856
1857      while (ptr < (int) array + sizeof array)
1858        {
1859          *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1860          ptr += INSN_CACHE_LINE_WIDTH;
1861        }
1862
1863      initialized = 1;
1864    }
1865
1866  /* Find the location in array that occupies the same cache line as BEG.  */
1867
1868  offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1869  start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1870                 & -INSN_CACHE_PLANE_SIZE)
1871                + offset);
1872
1873  /* Compute the cache alignment of the place to stop clearing.  */
1874#if 0  /* This is not needed for gcc's purposes.  */
1875  /* If the block to clear is bigger than a cache plane,
1876     we clear the entire cache, and OFFSET is already correct.  */
1877  if (end < beg + INSN_CACHE_PLANE_SIZE)
1878#endif
1879    offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1880               & -INSN_CACHE_LINE_WIDTH)
1881              & (INSN_CACHE_PLANE_SIZE - 1));
1882
1883#if INSN_CACHE_DEPTH > 1
1884  end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1885  if (end_addr <= start_addr)
1886    end_addr += INSN_CACHE_PLANE_SIZE;
1887
1888  for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1889    {
1890      int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1891      int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1892
1893      while (addr != stop)
1894        {
1895          /* Call the return instruction at ADDR.  */
1896          ((function_ptr) addr) ();
1897
1898          addr += INSN_CACHE_LINE_WIDTH;
1899        }
1900    }
1901#else /* just one plane */
1902  do
1903    {
1904      /* Call the return instruction at START_ADDR.  */
1905      ((function_ptr) start_addr) ();
1906
1907      start_addr += INSN_CACHE_LINE_WIDTH;
1908    }
1909  while ((start_addr % INSN_CACHE_SIZE) != offset);
1910#endif /* just one plane */
1911#endif /* Cache is large */
1912#endif /* Cache exists */
1913#endif /* CLEAR_INSN_CACHE */
1914}
1915
1916#endif /* L_clear_cache */
1917
1918#ifdef L_trampoline
1919
1920/* Jump to a trampoline, loading the static chain address.  */
1921
1922#ifdef WINNT
1923
1924long getpagesize()
1925{
1926#ifdef _ALPHA_
1927  return 8192;
1928#else
1929  return 4096;
1930#endif
1931}
1932
1933int mprotect(addr, len, prot)
1934  char *addr;
1935  int len, prot;
1936{
1937  int np, op;
1938
1939  if (prot == 7) np = 0x40;
1940  else if (prot == 5) np = 0x20;
1941  else if (prot == 4) np = 0x10;
1942  else if (prot == 3) np = 0x04;
1943  else if (prot == 1) np = 0x02;
1944  else if (prot == 0) np = 0x01;
1945
1946  if (VirtualProtect (addr, len, np, &op))
1947    return 0;
1948  else
1949    return -1;
1950   
1951}
1952
1953#endif
1954
1955#ifdef TRANSFER_FROM_TRAMPOLINE
1956TRANSFER_FROM_TRAMPOLINE
1957#endif
1958
1959#if defined (NeXT) && defined (__MACH__)
1960
1961/* Make stack executable so we can call trampolines on stack.
1962   This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1963#ifdef NeXTStep21
1964 #include <mach.h>
1965#else
1966 #include <mach/mach.h>
1967#endif
1968
1969void
1970__enable_execute_stack (addr)
1971     char *addr;
1972{
1973  kern_return_t r;
1974  char *eaddr = addr + TRAMPOLINE_SIZE;
1975  vm_address_t a = (vm_address_t) addr;
1976
1977  /* turn on execute access on stack */
1978  r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1979  if (r != KERN_SUCCESS)
1980    {
1981      mach_error("vm_protect VM_PROT_ALL", r);
1982      exit(1);
1983    }
1984
1985  /* We inline the i-cache invalidation for speed */
1986
1987#ifdef CLEAR_INSN_CACHE
1988  CLEAR_INSN_CACHE (addr, eaddr);
1989#else
1990  __clear_cache ((int) addr, (int) eaddr);
1991#endif
1992}
1993
1994#endif /* defined (NeXT) && defined (__MACH__) */
1995
1996#ifdef __convex__
1997
1998/* Make stack executable so we can call trampolines on stack.
1999   This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2000
2001#include <sys/mman.h>
2002#include <sys/vmparam.h>
2003#include <machine/machparam.h>
2004
2005void
2006__enable_execute_stack ()
2007{
2008  int fp;
2009  static unsigned lowest = USRSTACK;
2010  unsigned current = (unsigned) &fp & -NBPG;
2011
2012  if (lowest > current)
2013    {
2014      unsigned len = lowest - current;
2015      mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2016      lowest = current;
2017    }
2018
2019  /* Clear instruction cache in case an old trampoline is in it. */
2020  asm ("pich");
2021}
2022#endif /* __convex__ */
2023
2024#ifdef __DOLPHIN__
2025
2026/* Modified from the convex -code above. */
2027
2028#include <sys/param.h>
2029#include <errno.h>
2030#include <sys/m88kbcs.h>
2031
2032void
2033__enable_execute_stack ()
2034{
2035  int save_errno;
2036  static unsigned long lowest = USRSTACK;
2037  unsigned long current = (unsigned long) &save_errno & -NBPC;
2038 
2039  /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2040     address is seen as 'negative'. That is the case with the stack.   */
2041
2042  save_errno=errno;
2043  if (lowest > current)
2044    {
2045      unsigned len=lowest-current;
2046      memctl(current,len,MCT_TEXT);
2047      lowest = current;
2048    }
2049  else
2050    memctl(current,NBPC,MCT_TEXT);
2051  errno=save_errno;
2052}
2053
2054#endif /* __DOLPHIN__ */
2055
2056#ifdef __pyr__
2057
2058#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2059#include <stdio.h>
2060#include <sys/mman.h>
2061#include <sys/types.h>
2062#include <sys/param.h>
2063#include <sys/vmmac.h>
2064
2065/* Modified from the convex -code above.
2066   mremap promises to clear the i-cache. */
2067
2068void
2069__enable_execute_stack ()
2070{
2071  int fp;
2072  if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2073                PROT_READ|PROT_WRITE|PROT_EXEC))
2074    {
2075      perror ("mprotect in __enable_execute_stack");
2076      fflush (stderr);
2077      abort ();
2078    }
2079}
2080#endif /* __pyr__ */
2081#endif /* L_trampoline */
2082
2083#ifdef L__main
2084
2085#include "gbl-ctors.h"
2086/* Some systems use __main in a way incompatible with its use in gcc, in these
2087   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2088   give the same symbol without quotes for an alternative entry point.  You
2089   must define both, or neither. */
2090#ifndef NAME__MAIN
2091#define NAME__MAIN "__main"
2092#define SYMBOL__MAIN __main
2093#endif
2094
2095#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2096/* Run all the global destructors on exit from the program.  */
2097
2098void
2099__do_global_dtors ()
2100{
2101#ifdef DO_GLOBAL_DTORS_BODY
2102  DO_GLOBAL_DTORS_BODY;
2103#else
2104  func_ptr *p;
2105  for (p = __DTOR_LIST__ + 1; *p; )
2106    (*p++) ();
2107#endif
2108}
2109#endif
2110
2111#ifndef INIT_SECTION_ASM_OP
2112/* Run all the global constructors on entry to the program.  */
2113
2114#ifndef ON_EXIT
2115#define ON_EXIT(a, b)
2116#else
2117/* Make sure the exit routine is pulled in to define the globals as
2118   bss symbols, just in case the linker does not automatically pull
2119   bss definitions from the library.  */
2120
2121extern int _exit_dummy_decl;
2122int *_exit_dummy_ref = &_exit_dummy_decl;
2123#endif /* ON_EXIT */
2124
2125void
2126__do_global_ctors ()
2127{
2128  DO_GLOBAL_CTORS_BODY;
2129  ON_EXIT (__do_global_dtors, 0);
2130}
2131#endif /* no INIT_SECTION_ASM_OP */
2132
2133#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2134/* Subroutine called automatically by `main'.
2135   Compiling a global function named `main'
2136   produces an automatic call to this function at the beginning.
2137
2138   For many systems, this routine calls __do_global_ctors.
2139   For systems which support a .init section we use the .init section
2140   to run __do_global_ctors, so we need not do anything here.  */
2141
2142void
2143SYMBOL__MAIN ()
2144{
2145  /* Support recursive calls to `main': run initializers just once.  */
2146  static int initialized;
2147  if (! initialized)
2148    {
2149      initialized = 1;
2150      __do_global_ctors ();
2151    }
2152}
2153#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2154
2155#endif /* L__main */
2156
2157#ifdef L_ctors
2158
2159#include "gbl-ctors.h"
2160
2161/* Provide default definitions for the lists of constructors and
2162   destructors, so that we don't get linker errors.  These symbols are
2163   intentionally bss symbols, so that gld and/or collect will provide
2164   the right values.  */
2165
2166/* We declare the lists here with two elements each,
2167   so that they are valid empty lists if no other definition is loaded.  */
2168#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2169#if defined(__NeXT__) || defined(_AIX)
2170/* After 2.3, try this definition on all systems.  */
2171func_ptr __CTOR_LIST__[2] = {0, 0};
2172func_ptr __DTOR_LIST__[2] = {0, 0};
2173#else
2174func_ptr __CTOR_LIST__[2];
2175func_ptr __DTOR_LIST__[2];
2176#endif
2177#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2178#endif /* L_ctors */
2179
2180#ifdef L_exit
2181
2182#include "gbl-ctors.h"
2183
2184#ifndef ON_EXIT
2185
2186/* If we have no known way of registering our own __do_global_dtors
2187   routine so that it will be invoked at program exit time, then we
2188   have to define our own exit routine which will get this to happen.  */
2189
2190extern void __do_global_dtors ();
2191extern void _cleanup ();
2192extern void _exit () __attribute__ ((noreturn));
2193
2194void
2195exit (status)
2196     int status;
2197{
2198#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2199  __do_global_dtors ();
2200#endif
2201#ifdef EXIT_BODY
2202  EXIT_BODY;
2203#else
2204  _cleanup ();
2205#endif
2206  _exit (status);
2207}
2208
2209#else
2210int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2211#endif
2212
2213#endif /* L_exit */
2214
2215#ifdef L_eh
2216typedef struct {
2217  void *start;
2218  void *end;
2219  void *exception_handler;
2220} exception_table;
2221
2222struct exception_table_node {
2223  exception_table *table;
2224  void *start;
2225  void *end;
2226  struct exception_table_node *next;
2227};
2228
2229static int except_table_pos;
2230static void *except_pc;
2231static struct exception_table_node *exception_table_list;
2232
2233static exception_table *
2234find_exception_table (pc)
2235     void* pc;
2236{
2237  register struct exception_table_node *table = exception_table_list;
2238  for ( ; table != 0; table = table->next)
2239    {
2240      if (table->start <= pc && table->end > pc)
2241        return table->table;
2242    }
2243  return 0;
2244}
2245
2246/* this routine takes a pc, and the address of the exception handler associated
2247   with the closest exception table handler entry associated with that PC,
2248   or 0 if there are no table entries the PC fits in.  The algorithm works
2249   something like this:
2250
2251    while(current_entry exists) {
2252        if(current_entry.start < pc )
2253            current_entry = next_entry;
2254        else {
2255            if(prev_entry.start <= pc && prev_entry.end > pc) {
2256                save pointer to prev_entry;
2257                return prev_entry.exception_handler;
2258             }
2259            else return 0;
2260         }
2261     }
2262    return 0;
2263
2264   Assuming a correctly sorted table (ascending order) this routine should
2265   return the tightest match...
2266
2267   In the advent of a tie, we have to give the last entry, as it represents
2268   an inner block.
2269 */
2270
2271
2272void *
2273__find_first_exception_table_match(pc)
2274void *pc;
2275{
2276  exception_table *table = find_exception_table (pc);
2277  int pos = 0;
2278  int best = 0;
2279  if (table == 0)
2280    return (void*)0;
2281#if 0
2282  printf("find_first_exception_table_match(): pc = %x!\n",pc);
2283#endif
2284
2285  except_pc = pc;
2286
2287#if 0
2288  /* We can't do this yet, as we don't know that the table is sorted.  */
2289  do {
2290    ++pos;
2291    if (table[pos].start > except_pc)
2292      /* found the first table[pos].start > except_pc, so the previous
2293         entry better be the one we want! */
2294      break;
2295  } while(table[pos].exception_handler != (void*)-1);
2296
2297  --pos;
2298  if (table[pos].start <= except_pc && table[pos].end > except_pc)
2299    {
2300      except_table_pos = pos;
2301#if 0
2302      printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2303#endif
2304      return table[pos].exception_handler;
2305    }
2306#else
2307  while (table[++pos].exception_handler != (void*)-1) {
2308    if (table[pos].start <= except_pc && table[pos].end > except_pc)
2309      {
2310        /* This can apply.  Make sure it is better or as good as the previous
2311           best.  */
2312        /* The best one ends first. */
2313        if (best == 0 || (table[pos].end <= table[best].end
2314                          /* The best one starts last.  */
2315                          && table[pos].start >= table[best].start))
2316          best = pos;
2317      }
2318  }
2319  if (best != 0)
2320    return table[best].exception_handler;
2321#endif
2322
2323#if 0
2324  printf("find_first_eh_table_match(): else: returning NULL!\n");
2325#endif
2326  return (void*)0;
2327}
2328
2329void *
2330__throw_type_match (void *catch_type, void *throw_type, void* obj)
2331{
2332#if 0
2333 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2334        catch_type, throw_type);
2335#endif
2336 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2337   return obj;
2338 return 0;
2339}
2340
2341void
2342__register_exceptions (exception_table *table)
2343{
2344  struct exception_table_node *node;
2345  exception_table *range = table + 1;
2346
2347  if (range->start == (void*)-1)
2348    return;
2349
2350  node = (struct exception_table_node*)
2351    malloc (sizeof (struct exception_table_node));
2352  node->table = table;
2353
2354  /* This look can be optimized away either if the table
2355     is sorted, or if we pass in extra parameters. */
2356  node->start = range->start;
2357  node->end = range->end;
2358  for (range++ ; range->start != (void*)(-1); range++)
2359    {
2360      if (range->start < node->start)
2361        node->start = range->start;
2362      if (range->end > node->end)
2363        node->end = range->end;
2364    }
2365
2366  node->next = exception_table_list;
2367  exception_table_list = node;
2368}
2369
2370#if #machine(i386)
2371void
2372__unwind_function(void *ptr)
2373{
2374  asm("movl 8(%esp),%ecx");
2375  /* Undo current frame */
2376  asm("movl %ebp,%esp");
2377  asm("popl %ebp");
2378  /* like ret, but stay here */
2379  asm("addl $4,%esp");
2380 
2381  /* Now, undo previous frame. */
2382  /* This is a test routine, as we have to dynamically probe to find out
2383     what to pop for certain, this is just a guess. */
2384  asm("leal -16(%ebp),%esp");
2385  asm("pop %ebx");
2386  asm("pop %esi");
2387  asm("pop %edi");
2388  asm("movl %ebp,%esp");
2389  asm("popl %ebp");
2390
2391  asm("movl %ecx,0(%esp)");
2392  asm("ret");
2393}
2394#elif #machine(rs6000)
2395__unwind_function(void *ptr)
2396{
2397  asm("mr 31,1");
2398  asm("l 1,0(1)");
2399  asm("l 31,-4(1)");
2400  asm("# br");
2401
2402  asm("mr 31,1");
2403  asm("l 1,0(1)");
2404  /* use 31 as a scratch register to restore the link register. */
2405  asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2406  asm("l 31,-4(1)");
2407  asm("# br");
2408  asm("mtctr 3;bctr # b 3");
2409}
2410#elif #machine(powerpc)
2411__unwind_function(void *ptr)
2412{
2413  asm("mr 31,1");
2414  asm("lwz 1,0(1)");
2415  asm("lwz 31,-4(1)");
2416  asm("# br");
2417
2418  asm("mr 31,1");
2419  asm("lwz 1,0(1)");
2420  /* use 31 as a scratch register to restore the link register. */
2421  asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2422  asm("lwz 31,-4(1)");
2423  asm("# br");
2424  asm("mtctr 3;bctr # b 3");
2425}
2426#elif #machine(vax)
2427__unwind_function(void *ptr)
2428{
2429  __label__ return_again;
2430
2431  /* Replace our frame's return address with the label below.
2432     During execution, we will first return here instead of to
2433     caller, then second return takes caller's frame off the stack.
2434     Two returns matches two actual calls, so is less likely to
2435     confuse debuggers.  `16' corresponds to RETURN_ADDRESS_OFFSET.  */
2436  __asm ("movl %0,16(fp)" : : "p" (&& return_again));
2437  return;
2438
2439 return_again:
2440  return;
2441}
2442#else
2443__unwind_function(void *ptr)
2444{
2445  abort ();
2446}
2447#endif /* powerpc */
2448#endif /* L_eh */
2449
2450#ifdef L_pure
2451#ifndef inhibit_libc
2452/* This gets us __GNU_LIBRARY__.  */
2453#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2454#include <stdio.h>
2455
2456#ifdef __GNU_LIBRARY__
2457  /* Avoid forcing the library's meaning of `write' on the user program
2458     by using the "internal" name (for use within the library)  */
2459#define write(fd, buf, n)       __write((fd), (buf), (n))
2460#endif
2461#endif /* inhibit_libc */
2462
2463#define MESSAGE "pure virtual method called\n"
2464
2465void
2466__pure_virtual ()
2467{
2468#ifndef inhibit_libc
2469  write (2, MESSAGE, sizeof (MESSAGE) - 1);
2470#endif
2471  _exit (-1);
2472}
2473#endif
Note: See TracBrowser for help on using the repository browser.