libgcc2.c revision 104764
1362679Sdim/* More subroutines needed by GCC output code on some machines.  */
2362679Sdim/* Compile this one with gcc.  */
3362679Sdim/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4362679Sdim   2000, 2001, 2002  Free Software Foundation, Inc.
5362679Sdim
6362679SdimThis file is part of GCC.
7362679Sdim
8362679SdimGCC is free software; you can redistribute it and/or modify it under
9362679Sdimthe terms of the GNU General Public License as published by the Free
10362679SdimSoftware Foundation; either version 2, or (at your option) any later
11362679Sdimversion.
12362679Sdim
13362679SdimIn addition to the permissions in the GNU General Public License, the
14362679SdimFree Software Foundation gives you unlimited permission to link the
15362679Sdimcompiled version of this file into combinations with other programs,
16362679Sdimand to distribute those combinations without any restriction coming
17362679Sdimfrom the use of this file.  (The General Public License restrictions
18362679Sdimdo apply in other respects; for example, they cover modification of
19362679Sdimthe file, and distribution when not linked into a combine
20362679Sdimexecutable.)
21362679Sdim
22362679SdimGCC is distributed in the hope that it will be useful, but WITHOUT ANY
23362679SdimWARRANTY; without even the implied warranty of MERCHANTABILITY or
24362679SdimFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25362679Sdimfor more details.
26362679Sdim
27362679SdimYou should have received a copy of the GNU General Public License
28362679Sdimalong with GCC; see the file COPYING.  If not, write to the Free
29362679SdimSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
30362679Sdim02111-1307, USA.  */
31362679Sdim
32362679Sdim/* $FreeBSD: head/contrib/gcc/libgcc2.c 104764 2002-10-10 04:50:29Z kan $ */
33362679Sdim
34362679Sdim/* It is incorrect to include config.h here, because this file is being
35362679Sdim   compiled for the target, and hence definitions concerning only the host
36362679Sdim   do not apply.  */
37362679Sdim
38362679Sdim#include "tconfig.h"
39362679Sdim#include "tsystem.h"
40362679Sdim
41362679Sdim/* Don't use `fancy_abort' here even if config.h says to use it.  */
42362679Sdim#ifdef abort
43362679Sdim#undef abort
44362679Sdim#endif
45362679Sdim
46362679Sdim#include "libgcc2.h"
47362679Sdim
48362679Sdim#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
49362679Sdim#if defined (L_divdi3) || defined (L_moddi3)
50362679Sdimstatic inline
51362679Sdim#endif
52362679SdimDWtype
53362679Sdim__negdi2 (DWtype u)
54362679Sdim{
55362679Sdim  DWunion w;
56362679Sdim  DWunion uu;
57362679Sdim
58362679Sdim  uu.ll = u;
59362679Sdim
60362679Sdim  w.s.low = -uu.s.low;
61362679Sdim  w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
62362679Sdim
63362679Sdim  return w.ll;
64362679Sdim}
65362679Sdim#endif
66362679Sdim
67362679Sdim#ifdef L_addvsi3
68362679SdimWtype
69362679Sdim__addvsi3 (Wtype a, Wtype b)
70362679Sdim{
71362679Sdim  Wtype w;
72362679Sdim
73362679Sdim  w = a + b;
74362679Sdim
75362679Sdim  if (b >= 0 ? w < a : w > a)
76362679Sdim    abort ();
77362679Sdim
78362679Sdim  return w;
79362679Sdim}
80362679Sdim#endif
81362679Sdim
82362679Sdim#ifdef L_addvdi3
83362679SdimDWtype
84362679Sdim__addvdi3 (DWtype a, DWtype b)
85362679Sdim{
86362679Sdim  DWtype w;
87362679Sdim
88362679Sdim  w = a + b;
89362679Sdim
90362679Sdim  if (b >= 0 ? w < a : w > a)
91362679Sdim    abort ();
92362679Sdim
93362679Sdim  return w;
94362679Sdim}
95362679Sdim#endif
96362679Sdim
97362679Sdim#ifdef L_subvsi3
98362679SdimWtype
99362679Sdim__subvsi3 (Wtype a, Wtype b)
100362679Sdim{
101362679Sdim#ifdef L_addvsi3
102362679Sdim  return __addvsi3 (a, (-b));
103362679Sdim#else
104362679Sdim  DWtype w;
105362679Sdim
106362679Sdim  w = a - b;
107362679Sdim
108362679Sdim  if (b >= 0 ? w > a : w < a)
109362679Sdim    abort ();
110362679Sdim
111362679Sdim  return w;
112362679Sdim#endif
113362679Sdim}
114362679Sdim#endif
115362679Sdim
116362679Sdim#ifdef L_subvdi3
117362679SdimDWtype
118362679Sdim__subvdi3 (DWtype a, DWtype b)
119362679Sdim{
120362679Sdim#ifdef L_addvdi3
121362679Sdim  return (a, (-b));
122362679Sdim#else
123362679Sdim  DWtype w;
124362679Sdim
125362679Sdim  w = a - b;
126362679Sdim
127362679Sdim  if (b >= 0 ? w > a : w < a)
128362679Sdim    abort ();
129362679Sdim
130362679Sdim  return w;
131362679Sdim#endif
132362679Sdim}
133362679Sdim#endif
134362679Sdim
135362679Sdim#ifdef L_mulvsi3
136362679SdimWtype
137362679Sdim__mulvsi3 (Wtype a, Wtype b)
138362679Sdim{
139362679Sdim  DWtype w;
140362679Sdim
141362679Sdim  w = a * b;
142362679Sdim
143362679Sdim  if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
144362679Sdim    abort ();
145362679Sdim
146362679Sdim  return w;
147362679Sdim}
148362679Sdim#endif
149362679Sdim
150362679Sdim#ifdef L_negvsi2
151362679SdimWtype
152362679Sdim__negvsi2 (Wtype a)
153362679Sdim{
154362679Sdim   Wtype w;
155362679Sdim
156362679Sdim   w  = -a;
157362679Sdim
158362679Sdim  if (a >= 0 ? w > 0 : w < 0)
159362679Sdim    abort ();
160362679Sdim
161362679Sdim   return w;
162362679Sdim}
163362679Sdim#endif
164362679Sdim
165362679Sdim#ifdef L_negvdi2
166362679SdimDWtype
167362679Sdim__negvdi2 (DWtype a)
168362679Sdim{
169362679Sdim   DWtype w;
170362679Sdim
171362679Sdim   w  = -a;
172362679Sdim
173362679Sdim  if (a >= 0 ? w > 0 : w < 0)
174362679Sdim    abort ();
175362679Sdim
176362679Sdim   return w;
177362679Sdim}
178362679Sdim#endif
179362679Sdim
180362679Sdim#ifdef L_absvsi2
181362679SdimWtype
182362679Sdim__absvsi2 (Wtype a)
183362679Sdim{
184362679Sdim   Wtype w = a;
185362679Sdim
186362679Sdim   if (a < 0)
187362679Sdim#ifdef L_negvsi2
188362679Sdim     w = __negvsi2 (a);
189362679Sdim#else
190362679Sdim     w = -a;
191362679Sdim
192362679Sdim   if (w < 0)
193362679Sdim     abort ();
194362679Sdim#endif
195362679Sdim
196362679Sdim   return w;
197362679Sdim}
198362679Sdim#endif
199362679Sdim
200362679Sdim#ifdef L_absvdi2
201362679SdimDWtype
202362679Sdim__absvdi2 (DWtype a)
203362679Sdim{
204362679Sdim   DWtype w = a;
205362679Sdim
206362679Sdim   if (a < 0)
207362679Sdim#ifdef L_negvsi2
208362679Sdim     w = __negvsi2 (a);
209362679Sdim#else
210362679Sdim     w = -a;
211362679Sdim
212362679Sdim   if (w < 0)
213362679Sdim     abort ();
214362679Sdim#endif
215362679Sdim
216362679Sdim   return w;
217362679Sdim}
218362679Sdim#endif
219362679Sdim
220362679Sdim#ifdef L_mulvdi3
221362679SdimDWtype
222362679Sdim__mulvdi3 (DWtype u, DWtype v)
223362679Sdim{
224362679Sdim   DWtype w;
225362679Sdim
226362679Sdim  w = u * v;
227362679Sdim
228362679Sdim  if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
229362679Sdim    abort ();
230362679Sdim
231362679Sdim  return w;
232362679Sdim}
233362679Sdim#endif
234362679Sdim
235362679Sdim
236362679Sdim/* Unless shift functions are defined whith full ANSI prototypes,
237362679Sdim   parameter b will be promoted to int if word_type is smaller than an int.  */
238362679Sdim#ifdef L_lshrdi3
239362679SdimDWtype
240362679Sdim__lshrdi3 (DWtype u, word_type b)
241362679Sdim{
242362679Sdim  DWunion w;
243362679Sdim  word_type bm;
244362679Sdim  DWunion uu;
245362679Sdim
246362679Sdim  if (b == 0)
247362679Sdim    return u;
248362679Sdim
249362679Sdim  uu.ll = u;
250362679Sdim
251362679Sdim  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
252362679Sdim  if (bm <= 0)
253362679Sdim    {
254362679Sdim      w.s.high = 0;
255362679Sdim      w.s.low = (UWtype) uu.s.high >> -bm;
256362679Sdim    }
257362679Sdim  else
258362679Sdim    {
259362679Sdim      UWtype carries = (UWtype) uu.s.high << bm;
260362679Sdim
261362679Sdim      w.s.high = (UWtype) uu.s.high >> b;
262362679Sdim      w.s.low = ((UWtype) uu.s.low >> b) | carries;
263362679Sdim    }
264362679Sdim
265362679Sdim  return w.ll;
266362679Sdim}
267362679Sdim#endif
268362679Sdim
269362679Sdim#ifdef L_ashldi3
270362679SdimDWtype
271362679Sdim__ashldi3 (DWtype u, word_type b)
272362679Sdim{
273362679Sdim  DWunion w;
274362679Sdim  word_type bm;
275362679Sdim  DWunion uu;
276362679Sdim
277362679Sdim  if (b == 0)
278362679Sdim    return u;
279362679Sdim
280362679Sdim  uu.ll = u;
281362679Sdim
282362679Sdim  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
283362679Sdim  if (bm <= 0)
284362679Sdim    {
285362679Sdim      w.s.low = 0;
286362679Sdim      w.s.high = (UWtype) uu.s.low << -bm;
287362679Sdim    }
288362679Sdim  else
289362679Sdim    {
290362679Sdim      UWtype carries = (UWtype) uu.s.low >> bm;
291362679Sdim
292362679Sdim      w.s.low = (UWtype) uu.s.low << b;
293362679Sdim      w.s.high = ((UWtype) uu.s.high << b) | carries;
294362679Sdim    }
295362679Sdim
296362679Sdim  return w.ll;
297362679Sdim}
298362679Sdim#endif
299362679Sdim
300362679Sdim#ifdef L_ashrdi3
301362679SdimDWtype
302362679Sdim__ashrdi3 (DWtype u, word_type b)
303362679Sdim{
304362679Sdim  DWunion w;
305362679Sdim  word_type bm;
306362679Sdim  DWunion uu;
307362679Sdim
308362679Sdim  if (b == 0)
309362679Sdim    return u;
310362679Sdim
311362679Sdim  uu.ll = u;
312362679Sdim
313362679Sdim  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
314362679Sdim  if (bm <= 0)
315362679Sdim    {
316362679Sdim      /* w.s.high = 1..1 or 0..0 */
317362679Sdim      w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
318362679Sdim      w.s.low = uu.s.high >> -bm;
319362679Sdim    }
320362679Sdim  else
321362679Sdim    {
322362679Sdim      UWtype carries = (UWtype) uu.s.high << bm;
323362679Sdim
324362679Sdim      w.s.high = uu.s.high >> b;
325362679Sdim      w.s.low = ((UWtype) uu.s.low >> b) | carries;
326362679Sdim    }
327362679Sdim
328362679Sdim  return w.ll;
329362679Sdim}
330362679Sdim#endif
331362679Sdim
332362679Sdim#ifdef L_ffsdi2
333362679SdimDWtype
334362679Sdim__ffsdi2 (DWtype u)
335362679Sdim{
336362679Sdim  DWunion uu;
337362679Sdim  UWtype word, count, add;
338362679Sdim
339362679Sdim  uu.ll = u;
340362679Sdim  if (uu.s.low != 0)
341362679Sdim    word = uu.s.low, add = 0;
342362679Sdim  else if (uu.s.high != 0)
343362679Sdim    word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
344362679Sdim  else
345362679Sdim    return 0;
346362679Sdim
347362679Sdim  count_trailing_zeros (count, word);
348362679Sdim  return count + add + 1;
349362679Sdim}
350362679Sdim#endif
351362679Sdim
352362679Sdim#ifdef L_muldi3
353362679SdimDWtype
354362679Sdim__muldi3 (DWtype u, DWtype v)
355362679Sdim{
356362679Sdim  DWunion w;
357362679Sdim  DWunion uu, vv;
358362679Sdim
359362679Sdim  uu.ll = u,
360362679Sdim  vv.ll = v;
361362679Sdim
362362679Sdim  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
363362679Sdim  w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
364362679Sdim	       + (UWtype) uu.s.high * (UWtype) vv.s.low);
365362679Sdim
366362679Sdim  return w.ll;
367362679Sdim}
368362679Sdim#endif
369362679Sdim
370362679Sdim#ifdef L_udiv_w_sdiv
371362679Sdim#if defined (sdiv_qrnnd)
372362679SdimUWtype
373362679Sdim__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
374362679Sdim{
375362679Sdim  UWtype q, r;
376362679Sdim  UWtype c0, c1, b1;
377362679Sdim
378362679Sdim  if ((Wtype) d >= 0)
379362679Sdim    {
380362679Sdim      if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
381362679Sdim	{
382362679Sdim	  /* dividend, divisor, and quotient are nonnegative */
383362679Sdim	  sdiv_qrnnd (q, r, a1, a0, d);
384362679Sdim	}
385362679Sdim      else
386362679Sdim	{
387362679Sdim	  /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
388362679Sdim	  sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
389362679Sdim	  /* Divide (c1*2^32 + c0) by d */
390362679Sdim	  sdiv_qrnnd (q, r, c1, c0, d);
391362679Sdim	  /* Add 2^31 to quotient */
392362679Sdim	  q += (UWtype) 1 << (W_TYPE_SIZE - 1);
393362679Sdim	}
394362679Sdim    }
395362679Sdim  else
396362679Sdim    {
397362679Sdim      b1 = d >> 1;			/* d/2, between 2^30 and 2^31 - 1 */
398362679Sdim      c1 = a1 >> 1;			/* A/2 */
399362679Sdim      c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
400362679Sdim
401362679Sdim      if (a1 < b1)			/* A < 2^32*b1, so A/2 < 2^31*b1 */
402362679Sdim	{
403362679Sdim	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
404362679Sdim
405362679Sdim	  r = 2*r + (a0 & 1);		/* Remainder from A/(2*b1) */
406362679Sdim	  if ((d & 1) != 0)
407362679Sdim	    {
408362679Sdim	      if (r >= q)
409362679Sdim		r = r - q;
410362679Sdim	      else if (q - r <= d)
411362679Sdim		{
412362679Sdim		  r = r - q + d;
413362679Sdim		  q--;
414362679Sdim		}
415362679Sdim	      else
416362679Sdim		{
417362679Sdim		  r = r - q + 2*d;
418362679Sdim		  q -= 2;
419362679Sdim		}
420362679Sdim	    }
421362679Sdim	}
422362679Sdim      else if (c1 < b1)			/* So 2^31 <= (A/2)/b1 < 2^32 */
423362679Sdim	{
424362679Sdim	  c1 = (b1 - 1) - c1;
425362679Sdim	  c0 = ~c0;			/* logical NOT */
426362679Sdim
427362679Sdim	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
428362679Sdim
429362679Sdim	  q = ~q;			/* (A/2)/b1 */
430362679Sdim	  r = (b1 - 1) - r;
431362679Sdim
432362679Sdim	  r = 2*r + (a0 & 1);		/* A/(2*b1) */
433362679Sdim
434362679Sdim	  if ((d & 1) != 0)
435362679Sdim	    {
436362679Sdim	      if (r >= q)
437362679Sdim		r = r - q;
438362679Sdim	      else if (q - r <= d)
439362679Sdim		{
440362679Sdim		  r = r - q + d;
441362679Sdim		  q--;
442362679Sdim		}
443362679Sdim	      else
444362679Sdim		{
445362679Sdim		  r = r - q + 2*d;
446362679Sdim		  q -= 2;
447362679Sdim		}
448362679Sdim	    }
449362679Sdim	}
450362679Sdim      else				/* Implies c1 = b1 */
451362679Sdim	{				/* Hence a1 = d - 1 = 2*b1 - 1 */
452362679Sdim	  if (a0 >= -d)
453362679Sdim	    {
454362679Sdim	      q = -1;
455362679Sdim	      r = a0 + d;
456362679Sdim	    }
457362679Sdim	  else
458362679Sdim	    {
459362679Sdim	      q = -2;
460362679Sdim	      r = a0 + 2*d;
461362679Sdim	    }
462362679Sdim	}
463362679Sdim    }
464362679Sdim
465362679Sdim  *rp = r;
466362679Sdim  return q;
467362679Sdim}
468362679Sdim#else
469362679Sdim/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
470362679SdimUWtype
471362679Sdim__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
472362679Sdim	       UWtype a1 __attribute__ ((__unused__)),
473362679Sdim	       UWtype a0 __attribute__ ((__unused__)),
474362679Sdim	       UWtype d __attribute__ ((__unused__)))
475362679Sdim{
476362679Sdim  return 0;
477362679Sdim}
478362679Sdim#endif
479362679Sdim#endif
480362679Sdim
481362679Sdim#if (defined (L_udivdi3) || defined (L_divdi3) || \
482362679Sdim     defined (L_umoddi3) || defined (L_moddi3))
483362679Sdim#define L_udivmoddi4
484362679Sdim#endif
485362679Sdim
486362679Sdim#ifdef L_clz
487362679Sdimconst UQItype __clz_tab[] =
488362679Sdim{
489362679Sdim  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,
490362679Sdim  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,
491362679Sdim  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,
492362679Sdim  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,
493362679Sdim  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,
494362679Sdim  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,
495362679Sdim  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,
496362679Sdim  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,
497362679Sdim};
498362679Sdim#endif
499362679Sdim
500362679Sdim#ifdef L_udivmoddi4
501362679Sdim
502362679Sdim#if (defined (L_udivdi3) || defined (L_divdi3) || \
503362679Sdim     defined (L_umoddi3) || defined (L_moddi3))
504362679Sdimstatic inline
505362679Sdim#endif
506362679SdimUDWtype
507362679Sdim__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
508362679Sdim{
509362679Sdim  DWunion ww;
510362679Sdim  DWunion nn, dd;
511362679Sdim  DWunion rr;
512362679Sdim  UWtype d0, d1, n0, n1, n2;
513362679Sdim  UWtype q0, q1;
514362679Sdim  UWtype b, bm;
515362679Sdim
516362679Sdim  nn.ll = n;
517362679Sdim  dd.ll = d;
518362679Sdim
519362679Sdim  d0 = dd.s.low;
520362679Sdim  d1 = dd.s.high;
521362679Sdim  n0 = nn.s.low;
522362679Sdim  n1 = nn.s.high;
523362679Sdim
524362679Sdim#if !UDIV_NEEDS_NORMALIZATION
525362679Sdim  if (d1 == 0)
526362679Sdim    {
527362679Sdim      if (d0 > n1)
528362679Sdim	{
529362679Sdim	  /* 0q = nn / 0D */
530362679Sdim
531362679Sdim	  udiv_qrnnd (q0, n0, n1, n0, d0);
532362679Sdim	  q1 = 0;
533362679Sdim
534362679Sdim	  /* Remainder in n0.  */
535362679Sdim	}
536362679Sdim      else
537362679Sdim	{
538362679Sdim	  /* qq = NN / 0d */
539362679Sdim
540362679Sdim	  if (d0 == 0)
541362679Sdim	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
542362679Sdim
543362679Sdim	  udiv_qrnnd (q1, n1, 0, n1, d0);
544362679Sdim	  udiv_qrnnd (q0, n0, n1, n0, d0);
545362679Sdim
546362679Sdim	  /* Remainder in n0.  */
547362679Sdim	}
548362679Sdim
549362679Sdim      if (rp != 0)
550362679Sdim	{
551362679Sdim	  rr.s.low = n0;
552362679Sdim	  rr.s.high = 0;
553362679Sdim	  *rp = rr.ll;
554362679Sdim	}
555362679Sdim    }
556362679Sdim
557362679Sdim#else /* UDIV_NEEDS_NORMALIZATION */
558362679Sdim
559362679Sdim  if (d1 == 0)
560362679Sdim    {
561362679Sdim      if (d0 > n1)
562362679Sdim	{
563362679Sdim	  /* 0q = nn / 0D */
564362679Sdim
565362679Sdim	  count_leading_zeros (bm, d0);
566362679Sdim
567362679Sdim	  if (bm != 0)
568362679Sdim	    {
569362679Sdim	      /* Normalize, i.e. make the most significant bit of the
570362679Sdim		 denominator set.  */
571362679Sdim
572362679Sdim	      d0 = d0 << bm;
573362679Sdim	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
574362679Sdim	      n0 = n0 << bm;
575362679Sdim	    }
576362679Sdim
577362679Sdim	  udiv_qrnnd (q0, n0, n1, n0, d0);
578362679Sdim	  q1 = 0;
579362679Sdim
580362679Sdim	  /* Remainder in n0 >> bm.  */
581362679Sdim	}
582362679Sdim      else
583362679Sdim	{
584362679Sdim	  /* qq = NN / 0d */
585362679Sdim
586362679Sdim	  if (d0 == 0)
587362679Sdim	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
588362679Sdim
589362679Sdim	  count_leading_zeros (bm, d0);
590362679Sdim
591362679Sdim	  if (bm == 0)
592362679Sdim	    {
593362679Sdim	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
594362679Sdim		 conclude (the most significant bit of n1 is set) /\ (the
595362679Sdim		 leading quotient digit q1 = 1).
596362679Sdim
597362679Sdim		 This special case is necessary, not an optimization.
598362679Sdim		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
599362679Sdim
600362679Sdim	      n1 -= d0;
601362679Sdim	      q1 = 1;
602362679Sdim	    }
603362679Sdim	  else
604362679Sdim	    {
605362679Sdim	      /* Normalize.  */
606362679Sdim
607362679Sdim	      b = W_TYPE_SIZE - bm;
608362679Sdim
609362679Sdim	      d0 = d0 << bm;
610362679Sdim	      n2 = n1 >> b;
611362679Sdim	      n1 = (n1 << bm) | (n0 >> b);
612362679Sdim	      n0 = n0 << bm;
613362679Sdim
614362679Sdim	      udiv_qrnnd (q1, n1, n2, n1, d0);
615362679Sdim	    }
616362679Sdim
617362679Sdim	  /* n1 != d0...  */
618362679Sdim
619362679Sdim	  udiv_qrnnd (q0, n0, n1, n0, d0);
620362679Sdim
621362679Sdim	  /* Remainder in n0 >> bm.  */
622362679Sdim	}
623362679Sdim
624362679Sdim      if (rp != 0)
625362679Sdim	{
626362679Sdim	  rr.s.low = n0 >> bm;
627362679Sdim	  rr.s.high = 0;
628362679Sdim	  *rp = rr.ll;
629362679Sdim	}
630362679Sdim    }
631362679Sdim#endif /* UDIV_NEEDS_NORMALIZATION */
632362679Sdim
633362679Sdim  else
634362679Sdim    {
635362679Sdim      if (d1 > n1)
636362679Sdim	{
637362679Sdim	  /* 00 = nn / DD */
638362679Sdim
639362679Sdim	  q0 = 0;
640362679Sdim	  q1 = 0;
641362679Sdim
642362679Sdim	  /* Remainder in n1n0.  */
643362679Sdim	  if (rp != 0)
644362679Sdim	    {
645362679Sdim	      rr.s.low = n0;
646362679Sdim	      rr.s.high = n1;
647362679Sdim	      *rp = rr.ll;
648362679Sdim	    }
649362679Sdim	}
650362679Sdim      else
651362679Sdim	{
652362679Sdim	  /* 0q = NN / dd */
653362679Sdim
654362679Sdim	  count_leading_zeros (bm, d1);
655362679Sdim	  if (bm == 0)
656362679Sdim	    {
657362679Sdim	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
658362679Sdim		 conclude (the most significant bit of n1 is set) /\ (the
659362679Sdim		 quotient digit q0 = 0 or 1).
660362679Sdim
661362679Sdim		 This special case is necessary, not an optimization.  */
662362679Sdim
663362679Sdim	      /* The condition on the next line takes advantage of that
664362679Sdim		 n1 >= d1 (true due to program flow).  */
665362679Sdim	      if (n1 > d1 || n0 >= d0)
666362679Sdim		{
667362679Sdim		  q0 = 1;
668362679Sdim		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
669362679Sdim		}
670362679Sdim	      else
671362679Sdim		q0 = 0;
672362679Sdim
673362679Sdim	      q1 = 0;
674362679Sdim
675362679Sdim	      if (rp != 0)
676362679Sdim		{
677362679Sdim		  rr.s.low = n0;
678362679Sdim		  rr.s.high = n1;
679362679Sdim		  *rp = rr.ll;
680362679Sdim		}
681362679Sdim	    }
682362679Sdim	  else
683362679Sdim	    {
684362679Sdim	      UWtype m1, m0;
685362679Sdim	      /* Normalize.  */
686362679Sdim
687362679Sdim	      b = W_TYPE_SIZE - bm;
688362679Sdim
689362679Sdim	      d1 = (d1 << bm) | (d0 >> b);
690362679Sdim	      d0 = d0 << bm;
691362679Sdim	      n2 = n1 >> b;
692362679Sdim	      n1 = (n1 << bm) | (n0 >> b);
693362679Sdim	      n0 = n0 << bm;
694362679Sdim
695362679Sdim	      udiv_qrnnd (q0, n1, n2, n1, d1);
696362679Sdim	      umul_ppmm (m1, m0, q0, d0);
697362679Sdim
698362679Sdim	      if (m1 > n1 || (m1 == n1 && m0 > n0))
699362679Sdim		{
700362679Sdim		  q0--;
701362679Sdim		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
702362679Sdim		}
703362679Sdim
704362679Sdim	      q1 = 0;
705362679Sdim
706362679Sdim	      /* Remainder in (n1n0 - m1m0) >> bm.  */
707362679Sdim	      if (rp != 0)
708362679Sdim		{
709362679Sdim		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
710362679Sdim		  rr.s.low = (n1 << b) | (n0 >> bm);
711362679Sdim		  rr.s.high = n1 >> bm;
712362679Sdim		  *rp = rr.ll;
713362679Sdim		}
714362679Sdim	    }
715362679Sdim	}
716362679Sdim    }
717362679Sdim
718362679Sdim  ww.s.low = q0;
719362679Sdim  ww.s.high = q1;
720362679Sdim  return ww.ll;
721362679Sdim}
722#endif
723
724#ifdef L_divdi3
725DWtype
726__divdi3 (DWtype u, DWtype v)
727{
728  word_type c = 0;
729  DWunion uu, vv;
730  DWtype w;
731
732  uu.ll = u;
733  vv.ll = v;
734
735  if (uu.s.high < 0)
736    c = ~c,
737    uu.ll = __negdi2 (uu.ll);
738  if (vv.s.high < 0)
739    c = ~c,
740    vv.ll = __negdi2 (vv.ll);
741
742  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
743  if (c)
744    w = __negdi2 (w);
745
746  return w;
747}
748#endif
749
750#ifdef L_moddi3
751DWtype
752__moddi3 (DWtype u, DWtype v)
753{
754  word_type c = 0;
755  DWunion uu, vv;
756  DWtype w;
757
758  uu.ll = u;
759  vv.ll = v;
760
761  if (uu.s.high < 0)
762    c = ~c,
763    uu.ll = __negdi2 (uu.ll);
764  if (vv.s.high < 0)
765    vv.ll = __negdi2 (vv.ll);
766
767  (void) __udivmoddi4 (uu.ll, vv.ll, &w);
768  if (c)
769    w = __negdi2 (w);
770
771  return w;
772}
773#endif
774
775#ifdef L_umoddi3
776UDWtype
777__umoddi3 (UDWtype u, UDWtype v)
778{
779  UDWtype w;
780
781  (void) __udivmoddi4 (u, v, &w);
782
783  return w;
784}
785#endif
786
787#ifdef L_udivdi3
788UDWtype
789__udivdi3 (UDWtype n, UDWtype d)
790{
791  return __udivmoddi4 (n, d, (UDWtype *) 0);
792}
793#endif
794
795#ifdef L_cmpdi2
796word_type
797__cmpdi2 (DWtype a, DWtype b)
798{
799  DWunion au, bu;
800
801  au.ll = a, bu.ll = b;
802
803  if (au.s.high < bu.s.high)
804    return 0;
805  else if (au.s.high > bu.s.high)
806    return 2;
807  if ((UWtype) au.s.low < (UWtype) bu.s.low)
808    return 0;
809  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
810    return 2;
811  return 1;
812}
813#endif
814
815#ifdef L_ucmpdi2
816word_type
817__ucmpdi2 (DWtype a, DWtype b)
818{
819  DWunion au, bu;
820
821  au.ll = a, bu.ll = b;
822
823  if ((UWtype) au.s.high < (UWtype) bu.s.high)
824    return 0;
825  else if ((UWtype) au.s.high > (UWtype) bu.s.high)
826    return 2;
827  if ((UWtype) au.s.low < (UWtype) bu.s.low)
828    return 0;
829  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
830    return 2;
831  return 1;
832}
833#endif
834
835#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
836#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
837#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
838
839DWtype
840__fixunstfDI (TFtype a)
841{
842  TFtype b;
843  UDWtype v;
844
845  if (a < 0)
846    return 0;
847
848  /* Compute high word of result, as a flonum.  */
849  b = (a / HIGH_WORD_COEFF);
850  /* Convert that to fixed (but not to DWtype!),
851     and shift it into the high word.  */
852  v = (UWtype) b;
853  v <<= WORD_SIZE;
854  /* Remove high part from the TFtype, leaving the low part as flonum.  */
855  a -= (TFtype)v;
856  /* Convert that to fixed (but not to DWtype!) and add it in.
857     Sometimes A comes out negative.  This is significant, since
858     A has more bits than a long int does.  */
859  if (a < 0)
860    v -= (UWtype) (- a);
861  else
862    v += (UWtype) a;
863  return v;
864}
865#endif
866
867#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
868DWtype
869__fixtfdi (TFtype a)
870{
871  if (a < 0)
872    return - __fixunstfDI (-a);
873  return __fixunstfDI (a);
874}
875#endif
876
877#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
878#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
879#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
880
881DWtype
882__fixunsxfDI (XFtype a)
883{
884  XFtype b;
885  UDWtype v;
886
887  if (a < 0)
888    return 0;
889
890  /* Compute high word of result, as a flonum.  */
891  b = (a / HIGH_WORD_COEFF);
892  /* Convert that to fixed (but not to DWtype!),
893     and shift it into the high word.  */
894  v = (UWtype) b;
895  v <<= WORD_SIZE;
896  /* Remove high part from the XFtype, leaving the low part as flonum.  */
897  a -= (XFtype)v;
898  /* Convert that to fixed (but not to DWtype!) and add it in.
899     Sometimes A comes out negative.  This is significant, since
900     A has more bits than a long int does.  */
901  if (a < 0)
902    v -= (UWtype) (- a);
903  else
904    v += (UWtype) a;
905  return v;
906}
907#endif
908
909#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
910DWtype
911__fixxfdi (XFtype a)
912{
913  if (a < 0)
914    return - __fixunsxfDI (-a);
915  return __fixunsxfDI (a);
916}
917#endif
918
919#ifdef L_fixunsdfdi
920#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
921#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
922
923DWtype
924__fixunsdfDI (DFtype a)
925{
926  DFtype b;
927  UDWtype v;
928
929  if (a < 0)
930    return 0;
931
932  /* Compute high word of result, as a flonum.  */
933  b = (a / HIGH_WORD_COEFF);
934  /* Convert that to fixed (but not to DWtype!),
935     and shift it into the high word.  */
936  v = (UWtype) b;
937  v <<= WORD_SIZE;
938  /* Remove high part from the DFtype, leaving the low part as flonum.  */
939  a -= (DFtype)v;
940  /* Convert that to fixed (but not to DWtype!) and add it in.
941     Sometimes A comes out negative.  This is significant, since
942     A has more bits than a long int does.  */
943  if (a < 0)
944    v -= (UWtype) (- a);
945  else
946    v += (UWtype) a;
947  return v;
948}
949#endif
950
951#ifdef L_fixdfdi
952DWtype
953__fixdfdi (DFtype a)
954{
955  if (a < 0)
956    return - __fixunsdfDI (-a);
957  return __fixunsdfDI (a);
958}
959#endif
960
961#ifdef L_fixunssfdi
962#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
963#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
964
965DWtype
966__fixunssfDI (SFtype original_a)
967{
968  /* Convert the SFtype to a DFtype, because that is surely not going
969     to lose any bits.  Some day someone else can write a faster version
970     that avoids converting to DFtype, and verify it really works right.  */
971  DFtype a = original_a;
972  DFtype b;
973  UDWtype v;
974
975  if (a < 0)
976    return 0;
977
978  /* Compute high word of result, as a flonum.  */
979  b = (a / HIGH_WORD_COEFF);
980  /* Convert that to fixed (but not to DWtype!),
981     and shift it into the high word.  */
982  v = (UWtype) b;
983  v <<= WORD_SIZE;
984  /* Remove high part from the DFtype, leaving the low part as flonum.  */
985  a -= (DFtype) v;
986  /* Convert that to fixed (but not to DWtype!) and add it in.
987     Sometimes A comes out negative.  This is significant, since
988     A has more bits than a long int does.  */
989  if (a < 0)
990    v -= (UWtype) (- a);
991  else
992    v += (UWtype) a;
993  return v;
994}
995#endif
996
997#ifdef L_fixsfdi
998DWtype
999__fixsfdi (SFtype a)
1000{
1001  if (a < 0)
1002    return - __fixunssfDI (-a);
1003  return __fixunssfDI (a);
1004}
1005#endif
1006
1007#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1008#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1009#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1010#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1011
1012XFtype
1013__floatdixf (DWtype u)
1014{
1015  XFtype d;
1016
1017  d = (Wtype) (u >> WORD_SIZE);
1018  d *= HIGH_HALFWORD_COEFF;
1019  d *= HIGH_HALFWORD_COEFF;
1020  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1021
1022  return d;
1023}
1024#endif
1025
1026#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1027#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1028#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1029#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1030
1031TFtype
1032__floatditf (DWtype u)
1033{
1034  TFtype d;
1035
1036  d = (Wtype) (u >> WORD_SIZE);
1037  d *= HIGH_HALFWORD_COEFF;
1038  d *= HIGH_HALFWORD_COEFF;
1039  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1040
1041  return d;
1042}
1043#endif
1044
1045#ifdef L_floatdidf
1046#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1047#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1048#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1049
1050DFtype
1051__floatdidf (DWtype u)
1052{
1053  DFtype d;
1054
1055  d = (Wtype) (u >> WORD_SIZE);
1056  d *= HIGH_HALFWORD_COEFF;
1057  d *= HIGH_HALFWORD_COEFF;
1058  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1059
1060  return d;
1061}
1062#endif
1063
1064#ifdef L_floatdisf
1065#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1067#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1068#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1069
1070/* Define codes for all the float formats that we know of.  Note
1071   that this is copied from real.h.  */
1072
1073#define UNKNOWN_FLOAT_FORMAT 0
1074#define IEEE_FLOAT_FORMAT 1
1075#define VAX_FLOAT_FORMAT 2
1076#define IBM_FLOAT_FORMAT 3
1077
1078/* Default to IEEE float if not specified.  Nearly all machines use it.  */
1079#ifndef HOST_FLOAT_FORMAT
1080#define	HOST_FLOAT_FORMAT	IEEE_FLOAT_FORMAT
1081#endif
1082
1083#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1084#define DF_SIZE 53
1085#define SF_SIZE 24
1086#endif
1087
1088#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1089#define DF_SIZE 56
1090#define SF_SIZE 24
1091#endif
1092
1093#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1094#define DF_SIZE 56
1095#define SF_SIZE 24
1096#endif
1097
1098SFtype
1099__floatdisf (DWtype u)
1100{
1101  /* Do the calculation in DFmode
1102     so that we don't lose any of the precision of the high word
1103     while multiplying it.  */
1104  DFtype f;
1105
1106  /* Protect against double-rounding error.
1107     Represent any low-order bits, that might be truncated in DFmode,
1108     by a bit that won't be lost.  The bit can go in anywhere below the
1109     rounding position of the SFmode.  A fixed mask and bit position
1110     handles all usual configurations.  It doesn't handle the case
1111     of 128-bit DImode, however.  */
1112  if (DF_SIZE < DI_SIZE
1113      && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1114    {
1115#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1116      if (! (- ((DWtype) 1 << DF_SIZE) < u
1117	     && u < ((DWtype) 1 << DF_SIZE)))
1118	{
1119	  if ((UDWtype) u & (REP_BIT - 1))
1120	    {
1121	      u &= ~ (REP_BIT - 1);
1122	      u |= REP_BIT;
1123	    }
1124	}
1125    }
1126  f = (Wtype) (u >> WORD_SIZE);
1127  f *= HIGH_HALFWORD_COEFF;
1128  f *= HIGH_HALFWORD_COEFF;
1129  f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1130
1131  return (SFtype) f;
1132}
1133#endif
1134
1135#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1136/* Reenable the normal types, in case limits.h needs them.  */
1137#undef char
1138#undef short
1139#undef int
1140#undef long
1141#undef unsigned
1142#undef float
1143#undef double
1144#undef MIN
1145#undef MAX
1146#include <limits.h>
1147
1148UWtype
1149__fixunsxfSI (XFtype a)
1150{
1151  if (a >= - (DFtype) Wtype_MIN)
1152    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1153  return (Wtype) a;
1154}
1155#endif
1156
1157#ifdef L_fixunsdfsi
1158/* Reenable the normal types, in case limits.h needs them.  */
1159#undef char
1160#undef short
1161#undef int
1162#undef long
1163#undef unsigned
1164#undef float
1165#undef double
1166#undef MIN
1167#undef MAX
1168#include <limits.h>
1169
1170UWtype
1171__fixunsdfSI (DFtype a)
1172{
1173  if (a >= - (DFtype) Wtype_MIN)
1174    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1175  return (Wtype) a;
1176}
1177#endif
1178
1179#ifdef L_fixunssfsi
1180/* Reenable the normal types, in case limits.h needs them.  */
1181#undef char
1182#undef short
1183#undef int
1184#undef long
1185#undef unsigned
1186#undef float
1187#undef double
1188#undef MIN
1189#undef MAX
1190#include <limits.h>
1191
1192UWtype
1193__fixunssfSI (SFtype a)
1194{
1195  if (a >= - (SFtype) Wtype_MIN)
1196    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1197  return (Wtype) a;
1198}
1199#endif
1200
1201/* From here on down, the routines use normal data types.  */
1202
1203#define SItype bogus_type
1204#define USItype bogus_type
1205#define DItype bogus_type
1206#define UDItype bogus_type
1207#define SFtype bogus_type
1208#define DFtype bogus_type
1209#undef Wtype
1210#undef UWtype
1211#undef HWtype
1212#undef UHWtype
1213#undef DWtype
1214#undef UDWtype
1215
1216#undef char
1217#undef short
1218#undef int
1219#undef long
1220#undef unsigned
1221#undef float
1222#undef double
1223
1224#ifdef L__gcc_bcmp
1225
1226/* Like bcmp except the sign is meaningful.
1227   Result is negative if S1 is less than S2,
1228   positive if S1 is greater, 0 if S1 and S2 are equal.  */
1229
1230int
1231__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1232{
1233  while (size > 0)
1234    {
1235      unsigned char c1 = *s1++, c2 = *s2++;
1236      if (c1 != c2)
1237	return c1 - c2;
1238      size--;
1239    }
1240  return 0;
1241}
1242
1243#endif
1244
1245/* __eprintf used to be used by GCC's private version of <assert.h>.
1246   We no longer provide that header, but this routine remains in libgcc.a
1247   for binary backward compatibility.  Note that it is not included in
1248   the shared version of libgcc.  */
1249#ifdef L_eprintf
1250#ifndef inhibit_libc
1251
1252#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1253#include <stdio.h>
1254
1255void
1256__eprintf (const char *string, const char *expression,
1257	   unsigned int line, const char *filename)
1258{
1259  fprintf (stderr, string, expression, line, filename);
1260  fflush (stderr);
1261  abort ();
1262}
1263
1264#endif
1265#endif
1266
1267#ifdef L_bb
1268
1269#if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
1270typedef long gcov_type;
1271#else
1272typedef long long gcov_type;
1273#endif
1274
1275
1276/* Structure emitted by -a  */
1277struct bb
1278{
1279  long zero_word;
1280  const char *filename;
1281  gcov_type *counts;
1282  long ncounts;
1283  struct bb *next;
1284  const unsigned long *addresses;
1285
1286  /* Older GCC's did not emit these fields.  */
1287  long nwords;
1288  const char **functions;
1289  const long *line_nums;
1290  const char **filenames;
1291  char *flags;
1292};
1293
1294#ifndef inhibit_libc
1295
1296/* Simple minded basic block profiling output dumper for
1297   systems that don't provide tcov support.  At present,
1298   it requires atexit and stdio.  */
1299
1300#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1301#include <stdio.h>
1302
1303#include "gbl-ctors.h"
1304#include "gcov-io.h"
1305#include <string.h>
1306#ifdef TARGET_HAS_F_SETLKW
1307#include <fcntl.h>
1308#include <errno.h>
1309#endif
1310
1311static struct bb *bb_head;
1312
1313void
1314__bb_exit_func (void)
1315{
1316  FILE *da_file;
1317  int i;
1318  struct bb *ptr;
1319
1320  if (bb_head == 0)
1321    return;
1322
1323  i = strlen (bb_head->filename) - 3;
1324
1325
1326  for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1327    {
1328      int firstchar;
1329
1330      /* Make sure the output file exists -
1331         but don't clobber exiting data.  */
1332      if ((da_file = fopen (ptr->filename, "a")) != 0)
1333	fclose (da_file);
1334
1335      /* Need to re-open in order to be able to write from the start.  */
1336      da_file = fopen (ptr->filename, "r+b");
1337      /* Some old systems might not allow the 'b' mode modifier.
1338         Therefore, try to open without it.  This can lead to a race
1339         condition so that when you delete and re-create the file, the
1340         file might be opened in text mode, but then, you shouldn't
1341         delete the file in the first place.  */
1342      if (da_file == 0)
1343	da_file = fopen (ptr->filename, "r+");
1344      if (da_file == 0)
1345	{
1346	  fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1347		   ptr->filename);
1348	  continue;
1349	}
1350
1351      /* After a fork, another process might try to read and/or write
1352         the same file simultanously.  So if we can, lock the file to
1353         avoid race conditions.  */
1354#if defined (TARGET_HAS_F_SETLKW)
1355      {
1356	struct flock s_flock;
1357
1358	s_flock.l_type = F_WRLCK;
1359	s_flock.l_whence = SEEK_SET;
1360	s_flock.l_start = 0;
1361	s_flock.l_len = 1;
1362	s_flock.l_pid = getpid ();
1363
1364	while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1365	       && errno == EINTR);
1366      }
1367#endif
1368
1369      /* If the file is not empty, and the number of counts in it is the
1370         same, then merge them in.  */
1371      firstchar = fgetc (da_file);
1372      if (firstchar == EOF)
1373	{
1374	  if (ferror (da_file))
1375	    {
1376	      fprintf (stderr, "arc profiling: Can't read output file ");
1377	      perror (ptr->filename);
1378	    }
1379	}
1380      else
1381	{
1382	  long n_counts = 0;
1383
1384	  if (ungetc (firstchar, da_file) == EOF)
1385	    rewind (da_file);
1386	  if (__read_long (&n_counts, da_file, 8) != 0)
1387	    {
1388	      fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1389		       ptr->filename);
1390	      continue;
1391	    }
1392
1393	  if (n_counts == ptr->ncounts)
1394	    {
1395	      int i;
1396
1397	      for (i = 0; i < n_counts; i++)
1398		{
1399		  gcov_type v = 0;
1400
1401		  if (__read_gcov_type (&v, da_file, 8) != 0)
1402		    {
1403		      fprintf (stderr,
1404			       "arc profiling: Can't read output file %s.\n",
1405			       ptr->filename);
1406		      break;
1407		    }
1408		  ptr->counts[i] += v;
1409		}
1410	    }
1411
1412	}
1413
1414      rewind (da_file);
1415
1416      /* ??? Should first write a header to the file.  Preferably, a 4 byte
1417         magic number, 4 bytes containing the time the program was
1418         compiled, 4 bytes containing the last modification time of the
1419         source file, and 4 bytes indicating the compiler options used.
1420
1421         That way we can easily verify that the proper source/executable/
1422         data file combination is being used from gcov.  */
1423
1424      if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
1425	{
1426
1427	  fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1428		   ptr->filename);
1429	}
1430      else
1431	{
1432	  int j;
1433	  gcov_type *count_ptr = ptr->counts;
1434	  int ret = 0;
1435	  for (j = ptr->ncounts; j > 0; j--)
1436	    {
1437	      if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1438		{
1439		  ret = 1;
1440		  break;
1441		}
1442	      count_ptr++;
1443	    }
1444	  if (ret)
1445	    fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1446		     ptr->filename);
1447	}
1448
1449      if (fclose (da_file) == EOF)
1450	fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1451		 ptr->filename);
1452    }
1453
1454  return;
1455}
1456
1457void
1458__bb_init_func (struct bb *blocks)
1459{
1460  /* User is supposed to check whether the first word is non-0,
1461     but just in case....  */
1462
1463  if (blocks->zero_word)
1464    return;
1465
1466  /* Initialize destructor.  */
1467  if (!bb_head)
1468    atexit (__bb_exit_func);
1469
1470  /* Set up linked list.  */
1471  blocks->zero_word = 1;
1472  blocks->next = bb_head;
1473  bb_head = blocks;
1474}
1475
1476/* Called before fork or exec - write out profile information gathered so
1477   far and reset it to zero.  This avoids duplication or loss of the
1478   profile information gathered so far.  */
1479void
1480__bb_fork_func (void)
1481{
1482  struct bb *ptr;
1483
1484  __bb_exit_func ();
1485  for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1486    {
1487      long i;
1488      for (i = ptr->ncounts - 1; i >= 0; i--)
1489	ptr->counts[i] = 0;
1490    }
1491}
1492
1493#endif /* not inhibit_libc */
1494#endif /* L_bb */
1495
1496#ifdef L_clear_cache
1497/* Clear part of an instruction cache.  */
1498
1499#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1500
1501void
1502__clear_cache (char *beg __attribute__((__unused__)),
1503	       char *end __attribute__((__unused__)))
1504{
1505#ifdef CLEAR_INSN_CACHE
1506  CLEAR_INSN_CACHE (beg, end);
1507#else
1508#ifdef INSN_CACHE_SIZE
1509  static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1510  static int initialized;
1511  int offset;
1512  void *start_addr
1513  void *end_addr;
1514  typedef (*function_ptr) (void);
1515
1516#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1517  /* It's cheaper to clear the whole cache.
1518     Put in a series of jump instructions so that calling the beginning
1519     of the cache will clear the whole thing.  */
1520
1521  if (! initialized)
1522    {
1523      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1524		 & -INSN_CACHE_LINE_WIDTH);
1525      int end_ptr = ptr + INSN_CACHE_SIZE;
1526
1527      while (ptr < end_ptr)
1528	{
1529	  *(INSTRUCTION_TYPE *)ptr
1530	    = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1531	  ptr += INSN_CACHE_LINE_WIDTH;
1532	}
1533      *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1534
1535      initialized = 1;
1536    }
1537
1538  /* Call the beginning of the sequence.  */
1539  (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1540		    & -INSN_CACHE_LINE_WIDTH))
1541   ());
1542
1543#else /* Cache is large.  */
1544
1545  if (! initialized)
1546    {
1547      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1548		 & -INSN_CACHE_LINE_WIDTH);
1549
1550      while (ptr < (int) array + sizeof array)
1551	{
1552	  *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1553	  ptr += INSN_CACHE_LINE_WIDTH;
1554	}
1555
1556      initialized = 1;
1557    }
1558
1559  /* Find the location in array that occupies the same cache line as BEG.  */
1560
1561  offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1562  start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1563		 & -INSN_CACHE_PLANE_SIZE)
1564		+ offset);
1565
1566  /* Compute the cache alignment of the place to stop clearing.  */
1567#if 0  /* This is not needed for gcc's purposes.  */
1568  /* If the block to clear is bigger than a cache plane,
1569     we clear the entire cache, and OFFSET is already correct.  */
1570  if (end < beg + INSN_CACHE_PLANE_SIZE)
1571#endif
1572    offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1573	       & -INSN_CACHE_LINE_WIDTH)
1574	      & (INSN_CACHE_PLANE_SIZE - 1));
1575
1576#if INSN_CACHE_DEPTH > 1
1577  end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1578  if (end_addr <= start_addr)
1579    end_addr += INSN_CACHE_PLANE_SIZE;
1580
1581  for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1582    {
1583      int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1584      int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1585
1586      while (addr != stop)
1587	{
1588	  /* Call the return instruction at ADDR.  */
1589	  ((function_ptr) addr) ();
1590
1591	  addr += INSN_CACHE_LINE_WIDTH;
1592	}
1593    }
1594#else /* just one plane */
1595  do
1596    {
1597      /* Call the return instruction at START_ADDR.  */
1598      ((function_ptr) start_addr) ();
1599
1600      start_addr += INSN_CACHE_LINE_WIDTH;
1601    }
1602  while ((start_addr % INSN_CACHE_SIZE) != offset);
1603#endif /* just one plane */
1604#endif /* Cache is large */
1605#endif /* Cache exists */
1606#endif /* CLEAR_INSN_CACHE */
1607}
1608
1609#endif /* L_clear_cache */
1610
1611#ifdef L_trampoline
1612
1613/* Jump to a trampoline, loading the static chain address.  */
1614
1615#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1616
1617long
1618getpagesize (void)
1619{
1620#ifdef _ALPHA_
1621  return 8192;
1622#else
1623  return 4096;
1624#endif
1625}
1626
1627#ifdef __i386__
1628extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1629#endif
1630
1631int
1632mprotect (char *addr, int len, int prot)
1633{
1634  int np, op;
1635
1636  if (prot == 7)
1637    np = 0x40;
1638  else if (prot == 5)
1639    np = 0x20;
1640  else if (prot == 4)
1641    np = 0x10;
1642  else if (prot == 3)
1643    np = 0x04;
1644  else if (prot == 1)
1645    np = 0x02;
1646  else if (prot == 0)
1647    np = 0x01;
1648
1649  if (VirtualProtect (addr, len, np, &op))
1650    return 0;
1651  else
1652    return -1;
1653}
1654
1655#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1656
1657#ifdef TRANSFER_FROM_TRAMPOLINE
1658TRANSFER_FROM_TRAMPOLINE
1659#endif
1660
1661#if defined (NeXT) && defined (__MACH__)
1662
1663/* Make stack executable so we can call trampolines on stack.
1664   This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1665#ifdef NeXTStep21
1666 #include <mach.h>
1667#else
1668 #include <mach/mach.h>
1669#endif
1670
1671void
1672__enable_execute_stack (char *addr)
1673{
1674  kern_return_t r;
1675  char *eaddr = addr + TRAMPOLINE_SIZE;
1676  vm_address_t a = (vm_address_t) addr;
1677
1678  /* turn on execute access on stack */
1679  r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1680  if (r != KERN_SUCCESS)
1681    {
1682      mach_error("vm_protect VM_PROT_ALL", r);
1683      exit(1);
1684    }
1685
1686  /* We inline the i-cache invalidation for speed */
1687
1688#ifdef CLEAR_INSN_CACHE
1689  CLEAR_INSN_CACHE (addr, eaddr);
1690#else
1691  __clear_cache ((int) addr, (int) eaddr);
1692#endif
1693}
1694
1695#endif /* defined (NeXT) && defined (__MACH__) */
1696
1697#ifdef __convex__
1698
1699/* Make stack executable so we can call trampolines on stack.
1700   This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1701
1702#include <sys/mman.h>
1703#include <sys/vmparam.h>
1704#include <machine/machparam.h>
1705
1706void
1707__enable_execute_stack (void)
1708{
1709  int fp;
1710  static unsigned lowest = USRSTACK;
1711  unsigned current = (unsigned) &fp & -NBPG;
1712
1713  if (lowest > current)
1714    {
1715      unsigned len = lowest - current;
1716      mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1717      lowest = current;
1718    }
1719
1720  /* Clear instruction cache in case an old trampoline is in it.  */
1721  asm ("pich");
1722}
1723#endif /* __convex__ */
1724
1725#ifdef __sysV88__
1726
1727/* Modified from the convex -code above.  */
1728
1729#include <sys/param.h>
1730#include <errno.h>
1731#include <sys/m88kbcs.h>
1732
1733void
1734__enable_execute_stack (void)
1735{
1736  int save_errno;
1737  static unsigned long lowest = USRSTACK;
1738  unsigned long current = (unsigned long) &save_errno & -NBPC;
1739
1740  /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1741     address is seen as 'negative'. That is the case with the stack.  */
1742
1743  save_errno=errno;
1744  if (lowest > current)
1745    {
1746      unsigned len=lowest-current;
1747      memctl(current,len,MCT_TEXT);
1748      lowest = current;
1749    }
1750  else
1751    memctl(current,NBPC,MCT_TEXT);
1752  errno=save_errno;
1753}
1754
1755#endif /* __sysV88__ */
1756
1757#ifdef __sysV68__
1758
1759#include <sys/signal.h>
1760#include <errno.h>
1761
1762/* Motorola forgot to put memctl.o in the libp version of libc881.a,
1763   so define it here, because we need it in __clear_insn_cache below */
1764/* On older versions of this OS, no memctl or MCT_TEXT are defined;
1765   hence we enable this stuff only if MCT_TEXT is #define'd.  */
1766
1767#ifdef MCT_TEXT
1768asm("\n\
1769	global memctl\n\
1770memctl:\n\
1771	movq &75,%d0\n\
1772	trap &0\n\
1773	bcc.b noerror\n\
1774	jmp cerror%\n\
1775noerror:\n\
1776	movq &0,%d0\n\
1777	rts");
1778#endif
1779
1780/* Clear instruction cache so we can call trampolines on stack.
1781   This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
1782
1783void
1784__clear_insn_cache (void)
1785{
1786#ifdef MCT_TEXT
1787  int save_errno;
1788
1789  /* Preserve errno, because users would be surprised to have
1790  errno changing without explicitly calling any system-call.  */
1791  save_errno = errno;
1792
1793  /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1794     No need to use an address derived from _start or %sp, as 0 works also.  */
1795  memctl(0, 4096, MCT_TEXT);
1796  errno = save_errno;
1797#endif
1798}
1799
1800#endif /* __sysV68__ */
1801
1802#ifdef __pyr__
1803
1804#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1805#include <stdio.h>
1806#include <sys/mman.h>
1807#include <sys/types.h>
1808#include <sys/param.h>
1809#include <sys/vmmac.h>
1810
1811/* Modified from the convex -code above.
1812   mremap promises to clear the i-cache.  */
1813
1814void
1815__enable_execute_stack (void)
1816{
1817  int fp;
1818  if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1819		PROT_READ|PROT_WRITE|PROT_EXEC))
1820    {
1821      perror ("mprotect in __enable_execute_stack");
1822      fflush (stderr);
1823      abort ();
1824    }
1825}
1826#endif /* __pyr__ */
1827
1828#if defined (sony_news) && defined (SYSTYPE_BSD)
1829
1830#include <stdio.h>
1831#include <sys/types.h>
1832#include <sys/param.h>
1833#include <syscall.h>
1834#include <machine/sysnews.h>
1835
1836/* cacheflush function for NEWS-OS 4.2.
1837   This function is called from trampoline-initialize code
1838   defined in config/mips/mips.h.  */
1839
1840void
1841cacheflush (char *beg, int size, int flag)
1842{
1843  if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1844    {
1845      perror ("cache_flush");
1846      fflush (stderr);
1847      abort ();
1848    }
1849}
1850
1851#endif /* sony_news */
1852#endif /* L_trampoline */
1853
1854#ifndef __CYGWIN__
1855#ifdef L__main
1856
1857#include "gbl-ctors.h"
1858/* Some systems use __main in a way incompatible with its use in gcc, in these
1859   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1860   give the same symbol without quotes for an alternative entry point.  You
1861   must define both, or neither.  */
1862#ifndef NAME__MAIN
1863#define NAME__MAIN "__main"
1864#define SYMBOL__MAIN __main
1865#endif
1866
1867#ifdef INIT_SECTION_ASM_OP
1868#undef HAS_INIT_SECTION
1869#define HAS_INIT_SECTION
1870#endif
1871
1872#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1873
1874/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1875   code to run constructors.  In that case, we need to handle EH here, too.  */
1876
1877#ifdef EH_FRAME_SECTION_NAME
1878#include "unwind-dw2-fde.h"
1879extern unsigned char __EH_FRAME_BEGIN__[];
1880#endif
1881
1882/* Run all the global destructors on exit from the program.  */
1883
1884void
1885__do_global_dtors (void)
1886{
1887#ifdef DO_GLOBAL_DTORS_BODY
1888  DO_GLOBAL_DTORS_BODY;
1889#else
1890  static func_ptr *p = __DTOR_LIST__ + 1;
1891  while (*p)
1892    {
1893      p++;
1894      (*(p-1)) ();
1895    }
1896#endif
1897#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1898  {
1899    static int completed = 0;
1900    if (! completed)
1901      {
1902	completed = 1;
1903	__deregister_frame_info (__EH_FRAME_BEGIN__);
1904      }
1905  }
1906#endif
1907}
1908#endif
1909
1910#ifndef HAS_INIT_SECTION
1911/* Run all the global constructors on entry to the program.  */
1912
1913void
1914__do_global_ctors (void)
1915{
1916#ifdef EH_FRAME_SECTION_NAME
1917  {
1918    static struct object object;
1919    __register_frame_info (__EH_FRAME_BEGIN__, &object);
1920  }
1921#endif
1922  DO_GLOBAL_CTORS_BODY;
1923  atexit (__do_global_dtors);
1924}
1925#endif /* no HAS_INIT_SECTION */
1926
1927#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1928/* Subroutine called automatically by `main'.
1929   Compiling a global function named `main'
1930   produces an automatic call to this function at the beginning.
1931
1932   For many systems, this routine calls __do_global_ctors.
1933   For systems which support a .init section we use the .init section
1934   to run __do_global_ctors, so we need not do anything here.  */
1935
1936void
1937SYMBOL__MAIN ()
1938{
1939  /* Support recursive calls to `main': run initializers just once.  */
1940  static int initialized;
1941  if (! initialized)
1942    {
1943      initialized = 1;
1944      __do_global_ctors ();
1945    }
1946}
1947#endif /* no HAS_INIT_SECTION or INVOKE__main */
1948
1949#endif /* L__main */
1950#endif /* __CYGWIN__ */
1951
1952#ifdef L_ctors
1953
1954#include "gbl-ctors.h"
1955
1956/* Provide default definitions for the lists of constructors and
1957   destructors, so that we don't get linker errors.  These symbols are
1958   intentionally bss symbols, so that gld and/or collect will provide
1959   the right values.  */
1960
1961/* We declare the lists here with two elements each,
1962   so that they are valid empty lists if no other definition is loaded.
1963
1964   If we are using the old "set" extensions to have the gnu linker
1965   collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1966   must be in the bss/common section.
1967
1968   Long term no port should use those extensions.  But many still do.  */
1969#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1970#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1971func_ptr __CTOR_LIST__[2] = {0, 0};
1972func_ptr __DTOR_LIST__[2] = {0, 0};
1973#else
1974func_ptr __CTOR_LIST__[2];
1975func_ptr __DTOR_LIST__[2];
1976#endif
1977#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1978#endif /* L_ctors */
1979
1980#ifdef L_exit
1981
1982#include "gbl-ctors.h"
1983
1984#ifdef NEED_ATEXIT
1985
1986#ifndef ON_EXIT
1987
1988# include <errno.h>
1989
1990static func_ptr *atexit_chain = 0;
1991static long atexit_chain_length = 0;
1992static volatile long last_atexit_chain_slot = -1;
1993
1994int
1995atexit (func_ptr func)
1996{
1997  if (++last_atexit_chain_slot == atexit_chain_length)
1998    {
1999      atexit_chain_length += 32;
2000      if (atexit_chain)
2001	atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2002					     * sizeof (func_ptr));
2003      else
2004	atexit_chain = (func_ptr *) malloc (atexit_chain_length
2005					    * sizeof (func_ptr));
2006      if (! atexit_chain)
2007	{
2008	  atexit_chain_length = 0;
2009	  last_atexit_chain_slot = -1;
2010	  errno = ENOMEM;
2011	  return (-1);
2012	}
2013    }
2014  atexit_chain[last_atexit_chain_slot] = func;
2015  return (0);
2016}
2017
2018extern void _cleanup (void);
2019extern void _exit (int) __attribute__ ((__noreturn__));
2020
2021void
2022exit (int status)
2023{
2024  if (atexit_chain)
2025    {
2026      for ( ; last_atexit_chain_slot-- >= 0; )
2027	{
2028	  (*atexit_chain[last_atexit_chain_slot + 1]) ();
2029	  atexit_chain[last_atexit_chain_slot + 1] = 0;
2030	}
2031      free (atexit_chain);
2032      atexit_chain = 0;
2033    }
2034#ifdef EXIT_BODY
2035  EXIT_BODY;
2036#else
2037  _cleanup ();
2038#endif
2039  _exit (status);
2040}
2041
2042#else /* ON_EXIT */
2043
2044/* Simple; we just need a wrapper for ON_EXIT.  */
2045int
2046atexit (func_ptr func)
2047{
2048  return ON_EXIT (func);
2049}
2050
2051#endif /* ON_EXIT */
2052#endif /* NEED_ATEXIT */
2053
2054#endif /* L_exit */
2055