libgcc2.c revision 146906
118334Speter/* More subroutines needed by GCC output code on some machines.  */
218334Speter/* Compile this one with gcc.  */
390280Sobrien/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4132727Skan   2000, 2001, 2002, 2003  Free Software Foundation, Inc.
518334Speter
690280SobrienThis file is part of GCC.
718334Speter
890280SobrienGCC is free software; you can redistribute it and/or modify it under
990280Sobrienthe terms of the GNU General Public License as published by the Free
1090280SobrienSoftware Foundation; either version 2, or (at your option) any later
1190280Sobrienversion.
1218334Speter
1390280SobrienIn addition to the permissions in the GNU General Public License, the
1490280SobrienFree Software Foundation gives you unlimited permission to link the
1590280Sobriencompiled version of this file into combinations with other programs,
1690280Sobrienand to distribute those combinations without any restriction coming
1790280Sobrienfrom the use of this file.  (The General Public License restrictions
1890280Sobriendo apply in other respects; for example, they cover modification of
1990280Sobrienthe file, and distribution when not linked into a combine
2090280Sobrienexecutable.)
2118334Speter
2290280SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
2390280SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
2490280SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2590280Sobrienfor more details.
2690280Sobrien
2718334SpeterYou should have received a copy of the GNU General Public License
2890280Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
2990280SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
3090280Sobrien02111-1307, USA.  */
3118334Speter
32132727Skan
33132727Skan/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
34132727Skan   supposedly valid even though this is a "target" file.  */
35132727Skan#include "auto-host.h"
36132727Skan
3718334Speter/* It is incorrect to include config.h here, because this file is being
3818334Speter   compiled for the target, and hence definitions concerning only the host
3918334Speter   do not apply.  */
4018334Speter#include "tconfig.h"
4190280Sobrien#include "tsystem.h"
42132727Skan#include "coretypes.h"
43132727Skan#include "tm.h"
4450600Sobrien
4518334Speter/* Don't use `fancy_abort' here even if config.h says to use it.  */
4618334Speter#ifdef abort
4718334Speter#undef abort
4818334Speter#endif
4918334Speter
50132727Skan#ifdef HAVE_GAS_HIDDEN
51132727Skan#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
52132727Skan#else
53132727Skan#define ATTRIBUTE_HIDDEN
54132727Skan#endif
55132727Skan
5690280Sobrien#include "libgcc2.h"
5790280Sobrien
58117404Skan#ifdef DECLARE_LIBRARY_RENAMES
59117404Skan  DECLARE_LIBRARY_RENAMES
6018334Speter#endif
61117404Skan
62117404Skan#if defined (L_negdi2)
6390280SobrienDWtype
6490280Sobrien__negdi2 (DWtype u)
6590280Sobrien{
66132727Skan  const DWunion uu = {.ll = u};
67132727Skan  const DWunion w = { {.low = -uu.s.low,
68132727Skan		       .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
6918334Speter
7090280Sobrien  return w.ll;
7190280Sobrien}
7250600Sobrien#endif
7350600Sobrien
7490280Sobrien#ifdef L_addvsi3
7590280SobrienWtype
76146906Skan__addvSI3 (Wtype a, Wtype b)
7790280Sobrien{
78132727Skan  const Wtype w = a + b;
7918334Speter
8090280Sobrien  if (b >= 0 ? w < a : w > a)
8190280Sobrien    abort ();
8290280Sobrien
8390280Sobrien  return w;
8490280Sobrien}
85146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
86146906SkanSItype
87146906Skan__addvsi3 (SItype a, SItype b)
88146906Skan{
89146906Skan  const SItype w = a + b;
90146906Skan
91146906Skan  if (b >= 0 ? w < a : w > a)
92146906Skan    abort ();
93146906Skan
94146906Skan  return w;
95146906Skan}
96146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
9718334Speter#endif
9890280Sobrien
9990280Sobrien#ifdef L_addvdi3
10090280SobrienDWtype
101146906Skan__addvDI3 (DWtype a, DWtype b)
10290280Sobrien{
103132727Skan  const DWtype w = a + b;
10418334Speter
10590280Sobrien  if (b >= 0 ? w < a : w > a)
10690280Sobrien    abort ();
10790280Sobrien
10890280Sobrien  return w;
10990280Sobrien}
11052561Sobrien#endif
11190280Sobrien
11290280Sobrien#ifdef L_subvsi3
11390280SobrienWtype
114146906Skan__subvSI3 (Wtype a, Wtype b)
11590280Sobrien{
116146906Skan  const Wtype w = a - b;
11752561Sobrien
11890280Sobrien  if (b >= 0 ? w > a : w < a)
11990280Sobrien    abort ();
12018334Speter
12190280Sobrien  return w;
12290280Sobrien}
123146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
124146906SkanSItype
125146906Skan__subvsi3 (SItype a, SItype b)
126146906Skan{
127146906Skan  const SItype w = a - b;
128146906Skan
129146906Skan  if (b >= 0 ? w > a : w < a)
130146906Skan    abort ();
131146906Skan
132146906Skan  return w;
133146906Skan}
134146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
13590280Sobrien#endif
13690280Sobrien
13790280Sobrien#ifdef L_subvdi3
13890280SobrienDWtype
139146906Skan__subvDI3 (DWtype a, DWtype b)
14090280Sobrien{
141132727Skan  const DWtype w = a - b;
14218334Speter
14390280Sobrien  if (b >= 0 ? w > a : w < a)
14490280Sobrien    abort ();
14590280Sobrien
14690280Sobrien  return w;
14790280Sobrien}
14818334Speter#endif
14990280Sobrien
15090280Sobrien#ifdef L_mulvsi3
151132727Skan#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
15290280SobrienWtype
153146906Skan__mulvSI3 (Wtype a, Wtype b)
15490280Sobrien{
155132727Skan  const DWtype w = (DWtype) a * (DWtype) b;
15618334Speter
157146906Skan  if ((Wtype) (w >> WORD_SIZE) != (Wtype) w >> (WORD_SIZE - 1))
15890280Sobrien    abort ();
15918334Speter
16090280Sobrien  return w;
16190280Sobrien}
162146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
163146906Skan#undef WORD_SIZE
164146906Skan#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
165146906SkanSItype
166146906Skan__mulvsi3 (SItype a, SItype b)
167146906Skan{
168146906Skan  const DItype w = (DItype) a * (DItype) b;
169146906Skan
170146906Skan  if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
171146906Skan    abort ();
172146906Skan
173146906Skan  return w;
174146906Skan}
175146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
17690280Sobrien#endif
17790280Sobrien
17890280Sobrien#ifdef L_negvsi2
17990280SobrienWtype
180146906Skan__negvSI2 (Wtype a)
18190280Sobrien{
182132727Skan  const Wtype w = -a;
18318334Speter
18490280Sobrien  if (a >= 0 ? w > 0 : w < 0)
18590280Sobrien    abort ();
18618334Speter
18790280Sobrien   return w;
18890280Sobrien}
189146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
190146906SkanSItype
191146906Skan__negvsi2 (SItype a)
192146906Skan{
193146906Skan  const SItype w = -a;
194146906Skan
195146906Skan  if (a >= 0 ? w > 0 : w < 0)
196146906Skan    abort ();
197146906Skan
198146906Skan   return w;
199146906Skan}
200146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
20118334Speter#endif
20290280Sobrien
20390280Sobrien#ifdef L_negvdi2
20490280SobrienDWtype
205146906Skan__negvDI2 (DWtype a)
20690280Sobrien{
207132727Skan  const DWtype w = -a;
20818334Speter
20990280Sobrien  if (a >= 0 ? w > 0 : w < 0)
21090280Sobrien    abort ();
21190280Sobrien
212117404Skan  return w;
21390280Sobrien}
21490280Sobrien#endif
21590280Sobrien
21690280Sobrien#ifdef L_absvsi2
21790280SobrienWtype
218146906Skan__absvSI2 (Wtype a)
21918334Speter{
220117404Skan  Wtype w = a;
22118334Speter
222117404Skan  if (a < 0)
22390280Sobrien#ifdef L_negvsi2
224146906Skan    w = __negvSI2 (a);
225146906Skan#else
226146906Skan    w = -a;
227146906Skan
228146906Skan  if (w < 0)
229146906Skan    abort ();
230146906Skan#endif
231146906Skan
232146906Skan   return w;
233146906Skan}
234146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
235146906SkanSItype
236146906Skan__absvsi2 (SItype a)
237146906Skan{
238146906Skan  SItype w = a;
239146906Skan
240146906Skan  if (a < 0)
241146906Skan#ifdef L_negvsi2
242117404Skan    w = __negvsi2 (a);
24390280Sobrien#else
244117404Skan    w = -a;
24518334Speter
246117404Skan  if (w < 0)
247117404Skan    abort ();
24890280Sobrien#endif
24918334Speter
25090280Sobrien   return w;
25190280Sobrien}
252146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
25390280Sobrien#endif
25490280Sobrien
25590280Sobrien#ifdef L_absvdi2
25690280SobrienDWtype
257146906Skan__absvDI2 (DWtype a)
25890280Sobrien{
259117404Skan  DWtype w = a;
26018334Speter
261117404Skan  if (a < 0)
262132727Skan#ifdef L_negvdi2
263146906Skan    w = __negvDI2 (a);
26490280Sobrien#else
265117404Skan    w = -a;
26690280Sobrien
267117404Skan  if (w < 0)
268117404Skan    abort ();
26918334Speter#endif
27090280Sobrien
271117404Skan  return w;
27290280Sobrien}
27318334Speter#endif
27418334Speter
27590280Sobrien#ifdef L_mulvdi3
276132727Skan#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
27790280SobrienDWtype
278146906Skan__mulvDI3 (DWtype u, DWtype v)
27918334Speter{
280132727Skan  /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
281132727Skan     but the checked multiplication needs only two.  */
282132727Skan  const DWunion uu = {.ll = u};
283132727Skan  const DWunion vv = {.ll = v};
28418334Speter
285132727Skan  if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1))
286132727Skan    {
287132727Skan      /* u fits in a single Wtype.  */
288132727Skan      if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
289132727Skan	{
290132727Skan	  /* v fits in a single Wtype as well.  */
291132727Skan	  /* A single multiplication.  No overflow risk.  */
292132727Skan	  return (DWtype) uu.s.low * (DWtype) vv.s.low;
293132727Skan	}
294132727Skan      else
295132727Skan	{
296132727Skan	  /* Two multiplications.  */
297132727Skan	  DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
298132727Skan			* (UDWtype) (UWtype) vv.s.low};
299132727Skan	  DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
300132727Skan			* (UDWtype) (UWtype) vv.s.high};
30118334Speter
302132727Skan	  if (vv.s.high < 0)
303132727Skan	    w1.s.high -= uu.s.low;
304132727Skan	  if (uu.s.low < 0)
305132727Skan	    w1.ll -= vv.ll;
306132727Skan	  w1.ll += (UWtype) w0.s.high;
307132727Skan	  if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
308132727Skan	    {
309132727Skan	      w0.s.high = w1.s.low;
310132727Skan	      return w0.ll;
311132727Skan	    }
312132727Skan	}
313132727Skan    }
314132727Skan  else
315132727Skan    {
316132727Skan      if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
317132727Skan	{
318132727Skan	  /* v fits into a single Wtype.  */
319132727Skan	  /* Two multiplications.  */
320132727Skan	  DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
321132727Skan			* (UDWtype) (UWtype) vv.s.low};
322132727Skan	  DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
323132727Skan			* (UDWtype) (UWtype) vv.s.low};
32418334Speter
325132727Skan	  if (uu.s.high < 0)
326132727Skan	    w1.s.high -= vv.s.low;
327132727Skan	  if (vv.s.low < 0)
328132727Skan	    w1.ll -= uu.ll;
329132727Skan	  w1.ll += (UWtype) w0.s.high;
330132727Skan	  if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
331132727Skan	    {
332132727Skan	      w0.s.high = w1.s.low;
333132727Skan	      return w0.ll;
334132727Skan	    }
335132727Skan	}
336132727Skan      else
337132727Skan	{
338132727Skan	  /* A few sign checks and a single multiplication.  */
339132727Skan	  if (uu.s.high >= 0)
340132727Skan	    {
341132727Skan	      if (vv.s.high >= 0)
342132727Skan		{
343132727Skan		  if (uu.s.high == 0 && vv.s.high == 0)
344132727Skan		    {
345132727Skan		      const DWtype w = (UDWtype) (UWtype) uu.s.low
346132727Skan			* (UDWtype) (UWtype) vv.s.low;
347132727Skan		      if (__builtin_expect (w >= 0, 1))
348132727Skan			return w;
349132727Skan		    }
350132727Skan		}
351132727Skan	      else
352132727Skan		{
353132727Skan		  if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
354132727Skan		    {
355132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
356132727Skan				    * (UDWtype) (UWtype) vv.s.low};
357132727Skan
358132727Skan		      ww.s.high -= uu.s.low;
359132727Skan		      if (__builtin_expect (ww.s.high < 0, 1))
360132727Skan			return ww.ll;
361132727Skan		    }
362132727Skan		}
363132727Skan	    }
364132727Skan	  else
365132727Skan	    {
366132727Skan	      if (vv.s.high >= 0)
367132727Skan		{
368132727Skan		  if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
369132727Skan		    {
370132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
371132727Skan				    * (UDWtype) (UWtype) vv.s.low};
372132727Skan
373132727Skan		      ww.s.high -= vv.s.low;
374132727Skan		      if (__builtin_expect (ww.s.high < 0, 1))
375132727Skan			return ww.ll;
376132727Skan		    }
377132727Skan		}
378132727Skan	      else
379132727Skan		{
380132727Skan		  if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
381132727Skan		    {
382132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
383132727Skan				    * (UDWtype) (UWtype) vv.s.low};
384132727Skan
385132727Skan		      ww.s.high -= uu.s.low;
386132727Skan		      ww.s.high -= vv.s.low;
387132727Skan		      if (__builtin_expect (ww.s.high >= 0, 1))
388132727Skan			return ww.ll;
389132727Skan		    }
390132727Skan		}
391132727Skan	    }
392132727Skan	}
393132727Skan    }
394132727Skan
395132727Skan  /* Overflow.  */
396132727Skan  abort ();
39718334Speter}
39818334Speter#endif
39918334Speter
40090280Sobrien
401132727Skan/* Unless shift functions are defined with full ANSI prototypes,
40250600Sobrien   parameter b will be promoted to int if word_type is smaller than an int.  */
40318334Speter#ifdef L_lshrdi3
40490280SobrienDWtype
40590280Sobrien__lshrdi3 (DWtype u, word_type b)
40618334Speter{
40718334Speter  if (b == 0)
40818334Speter    return u;
40918334Speter
410132727Skan  const DWunion uu = {.ll = u};
411132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
412132727Skan  DWunion w;
41318334Speter
41418334Speter  if (bm <= 0)
41518334Speter    {
41618334Speter      w.s.high = 0;
41790280Sobrien      w.s.low = (UWtype) uu.s.high >> -bm;
41818334Speter    }
41918334Speter  else
42018334Speter    {
421132727Skan      const UWtype carries = (UWtype) uu.s.high << bm;
42290280Sobrien
42390280Sobrien      w.s.high = (UWtype) uu.s.high >> b;
42490280Sobrien      w.s.low = ((UWtype) uu.s.low >> b) | carries;
42518334Speter    }
42618334Speter
42718334Speter  return w.ll;
42818334Speter}
42918334Speter#endif
43018334Speter
43118334Speter#ifdef L_ashldi3
43290280SobrienDWtype
43390280Sobrien__ashldi3 (DWtype u, word_type b)
43418334Speter{
43518334Speter  if (b == 0)
43618334Speter    return u;
43718334Speter
438132727Skan  const DWunion uu = {.ll = u};
439132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
440132727Skan  DWunion w;
44118334Speter
44218334Speter  if (bm <= 0)
44318334Speter    {
44418334Speter      w.s.low = 0;
44590280Sobrien      w.s.high = (UWtype) uu.s.low << -bm;
44618334Speter    }
44718334Speter  else
44818334Speter    {
449132727Skan      const UWtype carries = (UWtype) uu.s.low >> bm;
45090280Sobrien
45190280Sobrien      w.s.low = (UWtype) uu.s.low << b;
45290280Sobrien      w.s.high = ((UWtype) uu.s.high << b) | carries;
45318334Speter    }
45418334Speter
45518334Speter  return w.ll;
45618334Speter}
45718334Speter#endif
45818334Speter
45918334Speter#ifdef L_ashrdi3
46090280SobrienDWtype
46190280Sobrien__ashrdi3 (DWtype u, word_type b)
46218334Speter{
46318334Speter  if (b == 0)
46418334Speter    return u;
46518334Speter
466132727Skan  const DWunion uu = {.ll = u};
467132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
468132727Skan  DWunion w;
46918334Speter
47018334Speter  if (bm <= 0)
47118334Speter    {
47218334Speter      /* w.s.high = 1..1 or 0..0 */
47390280Sobrien      w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
47418334Speter      w.s.low = uu.s.high >> -bm;
47518334Speter    }
47618334Speter  else
47718334Speter    {
478132727Skan      const UWtype carries = (UWtype) uu.s.high << bm;
47990280Sobrien
48018334Speter      w.s.high = uu.s.high >> b;
48190280Sobrien      w.s.low = ((UWtype) uu.s.low >> b) | carries;
48218334Speter    }
48318334Speter
48418334Speter  return w.ll;
48518334Speter}
48618334Speter#endif
48718334Speter
488132727Skan#ifdef L_ffssi2
489132727Skan#undef int
490132727Skanextern int __ffsSI2 (UWtype u);
491132727Skanint
492132727Skan__ffsSI2 (UWtype u)
493132727Skan{
494132727Skan  UWtype count;
495132727Skan
496132727Skan  if (u == 0)
497132727Skan    return 0;
498132727Skan
499132727Skan  count_trailing_zeros (count, u);
500132727Skan  return count + 1;
501132727Skan}
502132727Skan#endif
503132727Skan
50418334Speter#ifdef L_ffsdi2
505132727Skan#undef int
506132727Skanextern int __ffsDI2 (DWtype u);
507132727Skanint
508132727Skan__ffsDI2 (DWtype u)
50918334Speter{
510132727Skan  const DWunion uu = {.ll = u};
51190280Sobrien  UWtype word, count, add;
51290280Sobrien
51390280Sobrien  if (uu.s.low != 0)
51490280Sobrien    word = uu.s.low, add = 0;
51590280Sobrien  else if (uu.s.high != 0)
51690280Sobrien    word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
51790280Sobrien  else
51890280Sobrien    return 0;
51990280Sobrien
52090280Sobrien  count_trailing_zeros (count, word);
52190280Sobrien  return count + add + 1;
52218334Speter}
52318334Speter#endif
52418334Speter
52518334Speter#ifdef L_muldi3
52690280SobrienDWtype
52790280Sobrien__muldi3 (DWtype u, DWtype v)
52818334Speter{
529132727Skan  const DWunion uu = {.ll = u};
530132727Skan  const DWunion vv = {.ll = v};
531132727Skan  DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
53218334Speter
53390280Sobrien  w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
53490280Sobrien	       + (UWtype) uu.s.high * (UWtype) vv.s.low);
53518334Speter
53618334Speter  return w.ll;
53718334Speter}
53818334Speter#endif
53918334Speter
540117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
541117404Skan     defined (L_umoddi3) || defined (L_moddi3))
542117404Skan#if defined (sdiv_qrnnd)
543117404Skan#define L_udiv_w_sdiv
544117404Skan#endif
545117404Skan#endif
546117404Skan
54718334Speter#ifdef L_udiv_w_sdiv
54818334Speter#if defined (sdiv_qrnnd)
549117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
550117404Skan     defined (L_umoddi3) || defined (L_moddi3))
551117404Skanstatic inline __attribute__ ((__always_inline__))
552117404Skan#endif
55390280SobrienUWtype
55490280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
55518334Speter{
55690280Sobrien  UWtype q, r;
55790280Sobrien  UWtype c0, c1, b1;
55818334Speter
55990280Sobrien  if ((Wtype) d >= 0)
56018334Speter    {
56190280Sobrien      if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
56218334Speter	{
56318334Speter	  /* dividend, divisor, and quotient are nonnegative */
56418334Speter	  sdiv_qrnnd (q, r, a1, a0, d);
56518334Speter	}
56618334Speter      else
56718334Speter	{
56818334Speter	  /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
56990280Sobrien	  sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
57018334Speter	  /* Divide (c1*2^32 + c0) by d */
57118334Speter	  sdiv_qrnnd (q, r, c1, c0, d);
57218334Speter	  /* Add 2^31 to quotient */
57390280Sobrien	  q += (UWtype) 1 << (W_TYPE_SIZE - 1);
57418334Speter	}
57518334Speter    }
57618334Speter  else
57718334Speter    {
57818334Speter      b1 = d >> 1;			/* d/2, between 2^30 and 2^31 - 1 */
57918334Speter      c1 = a1 >> 1;			/* A/2 */
58090280Sobrien      c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
58118334Speter
58218334Speter      if (a1 < b1)			/* A < 2^32*b1, so A/2 < 2^31*b1 */
58318334Speter	{
58418334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
58518334Speter
58618334Speter	  r = 2*r + (a0 & 1);		/* Remainder from A/(2*b1) */
58718334Speter	  if ((d & 1) != 0)
58818334Speter	    {
58918334Speter	      if (r >= q)
59018334Speter		r = r - q;
59118334Speter	      else if (q - r <= d)
59218334Speter		{
59318334Speter		  r = r - q + d;
59418334Speter		  q--;
59518334Speter		}
59618334Speter	      else
59718334Speter		{
59818334Speter		  r = r - q + 2*d;
59918334Speter		  q -= 2;
60018334Speter		}
60118334Speter	    }
60218334Speter	}
60318334Speter      else if (c1 < b1)			/* So 2^31 <= (A/2)/b1 < 2^32 */
60418334Speter	{
60518334Speter	  c1 = (b1 - 1) - c1;
60618334Speter	  c0 = ~c0;			/* logical NOT */
60718334Speter
60818334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
60918334Speter
61018334Speter	  q = ~q;			/* (A/2)/b1 */
61118334Speter	  r = (b1 - 1) - r;
61218334Speter
61318334Speter	  r = 2*r + (a0 & 1);		/* A/(2*b1) */
61418334Speter
61518334Speter	  if ((d & 1) != 0)
61618334Speter	    {
61718334Speter	      if (r >= q)
61818334Speter		r = r - q;
61918334Speter	      else if (q - r <= d)
62018334Speter		{
62118334Speter		  r = r - q + d;
62218334Speter		  q--;
62318334Speter		}
62418334Speter	      else
62518334Speter		{
62618334Speter		  r = r - q + 2*d;
62718334Speter		  q -= 2;
62818334Speter		}
62918334Speter	    }
63018334Speter	}
63118334Speter      else				/* Implies c1 = b1 */
63218334Speter	{				/* Hence a1 = d - 1 = 2*b1 - 1 */
63318334Speter	  if (a0 >= -d)
63418334Speter	    {
63518334Speter	      q = -1;
63618334Speter	      r = a0 + d;
63718334Speter	    }
63818334Speter	  else
63918334Speter	    {
64018334Speter	      q = -2;
64118334Speter	      r = a0 + 2*d;
64218334Speter	    }
64318334Speter	}
64418334Speter    }
64518334Speter
64618334Speter  *rp = r;
64718334Speter  return q;
64818334Speter}
64918334Speter#else
65018334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
65190280SobrienUWtype
65290280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
65390280Sobrien	       UWtype a1 __attribute__ ((__unused__)),
65490280Sobrien	       UWtype a0 __attribute__ ((__unused__)),
65590280Sobrien	       UWtype d __attribute__ ((__unused__)))
65650600Sobrien{
65750600Sobrien  return 0;
65850600Sobrien}
65918334Speter#endif
66018334Speter#endif
66118334Speter
66218334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
66318334Speter     defined (L_umoddi3) || defined (L_moddi3))
66418334Speter#define L_udivmoddi4
66518334Speter#endif
66618334Speter
66790280Sobrien#ifdef L_clz
66890280Sobrienconst UQItype __clz_tab[] =
66918334Speter{
67018334Speter  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,
67118334Speter  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,
67218334Speter  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,
67318334Speter  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,
67418334Speter  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,
67518334Speter  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,
67618334Speter  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,
67718334Speter  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,
67818334Speter};
67990280Sobrien#endif
680132727Skan
681132727Skan#ifdef L_clzsi2
682132727Skan#undef int
683132727Skanextern int __clzSI2 (UWtype x);
684132727Skanint
685132727Skan__clzSI2 (UWtype x)
686132727Skan{
687132727Skan  Wtype ret;
68818334Speter
689132727Skan  count_leading_zeros (ret, x);
690132727Skan
691132727Skan  return ret;
692132727Skan}
693132727Skan#endif
694132727Skan
695132727Skan#ifdef L_clzdi2
696132727Skan#undef int
697132727Skanextern int __clzDI2 (UDWtype x);
698132727Skanint
699132727Skan__clzDI2 (UDWtype x)
700132727Skan{
701132727Skan  const DWunion uu = {.ll = x};
702132727Skan  UWtype word;
703132727Skan  Wtype ret, add;
704132727Skan
705132727Skan  if (uu.s.high)
706132727Skan    word = uu.s.high, add = 0;
707132727Skan  else
708132727Skan    word = uu.s.low, add = W_TYPE_SIZE;
709132727Skan
710132727Skan  count_leading_zeros (ret, word);
711132727Skan  return ret + add;
712132727Skan}
713132727Skan#endif
714132727Skan
715132727Skan#ifdef L_ctzsi2
716132727Skan#undef int
717132727Skanextern int __ctzSI2 (UWtype x);
718132727Skanint
719132727Skan__ctzSI2 (UWtype x)
720132727Skan{
721132727Skan  Wtype ret;
722132727Skan
723132727Skan  count_trailing_zeros (ret, x);
724132727Skan
725132727Skan  return ret;
726132727Skan}
727132727Skan#endif
728132727Skan
729132727Skan#ifdef L_ctzdi2
730132727Skan#undef int
731132727Skanextern int __ctzDI2 (UDWtype x);
732132727Skanint
733132727Skan__ctzDI2 (UDWtype x)
734132727Skan{
735132727Skan  const DWunion uu = {.ll = x};
736132727Skan  UWtype word;
737132727Skan  Wtype ret, add;
738132727Skan
739132727Skan  if (uu.s.low)
740132727Skan    word = uu.s.low, add = 0;
741132727Skan  else
742132727Skan    word = uu.s.high, add = W_TYPE_SIZE;
743132727Skan
744132727Skan  count_trailing_zeros (ret, word);
745132727Skan  return ret + add;
746132727Skan}
747132727Skan#endif
748132727Skan
749132727Skan#if (defined (L_popcountsi2) || defined (L_popcountdi2)	\
750132727Skan     || defined (L_popcount_tab))
751132727Skanextern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
752132727Skan#endif
753132727Skan
754132727Skan#ifdef L_popcount_tab
755132727Skanconst UQItype __popcount_tab[] =
756132727Skan{
757132727Skan    0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
758132727Skan    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
759132727Skan    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
760132727Skan    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
761132727Skan    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
762132727Skan    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
763132727Skan    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
764132727Skan    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
765132727Skan};
766132727Skan#endif
767132727Skan
768132727Skan#ifdef L_popcountsi2
769132727Skan#undef int
770132727Skanextern int __popcountSI2 (UWtype x);
771132727Skanint
772132727Skan__popcountSI2 (UWtype x)
773132727Skan{
774132727Skan  UWtype i, ret = 0;
775132727Skan
776132727Skan  for (i = 0; i < W_TYPE_SIZE; i += 8)
777132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
778132727Skan
779132727Skan  return ret;
780132727Skan}
781132727Skan#endif
782132727Skan
783132727Skan#ifdef L_popcountdi2
784132727Skan#undef int
785132727Skanextern int __popcountDI2 (UDWtype x);
786132727Skanint
787132727Skan__popcountDI2 (UDWtype x)
788132727Skan{
789132727Skan  UWtype i, ret = 0;
790132727Skan
791132727Skan  for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
792132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
793132727Skan
794132727Skan  return ret;
795132727Skan}
796132727Skan#endif
797132727Skan
798132727Skan#ifdef L_paritysi2
799132727Skan#undef int
800132727Skanextern int __paritySI2 (UWtype x);
801132727Skanint
802132727Skan__paritySI2 (UWtype x)
803132727Skan{
804132727Skan#if W_TYPE_SIZE > 64
805132727Skan# error "fill out the table"
806132727Skan#endif
807132727Skan#if W_TYPE_SIZE > 32
808132727Skan  x ^= x >> 32;
809132727Skan#endif
810132727Skan#if W_TYPE_SIZE > 16
811132727Skan  x ^= x >> 16;
812132727Skan#endif
813132727Skan  x ^= x >> 8;
814132727Skan  x ^= x >> 4;
815132727Skan  x &= 0xf;
816132727Skan  return (0x6996 >> x) & 1;
817132727Skan}
818132727Skan#endif
819132727Skan
820132727Skan#ifdef L_paritydi2
821132727Skan#undef int
822132727Skanextern int __parityDI2 (UDWtype x);
823132727Skanint
824132727Skan__parityDI2 (UDWtype x)
825132727Skan{
826132727Skan  const DWunion uu = {.ll = x};
827132727Skan  UWtype nx = uu.s.low ^ uu.s.high;
828132727Skan
829132727Skan#if W_TYPE_SIZE > 64
830132727Skan# error "fill out the table"
831132727Skan#endif
832132727Skan#if W_TYPE_SIZE > 32
833132727Skan  nx ^= nx >> 32;
834132727Skan#endif
835132727Skan#if W_TYPE_SIZE > 16
836132727Skan  nx ^= nx >> 16;
837132727Skan#endif
838132727Skan  nx ^= nx >> 8;
839132727Skan  nx ^= nx >> 4;
840132727Skan  nx &= 0xf;
841132727Skan  return (0x6996 >> nx) & 1;
842132727Skan}
843132727Skan#endif
844132727Skan
84590280Sobrien#ifdef L_udivmoddi4
84690280Sobrien
84718334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
84818334Speter     defined (L_umoddi3) || defined (L_moddi3))
849117404Skanstatic inline __attribute__ ((__always_inline__))
85018334Speter#endif
85190280SobrienUDWtype
85290280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
85318334Speter{
854132727Skan  const DWunion nn = {.ll = n};
855132727Skan  const DWunion dd = {.ll = d};
85690280Sobrien  DWunion rr;
85790280Sobrien  UWtype d0, d1, n0, n1, n2;
85890280Sobrien  UWtype q0, q1;
85990280Sobrien  UWtype b, bm;
86018334Speter
86118334Speter  d0 = dd.s.low;
86218334Speter  d1 = dd.s.high;
86318334Speter  n0 = nn.s.low;
86418334Speter  n1 = nn.s.high;
86518334Speter
86618334Speter#if !UDIV_NEEDS_NORMALIZATION
86718334Speter  if (d1 == 0)
86818334Speter    {
86918334Speter      if (d0 > n1)
87018334Speter	{
87118334Speter	  /* 0q = nn / 0D */
87218334Speter
87318334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
87418334Speter	  q1 = 0;
87518334Speter
87618334Speter	  /* Remainder in n0.  */
87718334Speter	}
87818334Speter      else
87918334Speter	{
88018334Speter	  /* qq = NN / 0d */
88118334Speter
88218334Speter	  if (d0 == 0)
88318334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
88418334Speter
88518334Speter	  udiv_qrnnd (q1, n1, 0, n1, d0);
88618334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
88718334Speter
88818334Speter	  /* Remainder in n0.  */
88918334Speter	}
89018334Speter
89118334Speter      if (rp != 0)
89218334Speter	{
89318334Speter	  rr.s.low = n0;
89418334Speter	  rr.s.high = 0;
89518334Speter	  *rp = rr.ll;
89618334Speter	}
89718334Speter    }
89818334Speter
89918334Speter#else /* UDIV_NEEDS_NORMALIZATION */
90018334Speter
90118334Speter  if (d1 == 0)
90218334Speter    {
90318334Speter      if (d0 > n1)
90418334Speter	{
90518334Speter	  /* 0q = nn / 0D */
90618334Speter
90718334Speter	  count_leading_zeros (bm, d0);
90818334Speter
90918334Speter	  if (bm != 0)
91018334Speter	    {
91118334Speter	      /* Normalize, i.e. make the most significant bit of the
91218334Speter		 denominator set.  */
91318334Speter
91418334Speter	      d0 = d0 << bm;
91590280Sobrien	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
91618334Speter	      n0 = n0 << bm;
91718334Speter	    }
91818334Speter
91918334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
92018334Speter	  q1 = 0;
92118334Speter
92218334Speter	  /* Remainder in n0 >> bm.  */
92318334Speter	}
92418334Speter      else
92518334Speter	{
92618334Speter	  /* qq = NN / 0d */
92718334Speter
92818334Speter	  if (d0 == 0)
92918334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
93018334Speter
93118334Speter	  count_leading_zeros (bm, d0);
93218334Speter
93318334Speter	  if (bm == 0)
93418334Speter	    {
93518334Speter	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
93618334Speter		 conclude (the most significant bit of n1 is set) /\ (the
93718334Speter		 leading quotient digit q1 = 1).
93818334Speter
93918334Speter		 This special case is necessary, not an optimization.
94090280Sobrien		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
94118334Speter
94218334Speter	      n1 -= d0;
94318334Speter	      q1 = 1;
94418334Speter	    }
94518334Speter	  else
94618334Speter	    {
94718334Speter	      /* Normalize.  */
94818334Speter
94990280Sobrien	      b = W_TYPE_SIZE - bm;
95018334Speter
95118334Speter	      d0 = d0 << bm;
95218334Speter	      n2 = n1 >> b;
95318334Speter	      n1 = (n1 << bm) | (n0 >> b);
95418334Speter	      n0 = n0 << bm;
95518334Speter
95618334Speter	      udiv_qrnnd (q1, n1, n2, n1, d0);
95718334Speter	    }
95818334Speter
95950600Sobrien	  /* n1 != d0...  */
96018334Speter
96118334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
96218334Speter
96318334Speter	  /* Remainder in n0 >> bm.  */
96418334Speter	}
96518334Speter
96618334Speter      if (rp != 0)
96718334Speter	{
96818334Speter	  rr.s.low = n0 >> bm;
96918334Speter	  rr.s.high = 0;
97018334Speter	  *rp = rr.ll;
97118334Speter	}
97218334Speter    }
97318334Speter#endif /* UDIV_NEEDS_NORMALIZATION */
97418334Speter
97518334Speter  else
97618334Speter    {
97718334Speter      if (d1 > n1)
97818334Speter	{
97918334Speter	  /* 00 = nn / DD */
98018334Speter
98118334Speter	  q0 = 0;
98218334Speter	  q1 = 0;
98318334Speter
98418334Speter	  /* Remainder in n1n0.  */
98518334Speter	  if (rp != 0)
98618334Speter	    {
98718334Speter	      rr.s.low = n0;
98818334Speter	      rr.s.high = n1;
98918334Speter	      *rp = rr.ll;
99018334Speter	    }
99118334Speter	}
99218334Speter      else
99318334Speter	{
99418334Speter	  /* 0q = NN / dd */
99518334Speter
99618334Speter	  count_leading_zeros (bm, d1);
99718334Speter	  if (bm == 0)
99818334Speter	    {
99918334Speter	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
100018334Speter		 conclude (the most significant bit of n1 is set) /\ (the
100118334Speter		 quotient digit q0 = 0 or 1).
100218334Speter
100318334Speter		 This special case is necessary, not an optimization.  */
100418334Speter
100518334Speter	      /* The condition on the next line takes advantage of that
100618334Speter		 n1 >= d1 (true due to program flow).  */
100718334Speter	      if (n1 > d1 || n0 >= d0)
100818334Speter		{
100918334Speter		  q0 = 1;
101018334Speter		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
101118334Speter		}
101218334Speter	      else
101318334Speter		q0 = 0;
101418334Speter
101518334Speter	      q1 = 0;
101618334Speter
101718334Speter	      if (rp != 0)
101818334Speter		{
101918334Speter		  rr.s.low = n0;
102018334Speter		  rr.s.high = n1;
102118334Speter		  *rp = rr.ll;
102218334Speter		}
102318334Speter	    }
102418334Speter	  else
102518334Speter	    {
102690280Sobrien	      UWtype m1, m0;
102718334Speter	      /* Normalize.  */
102818334Speter
102990280Sobrien	      b = W_TYPE_SIZE - bm;
103018334Speter
103118334Speter	      d1 = (d1 << bm) | (d0 >> b);
103218334Speter	      d0 = d0 << bm;
103318334Speter	      n2 = n1 >> b;
103418334Speter	      n1 = (n1 << bm) | (n0 >> b);
103518334Speter	      n0 = n0 << bm;
103618334Speter
103718334Speter	      udiv_qrnnd (q0, n1, n2, n1, d1);
103818334Speter	      umul_ppmm (m1, m0, q0, d0);
103918334Speter
104018334Speter	      if (m1 > n1 || (m1 == n1 && m0 > n0))
104118334Speter		{
104218334Speter		  q0--;
104318334Speter		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
104418334Speter		}
104518334Speter
104618334Speter	      q1 = 0;
104718334Speter
104818334Speter	      /* Remainder in (n1n0 - m1m0) >> bm.  */
104918334Speter	      if (rp != 0)
105018334Speter		{
105118334Speter		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
105218334Speter		  rr.s.low = (n1 << b) | (n0 >> bm);
105318334Speter		  rr.s.high = n1 >> bm;
105418334Speter		  *rp = rr.ll;
105518334Speter		}
105618334Speter	    }
105718334Speter	}
105818334Speter    }
105918334Speter
1060132727Skan  const DWunion ww = {{.low = q0, .high = q1}};
106118334Speter  return ww.ll;
106218334Speter}
106318334Speter#endif
106418334Speter
106518334Speter#ifdef L_divdi3
106690280SobrienDWtype
106790280Sobrien__divdi3 (DWtype u, DWtype v)
106818334Speter{
106918334Speter  word_type c = 0;
1070132727Skan  DWunion uu = {.ll = u};
1071132727Skan  DWunion vv = {.ll = v};
107290280Sobrien  DWtype w;
107318334Speter
107418334Speter  if (uu.s.high < 0)
107518334Speter    c = ~c,
1076117404Skan    uu.ll = -uu.ll;
107718334Speter  if (vv.s.high < 0)
107818334Speter    c = ~c,
1079117404Skan    vv.ll = -vv.ll;
108018334Speter
108190280Sobrien  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
108218334Speter  if (c)
1083117404Skan    w = -w;
108418334Speter
108518334Speter  return w;
108618334Speter}
108718334Speter#endif
108818334Speter
108918334Speter#ifdef L_moddi3
109090280SobrienDWtype
109190280Sobrien__moddi3 (DWtype u, DWtype v)
109218334Speter{
109318334Speter  word_type c = 0;
1094132727Skan  DWunion uu = {.ll = u};
1095132727Skan  DWunion vv = {.ll = v};
109690280Sobrien  DWtype w;
109718334Speter
109818334Speter  if (uu.s.high < 0)
109918334Speter    c = ~c,
1100117404Skan    uu.ll = -uu.ll;
110118334Speter  if (vv.s.high < 0)
1102117404Skan    vv.ll = -vv.ll;
110318334Speter
110418334Speter  (void) __udivmoddi4 (uu.ll, vv.ll, &w);
110518334Speter  if (c)
1106117404Skan    w = -w;
110718334Speter
110818334Speter  return w;
110918334Speter}
111018334Speter#endif
111118334Speter
111218334Speter#ifdef L_umoddi3
111390280SobrienUDWtype
111490280Sobrien__umoddi3 (UDWtype u, UDWtype v)
111518334Speter{
111690280Sobrien  UDWtype w;
111718334Speter
111818334Speter  (void) __udivmoddi4 (u, v, &w);
111918334Speter
112018334Speter  return w;
112118334Speter}
112218334Speter#endif
112318334Speter
112418334Speter#ifdef L_udivdi3
112590280SobrienUDWtype
112690280Sobrien__udivdi3 (UDWtype n, UDWtype d)
112718334Speter{
112890280Sobrien  return __udivmoddi4 (n, d, (UDWtype *) 0);
112918334Speter}
113018334Speter#endif
113118334Speter
113218334Speter#ifdef L_cmpdi2
113318334Speterword_type
113490280Sobrien__cmpdi2 (DWtype a, DWtype b)
113518334Speter{
1136132727Skan  const DWunion au = {.ll = a};
1137132727Skan  const DWunion bu = {.ll = b};
113818334Speter
113918334Speter  if (au.s.high < bu.s.high)
114018334Speter    return 0;
114118334Speter  else if (au.s.high > bu.s.high)
114218334Speter    return 2;
114390280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
114418334Speter    return 0;
114590280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
114618334Speter    return 2;
114718334Speter  return 1;
114818334Speter}
114918334Speter#endif
115018334Speter
115118334Speter#ifdef L_ucmpdi2
115218334Speterword_type
115390280Sobrien__ucmpdi2 (DWtype a, DWtype b)
115418334Speter{
1155132727Skan  const DWunion au = {.ll = a};
1156132727Skan  const DWunion bu = {.ll = b};
115718334Speter
115890280Sobrien  if ((UWtype) au.s.high < (UWtype) bu.s.high)
115918334Speter    return 0;
116090280Sobrien  else if ((UWtype) au.s.high > (UWtype) bu.s.high)
116118334Speter    return 2;
116290280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
116318334Speter    return 0;
116490280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
116518334Speter    return 2;
116618334Speter  return 1;
116718334Speter}
116818334Speter#endif
116918334Speter
117052561Sobrien#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
117190280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
117290280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
117318334Speter
117490280SobrienDWtype
117590280Sobrien__fixunstfDI (TFtype a)
117618334Speter{
117718334Speter  if (a < 0)
117818334Speter    return 0;
117918334Speter
118018334Speter  /* Compute high word of result, as a flonum.  */
1181132727Skan  const TFtype b = (a / HIGH_WORD_COEFF);
118290280Sobrien  /* Convert that to fixed (but not to DWtype!),
118318334Speter     and shift it into the high word.  */
1184132727Skan  UDWtype v = (UWtype) b;
118518334Speter  v <<= WORD_SIZE;
118618334Speter  /* Remove high part from the TFtype, leaving the low part as flonum.  */
118718334Speter  a -= (TFtype)v;
118890280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
118918334Speter     Sometimes A comes out negative.  This is significant, since
119018334Speter     A has more bits than a long int does.  */
119118334Speter  if (a < 0)
119290280Sobrien    v -= (UWtype) (- a);
119318334Speter  else
119490280Sobrien    v += (UWtype) a;
119518334Speter  return v;
119618334Speter}
119718334Speter#endif
119818334Speter
119952561Sobrien#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
120090280SobrienDWtype
120150600Sobrien__fixtfdi (TFtype a)
120218334Speter{
120318334Speter  if (a < 0)
120490280Sobrien    return - __fixunstfDI (-a);
120590280Sobrien  return __fixunstfDI (a);
120618334Speter}
120718334Speter#endif
120818334Speter
120952561Sobrien#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
121090280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
121190280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
121218334Speter
121390280SobrienDWtype
121490280Sobrien__fixunsxfDI (XFtype a)
121518334Speter{
121618334Speter  if (a < 0)
121718334Speter    return 0;
121818334Speter
121918334Speter  /* Compute high word of result, as a flonum.  */
1220132727Skan  const XFtype b = (a / HIGH_WORD_COEFF);
122190280Sobrien  /* Convert that to fixed (but not to DWtype!),
122218334Speter     and shift it into the high word.  */
1223132727Skan  UDWtype v = (UWtype) b;
122418334Speter  v <<= WORD_SIZE;
122518334Speter  /* Remove high part from the XFtype, leaving the low part as flonum.  */
122618334Speter  a -= (XFtype)v;
122790280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
122818334Speter     Sometimes A comes out negative.  This is significant, since
122918334Speter     A has more bits than a long int does.  */
123018334Speter  if (a < 0)
123190280Sobrien    v -= (UWtype) (- a);
123218334Speter  else
123390280Sobrien    v += (UWtype) a;
123418334Speter  return v;
123518334Speter}
123618334Speter#endif
123718334Speter
123852561Sobrien#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
123990280SobrienDWtype
124050600Sobrien__fixxfdi (XFtype a)
124118334Speter{
124218334Speter  if (a < 0)
124390280Sobrien    return - __fixunsxfDI (-a);
124490280Sobrien  return __fixunsxfDI (a);
124518334Speter}
124618334Speter#endif
124718334Speter
124818334Speter#ifdef L_fixunsdfdi
124990280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
125090280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
125118334Speter
125290280SobrienDWtype
125390280Sobrien__fixunsdfDI (DFtype a)
125418334Speter{
1255132727Skan  /* Get high part of result.  The division here will just moves the radix
1256132727Skan     point and will not cause any rounding.  Then the conversion to integral
1257132727Skan     type chops result as desired.  */
1258132727Skan  const UWtype hi = a / HIGH_WORD_COEFF;
125918334Speter
1260132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1261132727Skan     then subtract this from the number being converted.  This leaves the low
1262132727Skan     part.  Convert that to integral type.  */
1263132727Skan  const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
126418334Speter
1265132727Skan  /* Assemble result from the two parts.  */
1266132727Skan  return ((UDWtype) hi << WORD_SIZE) | lo;
126718334Speter}
126818334Speter#endif
126918334Speter
127018334Speter#ifdef L_fixdfdi
127190280SobrienDWtype
127250600Sobrien__fixdfdi (DFtype a)
127318334Speter{
127418334Speter  if (a < 0)
127590280Sobrien    return - __fixunsdfDI (-a);
127690280Sobrien  return __fixunsdfDI (a);
127718334Speter}
127818334Speter#endif
127918334Speter
128018334Speter#ifdef L_fixunssfdi
128190280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
128290280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
128318334Speter
128490280SobrienDWtype
128590280Sobrien__fixunssfDI (SFtype original_a)
128618334Speter{
128718334Speter  /* Convert the SFtype to a DFtype, because that is surely not going
128818334Speter     to lose any bits.  Some day someone else can write a faster version
128918334Speter     that avoids converting to DFtype, and verify it really works right.  */
1290132727Skan  const DFtype a = original_a;
129118334Speter
1292132727Skan  /* Get high part of result.  The division here will just moves the radix
1293132727Skan     point and will not cause any rounding.  Then the conversion to integral
1294132727Skan     type chops result as desired.  */
1295132727Skan  const UWtype hi = a / HIGH_WORD_COEFF;
129618334Speter
1297132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1298132727Skan     then subtract this from the number being converted.  This leaves the low
1299132727Skan     part.  Convert that to integral type.  */
1300132727Skan  const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1301132727Skan
1302132727Skan  /* Assemble result from the two parts.  */
1303132727Skan  return ((UDWtype) hi << WORD_SIZE) | lo;
130418334Speter}
130518334Speter#endif
130618334Speter
130718334Speter#ifdef L_fixsfdi
130890280SobrienDWtype
130918334Speter__fixsfdi (SFtype a)
131018334Speter{
131118334Speter  if (a < 0)
131290280Sobrien    return - __fixunssfDI (-a);
131390280Sobrien  return __fixunssfDI (a);
131418334Speter}
131518334Speter#endif
131618334Speter
131752561Sobrien#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
131890280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
131990280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
132090280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
132118334Speter
132218334SpeterXFtype
132390280Sobrien__floatdixf (DWtype u)
132418334Speter{
1325132727Skan  XFtype d = (Wtype) (u >> WORD_SIZE);
132618334Speter  d *= HIGH_HALFWORD_COEFF;
132718334Speter  d *= HIGH_HALFWORD_COEFF;
132890280Sobrien  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
132918334Speter
133050600Sobrien  return d;
133118334Speter}
133218334Speter#endif
133318334Speter
133452561Sobrien#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
133590280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
133690280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
133790280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
133818334Speter
133918334SpeterTFtype
134090280Sobrien__floatditf (DWtype u)
134118334Speter{
1342132727Skan  TFtype d = (Wtype) (u >> WORD_SIZE);
134318334Speter  d *= HIGH_HALFWORD_COEFF;
134418334Speter  d *= HIGH_HALFWORD_COEFF;
134590280Sobrien  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
134618334Speter
134750600Sobrien  return d;
134818334Speter}
134918334Speter#endif
135018334Speter
135118334Speter#ifdef L_floatdidf
135290280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
135390280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
135490280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
135518334Speter
135618334SpeterDFtype
135790280Sobrien__floatdidf (DWtype u)
135818334Speter{
1359132727Skan  DFtype d = (Wtype) (u >> WORD_SIZE);
136018334Speter  d *= HIGH_HALFWORD_COEFF;
136118334Speter  d *= HIGH_HALFWORD_COEFF;
136290280Sobrien  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
136318334Speter
136450600Sobrien  return d;
136518334Speter}
136618334Speter#endif
136718334Speter
136818334Speter#ifdef L_floatdisf
136990280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
137090280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
137190280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1372117404Skan
137390280Sobrien#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1374117404Skan#define DF_SIZE DBL_MANT_DIG
1375117404Skan#define SF_SIZE FLT_MANT_DIG
137618334Speter
137718334SpeterSFtype
137890280Sobrien__floatdisf (DWtype u)
137918334Speter{
138018334Speter  /* Protect against double-rounding error.
138118334Speter     Represent any low-order bits, that might be truncated in DFmode,
138218334Speter     by a bit that won't be lost.  The bit can go in anywhere below the
138318334Speter     rounding position of the SFmode.  A fixed mask and bit position
138418334Speter     handles all usual configurations.  It doesn't handle the case
138518334Speter     of 128-bit DImode, however.  */
138618334Speter  if (DF_SIZE < DI_SIZE
138718334Speter      && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
138818334Speter    {
138990280Sobrien#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
139090280Sobrien      if (! (- ((DWtype) 1 << DF_SIZE) < u
139190280Sobrien	     && u < ((DWtype) 1 << DF_SIZE)))
139218334Speter	{
139390280Sobrien	  if ((UDWtype) u & (REP_BIT - 1))
1394104764Skan	    {
1395104764Skan	      u &= ~ (REP_BIT - 1);
1396104764Skan	      u |= REP_BIT;
1397104764Skan	    }
139818334Speter	}
139918334Speter    }
1400132727Skan  /* Do the calculation in DFmode
1401132727Skan     so that we don't lose any of the precision of the high word
1402132727Skan     while multiplying it.  */
1403132727Skan  DFtype f = (Wtype) (u >> WORD_SIZE);
140418334Speter  f *= HIGH_HALFWORD_COEFF;
140518334Speter  f *= HIGH_HALFWORD_COEFF;
140690280Sobrien  f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
140718334Speter
140850600Sobrien  return (SFtype) f;
140918334Speter}
141018334Speter#endif
141118334Speter
141252561Sobrien#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
141318334Speter/* Reenable the normal types, in case limits.h needs them.  */
141418334Speter#undef char
141518334Speter#undef short
141618334Speter#undef int
141718334Speter#undef long
141818334Speter#undef unsigned
141918334Speter#undef float
142018334Speter#undef double
142118334Speter#undef MIN
142218334Speter#undef MAX
142318334Speter#include <limits.h>
142418334Speter
142590280SobrienUWtype
142690280Sobrien__fixunsxfSI (XFtype a)
142718334Speter{
142890280Sobrien  if (a >= - (DFtype) Wtype_MIN)
142990280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
143090280Sobrien  return (Wtype) a;
143118334Speter}
143218334Speter#endif
143318334Speter
143418334Speter#ifdef L_fixunsdfsi
143518334Speter/* Reenable the normal types, in case limits.h needs them.  */
143618334Speter#undef char
143718334Speter#undef short
143818334Speter#undef int
143918334Speter#undef long
144018334Speter#undef unsigned
144118334Speter#undef float
144218334Speter#undef double
144318334Speter#undef MIN
144418334Speter#undef MAX
144518334Speter#include <limits.h>
144618334Speter
144790280SobrienUWtype
144890280Sobrien__fixunsdfSI (DFtype a)
144918334Speter{
145090280Sobrien  if (a >= - (DFtype) Wtype_MIN)
145190280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
145290280Sobrien  return (Wtype) a;
145318334Speter}
145418334Speter#endif
145518334Speter
145618334Speter#ifdef L_fixunssfsi
145718334Speter/* Reenable the normal types, in case limits.h needs them.  */
145818334Speter#undef char
145918334Speter#undef short
146018334Speter#undef int
146118334Speter#undef long
146218334Speter#undef unsigned
146318334Speter#undef float
146418334Speter#undef double
146518334Speter#undef MIN
146618334Speter#undef MAX
146718334Speter#include <limits.h>
146818334Speter
146990280SobrienUWtype
147090280Sobrien__fixunssfSI (SFtype a)
147118334Speter{
147290280Sobrien  if (a >= - (SFtype) Wtype_MIN)
147390280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
147490280Sobrien  return (Wtype) a;
147518334Speter}
147618334Speter#endif
147718334Speter
147818334Speter/* From here on down, the routines use normal data types.  */
147918334Speter
148018334Speter#define SItype bogus_type
148118334Speter#define USItype bogus_type
148218334Speter#define DItype bogus_type
148318334Speter#define UDItype bogus_type
148418334Speter#define SFtype bogus_type
148518334Speter#define DFtype bogus_type
148690280Sobrien#undef Wtype
148790280Sobrien#undef UWtype
148890280Sobrien#undef HWtype
148990280Sobrien#undef UHWtype
149090280Sobrien#undef DWtype
149190280Sobrien#undef UDWtype
149218334Speter
149318334Speter#undef char
149418334Speter#undef short
149518334Speter#undef int
149618334Speter#undef long
149718334Speter#undef unsigned
149818334Speter#undef float
149918334Speter#undef double
150018334Speter
150118334Speter#ifdef L__gcc_bcmp
150218334Speter
150318334Speter/* Like bcmp except the sign is meaningful.
150418334Speter   Result is negative if S1 is less than S2,
150518334Speter   positive if S1 is greater, 0 if S1 and S2 are equal.  */
150618334Speter
150718334Speterint
150890280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
150918334Speter{
151018334Speter  while (size > 0)
151118334Speter    {
1512132727Skan      const unsigned char c1 = *s1++, c2 = *s2++;
151318334Speter      if (c1 != c2)
151418334Speter	return c1 - c2;
151518334Speter      size--;
151618334Speter    }
151718334Speter  return 0;
151818334Speter}
151918334Speter
152018334Speter#endif
152118334Speter
152290280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>.
152390280Sobrien   We no longer provide that header, but this routine remains in libgcc.a
152490280Sobrien   for binary backward compatibility.  Note that it is not included in
152590280Sobrien   the shared version of libgcc.  */
152618334Speter#ifdef L_eprintf
152718334Speter#ifndef inhibit_libc
152818334Speter
152918334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
153018334Speter#include <stdio.h>
153152561Sobrien
153218334Spetervoid
153350600Sobrien__eprintf (const char *string, const char *expression,
153450600Sobrien	   unsigned int line, const char *filename)
153518334Speter{
153618334Speter  fprintf (stderr, string, expression, line, filename);
153718334Speter  fflush (stderr);
153818334Speter  abort ();
153918334Speter}
154018334Speter
154118334Speter#endif
154218334Speter#endif
154318334Speter
154418334Speter
154518334Speter#ifdef L_clear_cache
154618334Speter/* Clear part of an instruction cache.  */
154718334Speter
154818334Spetervoid
154990280Sobrien__clear_cache (char *beg __attribute__((__unused__)),
155090280Sobrien	       char *end __attribute__((__unused__)))
155118334Speter{
155290280Sobrien#ifdef CLEAR_INSN_CACHE
155318334Speter  CLEAR_INSN_CACHE (beg, end);
155418334Speter#endif /* CLEAR_INSN_CACHE */
155518334Speter}
155618334Speter
155718334Speter#endif /* L_clear_cache */
155818334Speter
1559132727Skan#ifdef L_enable_execute_stack
1560132727Skan/* Attempt to turn on execute permission for the stack.  */
1561132727Skan
1562132727Skan#ifdef ENABLE_EXECUTE_STACK
1563132727Skan  ENABLE_EXECUTE_STACK
1564132727Skan#else
1565132727Skanvoid
1566132727Skan__enable_execute_stack (void *addr __attribute__((__unused__)))
1567132727Skan{}
1568132727Skan#endif /* ENABLE_EXECUTE_STACK */
1569132727Skan
1570132727Skan#endif /* L_enable_execute_stack */
1571132727Skan
157218334Speter#ifdef L_trampoline
157318334Speter
157418334Speter/* Jump to a trampoline, loading the static chain address.  */
157518334Speter
157652561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
157718334Speter
157890280Sobrienlong
157990280Sobriengetpagesize (void)
158018334Speter{
158118334Speter#ifdef _ALPHA_
158218334Speter  return 8192;
158318334Speter#else
158418334Speter  return 4096;
158518334Speter#endif
158618334Speter}
158718334Speter
158890280Sobrien#ifdef __i386__
158950600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
159050600Sobrien#endif
159150600Sobrien
159250600Sobrienint
159350600Sobrienmprotect (char *addr, int len, int prot)
159418334Speter{
159518334Speter  int np, op;
159618334Speter
159750600Sobrien  if (prot == 7)
159850600Sobrien    np = 0x40;
159950600Sobrien  else if (prot == 5)
160050600Sobrien    np = 0x20;
160150600Sobrien  else if (prot == 4)
160250600Sobrien    np = 0x10;
160350600Sobrien  else if (prot == 3)
160450600Sobrien    np = 0x04;
160550600Sobrien  else if (prot == 1)
160650600Sobrien    np = 0x02;
160750600Sobrien  else if (prot == 0)
160850600Sobrien    np = 0x01;
160918334Speter
161018334Speter  if (VirtualProtect (addr, len, np, &op))
161118334Speter    return 0;
161218334Speter  else
161318334Speter    return -1;
161418334Speter}
161518334Speter
161652561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
161718334Speter
161890280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE
161990280SobrienTRANSFER_FROM_TRAMPOLINE
162018334Speter#endif
162118334Speter#endif /* L_trampoline */
162218334Speter
162352561Sobrien#ifndef __CYGWIN__
162418334Speter#ifdef L__main
162518334Speter
162618334Speter#include "gbl-ctors.h"
162718334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these
162818334Speter   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
162918334Speter   give the same symbol without quotes for an alternative entry point.  You
163050600Sobrien   must define both, or neither.  */
163118334Speter#ifndef NAME__MAIN
163218334Speter#define NAME__MAIN "__main"
163318334Speter#define SYMBOL__MAIN __main
163418334Speter#endif
163518334Speter
163650600Sobrien#ifdef INIT_SECTION_ASM_OP
163750600Sobrien#undef HAS_INIT_SECTION
163850600Sobrien#define HAS_INIT_SECTION
163950600Sobrien#endif
164050600Sobrien
164150600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
164290280Sobrien
164390280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
164490280Sobrien   code to run constructors.  In that case, we need to handle EH here, too.  */
164590280Sobrien
164690280Sobrien#ifdef EH_FRAME_SECTION_NAME
164790280Sobrien#include "unwind-dw2-fde.h"
164890280Sobrienextern unsigned char __EH_FRAME_BEGIN__[];
164990280Sobrien#endif
165090280Sobrien
165118334Speter/* Run all the global destructors on exit from the program.  */
165218334Speter
165318334Spetervoid
165490280Sobrien__do_global_dtors (void)
165518334Speter{
165618334Speter#ifdef DO_GLOBAL_DTORS_BODY
165718334Speter  DO_GLOBAL_DTORS_BODY;
165818334Speter#else
165950600Sobrien  static func_ptr *p = __DTOR_LIST__ + 1;
166050600Sobrien  while (*p)
166150600Sobrien    {
166250600Sobrien      p++;
166350600Sobrien      (*(p-1)) ();
166450600Sobrien    }
166518334Speter#endif
166690280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
166790280Sobrien  {
166890280Sobrien    static int completed = 0;
166990280Sobrien    if (! completed)
167090280Sobrien      {
167190280Sobrien	completed = 1;
167290280Sobrien	__deregister_frame_info (__EH_FRAME_BEGIN__);
167390280Sobrien      }
167490280Sobrien  }
167590280Sobrien#endif
167618334Speter}
167750600Sobrien#endif
167818334Speter
167950600Sobrien#ifndef HAS_INIT_SECTION
168018334Speter/* Run all the global constructors on entry to the program.  */
168118334Speter
168218334Spetervoid
168390280Sobrien__do_global_ctors (void)
168418334Speter{
168590280Sobrien#ifdef EH_FRAME_SECTION_NAME
168690280Sobrien  {
168790280Sobrien    static struct object object;
168890280Sobrien    __register_frame_info (__EH_FRAME_BEGIN__, &object);
168990280Sobrien  }
169090280Sobrien#endif
169118334Speter  DO_GLOBAL_CTORS_BODY;
169290280Sobrien  atexit (__do_global_dtors);
169318334Speter}
169450600Sobrien#endif /* no HAS_INIT_SECTION */
169518334Speter
169650600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
169718334Speter/* Subroutine called automatically by `main'.
169818334Speter   Compiling a global function named `main'
169918334Speter   produces an automatic call to this function at the beginning.
170018334Speter
170118334Speter   For many systems, this routine calls __do_global_ctors.
170218334Speter   For systems which support a .init section we use the .init section
170318334Speter   to run __do_global_ctors, so we need not do anything here.  */
170418334Speter
1705132727Skanextern void SYMBOL__MAIN (void);
170618334Spetervoid
1707132727SkanSYMBOL__MAIN (void)
170818334Speter{
170918334Speter  /* Support recursive calls to `main': run initializers just once.  */
171018334Speter  static int initialized;
171118334Speter  if (! initialized)
171218334Speter    {
171318334Speter      initialized = 1;
171418334Speter      __do_global_ctors ();
171518334Speter    }
171618334Speter}
171750600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */
171818334Speter
171918334Speter#endif /* L__main */
172052561Sobrien#endif /* __CYGWIN__ */
172118334Speter
172218334Speter#ifdef L_ctors
172318334Speter
172418334Speter#include "gbl-ctors.h"
172518334Speter
172618334Speter/* Provide default definitions for the lists of constructors and
172718334Speter   destructors, so that we don't get linker errors.  These symbols are
172818334Speter   intentionally bss symbols, so that gld and/or collect will provide
172918334Speter   the right values.  */
173018334Speter
173118334Speter/* We declare the lists here with two elements each,
173252561Sobrien   so that they are valid empty lists if no other definition is loaded.
173352561Sobrien
173452561Sobrien   If we are using the old "set" extensions to have the gnu linker
173552561Sobrien   collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
173652561Sobrien   must be in the bss/common section.
173752561Sobrien
173852561Sobrien   Long term no port should use those extensions.  But many still do.  */
173950600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
174090280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
174118334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0};
174218334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0};
174318334Speter#else
174418334Speterfunc_ptr __CTOR_LIST__[2];
174518334Speterfunc_ptr __DTOR_LIST__[2];
174618334Speter#endif
174718334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
174818334Speter#endif /* L_ctors */
174918334Speter
1750