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,
4169699Skan   2000, 2001, 2002, 2003, 2004, 2005  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
29169699SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
30169699Skan02110-1301, USA.  */
3118334Speter
3218334Speter#include "tconfig.h"
3390280Sobrien#include "tsystem.h"
34132727Skan#include "coretypes.h"
35132727Skan#include "tm.h"
3650600Sobrien
37132727Skan#ifdef HAVE_GAS_HIDDEN
38132727Skan#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
39132727Skan#else
40132727Skan#define ATTRIBUTE_HIDDEN
41132727Skan#endif
42132727Skan
43169699Skan#ifndef MIN_UNITS_PER_WORD
44169699Skan#define MIN_UNITS_PER_WORD UNITS_PER_WORD
45169699Skan#endif
46169699Skan
47169699Skan/* Work out the largest "word" size that we can deal with on this target.  */
48169699Skan#if MIN_UNITS_PER_WORD > 4
49169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD 8
50169699Skan#elif (MIN_UNITS_PER_WORD > 2 \
51169699Skan       || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
52169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD 4
53169699Skan#else
54169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD
55169699Skan#endif
56169699Skan
57169699Skan/* Work out what word size we are using for this compilation.
58169699Skan   The value can be set on the command line.  */
59169699Skan#ifndef LIBGCC2_UNITS_PER_WORD
60169699Skan#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD
61169699Skan#endif
62169699Skan
63169699Skan#if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD
64169699Skan
6590280Sobrien#include "libgcc2.h"
6690280Sobrien
67117404Skan#ifdef DECLARE_LIBRARY_RENAMES
68117404Skan  DECLARE_LIBRARY_RENAMES
6918334Speter#endif
70117404Skan
71117404Skan#if defined (L_negdi2)
7290280SobrienDWtype
7390280Sobrien__negdi2 (DWtype u)
7490280Sobrien{
75132727Skan  const DWunion uu = {.ll = u};
76132727Skan  const DWunion w = { {.low = -uu.s.low,
77132727Skan		       .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
7818334Speter
7990280Sobrien  return w.ll;
8090280Sobrien}
8150600Sobrien#endif
8250600Sobrien
8390280Sobrien#ifdef L_addvsi3
8490280SobrienWtype
85146906Skan__addvSI3 (Wtype a, Wtype b)
8690280Sobrien{
87132727Skan  const Wtype w = a + b;
8818334Speter
8990280Sobrien  if (b >= 0 ? w < a : w > a)
9090280Sobrien    abort ();
9190280Sobrien
9290280Sobrien  return w;
9390280Sobrien}
94146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
95146906SkanSItype
96146906Skan__addvsi3 (SItype a, SItype b)
97146906Skan{
98146906Skan  const SItype w = a + b;
99146906Skan
100146906Skan  if (b >= 0 ? w < a : w > a)
101146906Skan    abort ();
102146906Skan
103146906Skan  return w;
104146906Skan}
105146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
10618334Speter#endif
10790280Sobrien
10890280Sobrien#ifdef L_addvdi3
10990280SobrienDWtype
110146906Skan__addvDI3 (DWtype a, DWtype b)
11190280Sobrien{
112132727Skan  const DWtype w = a + b;
11318334Speter
11490280Sobrien  if (b >= 0 ? w < a : w > a)
11590280Sobrien    abort ();
11690280Sobrien
11790280Sobrien  return w;
11890280Sobrien}
11952561Sobrien#endif
12090280Sobrien
12190280Sobrien#ifdef L_subvsi3
12290280SobrienWtype
123146906Skan__subvSI3 (Wtype a, Wtype b)
12490280Sobrien{
125146906Skan  const Wtype w = a - b;
12652561Sobrien
12790280Sobrien  if (b >= 0 ? w > a : w < a)
12890280Sobrien    abort ();
12918334Speter
13090280Sobrien  return w;
13190280Sobrien}
132146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
133146906SkanSItype
134146906Skan__subvsi3 (SItype a, SItype b)
135146906Skan{
136146906Skan  const SItype w = a - b;
137146906Skan
138146906Skan  if (b >= 0 ? w > a : w < a)
139146906Skan    abort ();
140146906Skan
141146906Skan  return w;
142146906Skan}
143146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
14490280Sobrien#endif
14590280Sobrien
14690280Sobrien#ifdef L_subvdi3
14790280SobrienDWtype
148146906Skan__subvDI3 (DWtype a, DWtype b)
14990280Sobrien{
150132727Skan  const DWtype w = a - b;
15118334Speter
15290280Sobrien  if (b >= 0 ? w > a : w < a)
15390280Sobrien    abort ();
15490280Sobrien
15590280Sobrien  return w;
15690280Sobrien}
15718334Speter#endif
15890280Sobrien
15990280Sobrien#ifdef L_mulvsi3
16090280SobrienWtype
161146906Skan__mulvSI3 (Wtype a, Wtype b)
16290280Sobrien{
163132727Skan  const DWtype w = (DWtype) a * (DWtype) b;
16418334Speter
165169699Skan  if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
16690280Sobrien    abort ();
16718334Speter
16890280Sobrien  return w;
16990280Sobrien}
170146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
171146906Skan#undef WORD_SIZE
172146906Skan#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
173146906SkanSItype
174146906Skan__mulvsi3 (SItype a, SItype b)
175146906Skan{
176146906Skan  const DItype w = (DItype) a * (DItype) b;
177146906Skan
178146906Skan  if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
179146906Skan    abort ();
180146906Skan
181146906Skan  return w;
182146906Skan}
183146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
18490280Sobrien#endif
18590280Sobrien
18690280Sobrien#ifdef L_negvsi2
18790280SobrienWtype
188146906Skan__negvSI2 (Wtype a)
18990280Sobrien{
190132727Skan  const Wtype w = -a;
19118334Speter
19290280Sobrien  if (a >= 0 ? w > 0 : w < 0)
19390280Sobrien    abort ();
19418334Speter
19590280Sobrien   return w;
19690280Sobrien}
197146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
198146906SkanSItype
199146906Skan__negvsi2 (SItype a)
200146906Skan{
201146906Skan  const SItype w = -a;
202146906Skan
203146906Skan  if (a >= 0 ? w > 0 : w < 0)
204146906Skan    abort ();
205146906Skan
206146906Skan   return w;
207146906Skan}
208146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
20918334Speter#endif
21090280Sobrien
21190280Sobrien#ifdef L_negvdi2
21290280SobrienDWtype
213146906Skan__negvDI2 (DWtype a)
21490280Sobrien{
215132727Skan  const DWtype w = -a;
21618334Speter
21790280Sobrien  if (a >= 0 ? w > 0 : w < 0)
21890280Sobrien    abort ();
21990280Sobrien
220117404Skan  return w;
22190280Sobrien}
22290280Sobrien#endif
22390280Sobrien
22490280Sobrien#ifdef L_absvsi2
22590280SobrienWtype
226146906Skan__absvSI2 (Wtype a)
22718334Speter{
228117404Skan  Wtype w = a;
22918334Speter
230117404Skan  if (a < 0)
23190280Sobrien#ifdef L_negvsi2
232146906Skan    w = __negvSI2 (a);
233146906Skan#else
234146906Skan    w = -a;
235146906Skan
236146906Skan  if (w < 0)
237146906Skan    abort ();
238146906Skan#endif
239146906Skan
240146906Skan   return w;
241146906Skan}
242146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
243146906SkanSItype
244146906Skan__absvsi2 (SItype a)
245146906Skan{
246146906Skan  SItype w = a;
247146906Skan
248146906Skan  if (a < 0)
249146906Skan#ifdef L_negvsi2
250117404Skan    w = __negvsi2 (a);
25190280Sobrien#else
252117404Skan    w = -a;
25318334Speter
254117404Skan  if (w < 0)
255117404Skan    abort ();
25690280Sobrien#endif
25718334Speter
25890280Sobrien   return w;
25990280Sobrien}
260146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
26190280Sobrien#endif
26290280Sobrien
26390280Sobrien#ifdef L_absvdi2
26490280SobrienDWtype
265146906Skan__absvDI2 (DWtype a)
26690280Sobrien{
267117404Skan  DWtype w = a;
26818334Speter
269117404Skan  if (a < 0)
270132727Skan#ifdef L_negvdi2
271146906Skan    w = __negvDI2 (a);
27290280Sobrien#else
273117404Skan    w = -a;
27490280Sobrien
275117404Skan  if (w < 0)
276117404Skan    abort ();
27718334Speter#endif
27890280Sobrien
279117404Skan  return w;
28090280Sobrien}
28118334Speter#endif
28218334Speter
28390280Sobrien#ifdef L_mulvdi3
28490280SobrienDWtype
285146906Skan__mulvDI3 (DWtype u, DWtype v)
28618334Speter{
287132727Skan  /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
288132727Skan     but the checked multiplication needs only two.  */
289132727Skan  const DWunion uu = {.ll = u};
290132727Skan  const DWunion vv = {.ll = v};
29118334Speter
292169699Skan  if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1))
293132727Skan    {
294132727Skan      /* u fits in a single Wtype.  */
295169699Skan      if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
296132727Skan	{
297132727Skan	  /* v fits in a single Wtype as well.  */
298132727Skan	  /* A single multiplication.  No overflow risk.  */
299132727Skan	  return (DWtype) uu.s.low * (DWtype) vv.s.low;
300132727Skan	}
301132727Skan      else
302132727Skan	{
303132727Skan	  /* Two multiplications.  */
304132727Skan	  DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
305132727Skan			* (UDWtype) (UWtype) vv.s.low};
306132727Skan	  DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
307132727Skan			* (UDWtype) (UWtype) vv.s.high};
30818334Speter
309132727Skan	  if (vv.s.high < 0)
310132727Skan	    w1.s.high -= uu.s.low;
311132727Skan	  if (uu.s.low < 0)
312132727Skan	    w1.ll -= vv.ll;
313132727Skan	  w1.ll += (UWtype) w0.s.high;
314169699Skan	  if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
315132727Skan	    {
316132727Skan	      w0.s.high = w1.s.low;
317132727Skan	      return w0.ll;
318132727Skan	    }
319132727Skan	}
320132727Skan    }
321132727Skan  else
322132727Skan    {
323169699Skan      if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
324132727Skan	{
325132727Skan	  /* v fits into a single Wtype.  */
326132727Skan	  /* Two multiplications.  */
327132727Skan	  DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
328132727Skan			* (UDWtype) (UWtype) vv.s.low};
329132727Skan	  DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
330132727Skan			* (UDWtype) (UWtype) vv.s.low};
33118334Speter
332132727Skan	  if (uu.s.high < 0)
333132727Skan	    w1.s.high -= vv.s.low;
334132727Skan	  if (vv.s.low < 0)
335132727Skan	    w1.ll -= uu.ll;
336132727Skan	  w1.ll += (UWtype) w0.s.high;
337169699Skan	  if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
338132727Skan	    {
339132727Skan	      w0.s.high = w1.s.low;
340132727Skan	      return w0.ll;
341132727Skan	    }
342132727Skan	}
343132727Skan      else
344132727Skan	{
345132727Skan	  /* A few sign checks and a single multiplication.  */
346132727Skan	  if (uu.s.high >= 0)
347132727Skan	    {
348132727Skan	      if (vv.s.high >= 0)
349132727Skan		{
350132727Skan		  if (uu.s.high == 0 && vv.s.high == 0)
351132727Skan		    {
352132727Skan		      const DWtype w = (UDWtype) (UWtype) uu.s.low
353132727Skan			* (UDWtype) (UWtype) vv.s.low;
354132727Skan		      if (__builtin_expect (w >= 0, 1))
355132727Skan			return w;
356132727Skan		    }
357132727Skan		}
358132727Skan	      else
359132727Skan		{
360132727Skan		  if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
361132727Skan		    {
362132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
363132727Skan				    * (UDWtype) (UWtype) vv.s.low};
364132727Skan
365132727Skan		      ww.s.high -= uu.s.low;
366132727Skan		      if (__builtin_expect (ww.s.high < 0, 1))
367132727Skan			return ww.ll;
368132727Skan		    }
369132727Skan		}
370132727Skan	    }
371132727Skan	  else
372132727Skan	    {
373132727Skan	      if (vv.s.high >= 0)
374132727Skan		{
375132727Skan		  if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
376132727Skan		    {
377132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
378132727Skan				    * (UDWtype) (UWtype) vv.s.low};
379132727Skan
380132727Skan		      ww.s.high -= vv.s.low;
381132727Skan		      if (__builtin_expect (ww.s.high < 0, 1))
382132727Skan			return ww.ll;
383132727Skan		    }
384132727Skan		}
385132727Skan	      else
386132727Skan		{
387132727Skan		  if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
388132727Skan		    {
389132727Skan		      DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
390132727Skan				    * (UDWtype) (UWtype) vv.s.low};
391132727Skan
392132727Skan		      ww.s.high -= uu.s.low;
393132727Skan		      ww.s.high -= vv.s.low;
394132727Skan		      if (__builtin_expect (ww.s.high >= 0, 1))
395132727Skan			return ww.ll;
396132727Skan		    }
397132727Skan		}
398132727Skan	    }
399132727Skan	}
400132727Skan    }
401132727Skan
402132727Skan  /* Overflow.  */
403132727Skan  abort ();
40418334Speter}
40518334Speter#endif
40618334Speter
40790280Sobrien
408132727Skan/* Unless shift functions are defined with full ANSI prototypes,
40950600Sobrien   parameter b will be promoted to int if word_type is smaller than an int.  */
41018334Speter#ifdef L_lshrdi3
41190280SobrienDWtype
41290280Sobrien__lshrdi3 (DWtype u, word_type b)
41318334Speter{
41418334Speter  if (b == 0)
41518334Speter    return u;
41618334Speter
417132727Skan  const DWunion uu = {.ll = u};
418132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
419132727Skan  DWunion w;
42018334Speter
42118334Speter  if (bm <= 0)
42218334Speter    {
42318334Speter      w.s.high = 0;
42490280Sobrien      w.s.low = (UWtype) uu.s.high >> -bm;
42518334Speter    }
42618334Speter  else
42718334Speter    {
428132727Skan      const UWtype carries = (UWtype) uu.s.high << bm;
42990280Sobrien
43090280Sobrien      w.s.high = (UWtype) uu.s.high >> b;
43190280Sobrien      w.s.low = ((UWtype) uu.s.low >> b) | carries;
43218334Speter    }
43318334Speter
43418334Speter  return w.ll;
43518334Speter}
43618334Speter#endif
43718334Speter
43818334Speter#ifdef L_ashldi3
43990280SobrienDWtype
44090280Sobrien__ashldi3 (DWtype u, word_type b)
44118334Speter{
44218334Speter  if (b == 0)
44318334Speter    return u;
44418334Speter
445132727Skan  const DWunion uu = {.ll = u};
446132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
447132727Skan  DWunion w;
44818334Speter
44918334Speter  if (bm <= 0)
45018334Speter    {
45118334Speter      w.s.low = 0;
45290280Sobrien      w.s.high = (UWtype) uu.s.low << -bm;
45318334Speter    }
45418334Speter  else
45518334Speter    {
456132727Skan      const UWtype carries = (UWtype) uu.s.low >> bm;
45790280Sobrien
45890280Sobrien      w.s.low = (UWtype) uu.s.low << b;
45990280Sobrien      w.s.high = ((UWtype) uu.s.high << b) | carries;
46018334Speter    }
46118334Speter
46218334Speter  return w.ll;
46318334Speter}
46418334Speter#endif
46518334Speter
46618334Speter#ifdef L_ashrdi3
46790280SobrienDWtype
46890280Sobrien__ashrdi3 (DWtype u, word_type b)
46918334Speter{
47018334Speter  if (b == 0)
47118334Speter    return u;
47218334Speter
473132727Skan  const DWunion uu = {.ll = u};
474132727Skan  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
475132727Skan  DWunion w;
47618334Speter
47718334Speter  if (bm <= 0)
47818334Speter    {
47918334Speter      /* w.s.high = 1..1 or 0..0 */
48090280Sobrien      w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
48118334Speter      w.s.low = uu.s.high >> -bm;
48218334Speter    }
48318334Speter  else
48418334Speter    {
485132727Skan      const UWtype carries = (UWtype) uu.s.high << bm;
48690280Sobrien
48718334Speter      w.s.high = uu.s.high >> b;
48890280Sobrien      w.s.low = ((UWtype) uu.s.low >> b) | carries;
48918334Speter    }
49018334Speter
49118334Speter  return w.ll;
49218334Speter}
49318334Speter#endif
49418334Speter
495258428Spfg#ifdef L_bswapsi2
496258428SpfgUWtype
497258428Spfg__bswapsi2 (UWtype u)
498258428Spfg{
499258428Spfg  return ((((u) & 0xff000000) >> 24)
500258428Spfg	  | (((u) & 0x00ff0000) >>  8)
501258428Spfg	  | (((u) & 0x0000ff00) <<  8)
502258428Spfg	  | (((u) & 0x000000ff) << 24));
503258428Spfg}
504258428Spfg#endif
505258428Spfg#ifdef L_bswapdi2
506258428SpfgUDWtype
507258428Spfg__bswapdi2 (UDWtype u)
508258428Spfg{
509258428Spfg  return ((((u) & 0xff00000000000000ull) >> 56)
510258428Spfg	  | (((u) & 0x00ff000000000000ull) >> 40)
511258428Spfg	  | (((u) & 0x0000ff0000000000ull) >> 24)
512258428Spfg	  | (((u) & 0x000000ff00000000ull) >>  8)
513258428Spfg	  | (((u) & 0x00000000ff000000ull) <<  8)
514258428Spfg	  | (((u) & 0x0000000000ff0000ull) << 24)
515258428Spfg	  | (((u) & 0x000000000000ff00ull) << 40)
516258428Spfg	  | (((u) & 0x00000000000000ffull) << 56));
517258428Spfg}
518258428Spfg#endif
519132727Skan#ifdef L_ffssi2
520132727Skan#undef int
521132727Skanint
522132727Skan__ffsSI2 (UWtype u)
523132727Skan{
524132727Skan  UWtype count;
525132727Skan
526132727Skan  if (u == 0)
527132727Skan    return 0;
528132727Skan
529132727Skan  count_trailing_zeros (count, u);
530132727Skan  return count + 1;
531132727Skan}
532132727Skan#endif
533132727Skan
53418334Speter#ifdef L_ffsdi2
535132727Skan#undef int
536132727Skanint
537132727Skan__ffsDI2 (DWtype u)
53818334Speter{
539132727Skan  const DWunion uu = {.ll = u};
54090280Sobrien  UWtype word, count, add;
54190280Sobrien
54290280Sobrien  if (uu.s.low != 0)
54390280Sobrien    word = uu.s.low, add = 0;
54490280Sobrien  else if (uu.s.high != 0)
54590280Sobrien    word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
54690280Sobrien  else
54790280Sobrien    return 0;
54890280Sobrien
54990280Sobrien  count_trailing_zeros (count, word);
55090280Sobrien  return count + add + 1;
55118334Speter}
55218334Speter#endif
55318334Speter
55418334Speter#ifdef L_muldi3
55590280SobrienDWtype
55690280Sobrien__muldi3 (DWtype u, DWtype v)
55718334Speter{
558132727Skan  const DWunion uu = {.ll = u};
559132727Skan  const DWunion vv = {.ll = v};
560132727Skan  DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
56118334Speter
56290280Sobrien  w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
56390280Sobrien	       + (UWtype) uu.s.high * (UWtype) vv.s.low);
56418334Speter
56518334Speter  return w.ll;
56618334Speter}
56718334Speter#endif
56818334Speter
569117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
570117404Skan     defined (L_umoddi3) || defined (L_moddi3))
571117404Skan#if defined (sdiv_qrnnd)
572117404Skan#define L_udiv_w_sdiv
573117404Skan#endif
574117404Skan#endif
575117404Skan
57618334Speter#ifdef L_udiv_w_sdiv
57718334Speter#if defined (sdiv_qrnnd)
578117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
579117404Skan     defined (L_umoddi3) || defined (L_moddi3))
580117404Skanstatic inline __attribute__ ((__always_inline__))
581117404Skan#endif
58290280SobrienUWtype
58390280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
58418334Speter{
58590280Sobrien  UWtype q, r;
58690280Sobrien  UWtype c0, c1, b1;
58718334Speter
58890280Sobrien  if ((Wtype) d >= 0)
58918334Speter    {
59090280Sobrien      if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
59118334Speter	{
592169699Skan	  /* Dividend, divisor, and quotient are nonnegative.  */
59318334Speter	  sdiv_qrnnd (q, r, a1, a0, d);
59418334Speter	}
59518334Speter      else
59618334Speter	{
597169699Skan	  /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d.  */
59890280Sobrien	  sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
599169699Skan	  /* Divide (c1*2^32 + c0) by d.  */
60018334Speter	  sdiv_qrnnd (q, r, c1, c0, d);
601169699Skan	  /* Add 2^31 to quotient.  */
60290280Sobrien	  q += (UWtype) 1 << (W_TYPE_SIZE - 1);
60318334Speter	}
60418334Speter    }
60518334Speter  else
60618334Speter    {
60718334Speter      b1 = d >> 1;			/* d/2, between 2^30 and 2^31 - 1 */
60818334Speter      c1 = a1 >> 1;			/* A/2 */
60990280Sobrien      c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
61018334Speter
61118334Speter      if (a1 < b1)			/* A < 2^32*b1, so A/2 < 2^31*b1 */
61218334Speter	{
61318334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
61418334Speter
61518334Speter	  r = 2*r + (a0 & 1);		/* Remainder from A/(2*b1) */
61618334Speter	  if ((d & 1) != 0)
61718334Speter	    {
61818334Speter	      if (r >= q)
61918334Speter		r = r - q;
62018334Speter	      else if (q - r <= d)
62118334Speter		{
62218334Speter		  r = r - q + d;
62318334Speter		  q--;
62418334Speter		}
62518334Speter	      else
62618334Speter		{
62718334Speter		  r = r - q + 2*d;
62818334Speter		  q -= 2;
62918334Speter		}
63018334Speter	    }
63118334Speter	}
63218334Speter      else if (c1 < b1)			/* So 2^31 <= (A/2)/b1 < 2^32 */
63318334Speter	{
63418334Speter	  c1 = (b1 - 1) - c1;
63518334Speter	  c0 = ~c0;			/* logical NOT */
63618334Speter
63718334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
63818334Speter
63918334Speter	  q = ~q;			/* (A/2)/b1 */
64018334Speter	  r = (b1 - 1) - r;
64118334Speter
64218334Speter	  r = 2*r + (a0 & 1);		/* A/(2*b1) */
64318334Speter
64418334Speter	  if ((d & 1) != 0)
64518334Speter	    {
64618334Speter	      if (r >= q)
64718334Speter		r = r - q;
64818334Speter	      else if (q - r <= d)
64918334Speter		{
65018334Speter		  r = r - q + d;
65118334Speter		  q--;
65218334Speter		}
65318334Speter	      else
65418334Speter		{
65518334Speter		  r = r - q + 2*d;
65618334Speter		  q -= 2;
65718334Speter		}
65818334Speter	    }
65918334Speter	}
66018334Speter      else				/* Implies c1 = b1 */
66118334Speter	{				/* Hence a1 = d - 1 = 2*b1 - 1 */
66218334Speter	  if (a0 >= -d)
66318334Speter	    {
66418334Speter	      q = -1;
66518334Speter	      r = a0 + d;
66618334Speter	    }
66718334Speter	  else
66818334Speter	    {
66918334Speter	      q = -2;
67018334Speter	      r = a0 + 2*d;
67118334Speter	    }
67218334Speter	}
67318334Speter    }
67418334Speter
67518334Speter  *rp = r;
67618334Speter  return q;
67718334Speter}
67818334Speter#else
67918334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
68090280SobrienUWtype
68190280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
68290280Sobrien	       UWtype a1 __attribute__ ((__unused__)),
68390280Sobrien	       UWtype a0 __attribute__ ((__unused__)),
68490280Sobrien	       UWtype d __attribute__ ((__unused__)))
68550600Sobrien{
68650600Sobrien  return 0;
68750600Sobrien}
68818334Speter#endif
68918334Speter#endif
69018334Speter
69118334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
69218334Speter     defined (L_umoddi3) || defined (L_moddi3))
69318334Speter#define L_udivmoddi4
69418334Speter#endif
69518334Speter
69690280Sobrien#ifdef L_clz
697169699Skanconst UQItype __clz_tab[256] =
69818334Speter{
69918334Speter  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,
70018334Speter  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,
70118334Speter  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,
70218334Speter  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,
70318334Speter  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,
70418334Speter  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,
70518334Speter  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,
706169699Skan  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
70718334Speter};
70890280Sobrien#endif
709132727Skan
710132727Skan#ifdef L_clzsi2
711132727Skan#undef int
712132727Skanint
713132727Skan__clzSI2 (UWtype x)
714132727Skan{
715132727Skan  Wtype ret;
71618334Speter
717132727Skan  count_leading_zeros (ret, x);
718132727Skan
719132727Skan  return ret;
720132727Skan}
721132727Skan#endif
722132727Skan
723132727Skan#ifdef L_clzdi2
724132727Skan#undef int
725132727Skanint
726132727Skan__clzDI2 (UDWtype x)
727132727Skan{
728132727Skan  const DWunion uu = {.ll = x};
729132727Skan  UWtype word;
730132727Skan  Wtype ret, add;
731132727Skan
732132727Skan  if (uu.s.high)
733132727Skan    word = uu.s.high, add = 0;
734132727Skan  else
735132727Skan    word = uu.s.low, add = W_TYPE_SIZE;
736132727Skan
737132727Skan  count_leading_zeros (ret, word);
738132727Skan  return ret + add;
739132727Skan}
740132727Skan#endif
741132727Skan
742132727Skan#ifdef L_ctzsi2
743132727Skan#undef int
744132727Skanint
745132727Skan__ctzSI2 (UWtype x)
746132727Skan{
747132727Skan  Wtype ret;
748132727Skan
749132727Skan  count_trailing_zeros (ret, x);
750132727Skan
751132727Skan  return ret;
752132727Skan}
753132727Skan#endif
754132727Skan
755132727Skan#ifdef L_ctzdi2
756132727Skan#undef int
757132727Skanint
758132727Skan__ctzDI2 (UDWtype x)
759132727Skan{
760132727Skan  const DWunion uu = {.ll = x};
761132727Skan  UWtype word;
762132727Skan  Wtype ret, add;
763132727Skan
764132727Skan  if (uu.s.low)
765132727Skan    word = uu.s.low, add = 0;
766132727Skan  else
767132727Skan    word = uu.s.high, add = W_TYPE_SIZE;
768132727Skan
769132727Skan  count_trailing_zeros (ret, word);
770132727Skan  return ret + add;
771132727Skan}
772132727Skan#endif
773132727Skan
774132727Skan#ifdef L_popcount_tab
775169699Skanconst UQItype __popcount_tab[256] =
776132727Skan{
777132727Skan    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,
778132727Skan    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,
779132727Skan    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,
780132727Skan    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,
781132727Skan    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,
782132727Skan    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,
783132727Skan    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,
784169699Skan    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
785132727Skan};
786132727Skan#endif
787132727Skan
788132727Skan#ifdef L_popcountsi2
789132727Skan#undef int
790132727Skanint
791132727Skan__popcountSI2 (UWtype x)
792132727Skan{
793169699Skan  int i, ret = 0;
794132727Skan
795132727Skan  for (i = 0; i < W_TYPE_SIZE; i += 8)
796132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
797132727Skan
798132727Skan  return ret;
799132727Skan}
800132727Skan#endif
801132727Skan
802132727Skan#ifdef L_popcountdi2
803132727Skan#undef int
804132727Skanint
805132727Skan__popcountDI2 (UDWtype x)
806132727Skan{
807169699Skan  int i, ret = 0;
808132727Skan
809132727Skan  for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
810132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
811132727Skan
812132727Skan  return ret;
813132727Skan}
814132727Skan#endif
815132727Skan
816132727Skan#ifdef L_paritysi2
817132727Skan#undef int
818132727Skanint
819132727Skan__paritySI2 (UWtype x)
820132727Skan{
821132727Skan#if W_TYPE_SIZE > 64
822132727Skan# error "fill out the table"
823132727Skan#endif
824132727Skan#if W_TYPE_SIZE > 32
825132727Skan  x ^= x >> 32;
826132727Skan#endif
827132727Skan#if W_TYPE_SIZE > 16
828132727Skan  x ^= x >> 16;
829132727Skan#endif
830132727Skan  x ^= x >> 8;
831132727Skan  x ^= x >> 4;
832132727Skan  x &= 0xf;
833132727Skan  return (0x6996 >> x) & 1;
834132727Skan}
835132727Skan#endif
836132727Skan
837132727Skan#ifdef L_paritydi2
838132727Skan#undef int
839132727Skanint
840132727Skan__parityDI2 (UDWtype x)
841132727Skan{
842132727Skan  const DWunion uu = {.ll = x};
843132727Skan  UWtype nx = uu.s.low ^ uu.s.high;
844132727Skan
845132727Skan#if W_TYPE_SIZE > 64
846132727Skan# error "fill out the table"
847132727Skan#endif
848132727Skan#if W_TYPE_SIZE > 32
849132727Skan  nx ^= nx >> 32;
850132727Skan#endif
851132727Skan#if W_TYPE_SIZE > 16
852132727Skan  nx ^= nx >> 16;
853132727Skan#endif
854132727Skan  nx ^= nx >> 8;
855132727Skan  nx ^= nx >> 4;
856132727Skan  nx &= 0xf;
857132727Skan  return (0x6996 >> nx) & 1;
858132727Skan}
859132727Skan#endif
860132727Skan
86190280Sobrien#ifdef L_udivmoddi4
86290280Sobrien
86318334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
86418334Speter     defined (L_umoddi3) || defined (L_moddi3))
865117404Skanstatic inline __attribute__ ((__always_inline__))
86618334Speter#endif
86790280SobrienUDWtype
86890280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
86918334Speter{
870132727Skan  const DWunion nn = {.ll = n};
871132727Skan  const DWunion dd = {.ll = d};
87290280Sobrien  DWunion rr;
87390280Sobrien  UWtype d0, d1, n0, n1, n2;
87490280Sobrien  UWtype q0, q1;
87590280Sobrien  UWtype b, bm;
87618334Speter
87718334Speter  d0 = dd.s.low;
87818334Speter  d1 = dd.s.high;
87918334Speter  n0 = nn.s.low;
88018334Speter  n1 = nn.s.high;
88118334Speter
88218334Speter#if !UDIV_NEEDS_NORMALIZATION
88318334Speter  if (d1 == 0)
88418334Speter    {
88518334Speter      if (d0 > n1)
88618334Speter	{
88718334Speter	  /* 0q = nn / 0D */
88818334Speter
88918334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
89018334Speter	  q1 = 0;
89118334Speter
89218334Speter	  /* Remainder in n0.  */
89318334Speter	}
89418334Speter      else
89518334Speter	{
89618334Speter	  /* qq = NN / 0d */
89718334Speter
89818334Speter	  if (d0 == 0)
89918334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
90018334Speter
90118334Speter	  udiv_qrnnd (q1, n1, 0, n1, d0);
90218334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
90318334Speter
90418334Speter	  /* Remainder in n0.  */
90518334Speter	}
90618334Speter
90718334Speter      if (rp != 0)
90818334Speter	{
90918334Speter	  rr.s.low = n0;
91018334Speter	  rr.s.high = 0;
91118334Speter	  *rp = rr.ll;
91218334Speter	}
91318334Speter    }
91418334Speter
91518334Speter#else /* UDIV_NEEDS_NORMALIZATION */
91618334Speter
91718334Speter  if (d1 == 0)
91818334Speter    {
91918334Speter      if (d0 > n1)
92018334Speter	{
92118334Speter	  /* 0q = nn / 0D */
92218334Speter
92318334Speter	  count_leading_zeros (bm, d0);
92418334Speter
92518334Speter	  if (bm != 0)
92618334Speter	    {
92718334Speter	      /* Normalize, i.e. make the most significant bit of the
92818334Speter		 denominator set.  */
92918334Speter
93018334Speter	      d0 = d0 << bm;
93190280Sobrien	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
93218334Speter	      n0 = n0 << bm;
93318334Speter	    }
93418334Speter
93518334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
93618334Speter	  q1 = 0;
93718334Speter
93818334Speter	  /* Remainder in n0 >> bm.  */
93918334Speter	}
94018334Speter      else
94118334Speter	{
94218334Speter	  /* qq = NN / 0d */
94318334Speter
94418334Speter	  if (d0 == 0)
94518334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
94618334Speter
94718334Speter	  count_leading_zeros (bm, d0);
94818334Speter
94918334Speter	  if (bm == 0)
95018334Speter	    {
95118334Speter	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
95218334Speter		 conclude (the most significant bit of n1 is set) /\ (the
95318334Speter		 leading quotient digit q1 = 1).
95418334Speter
95518334Speter		 This special case is necessary, not an optimization.
95690280Sobrien		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
95718334Speter
95818334Speter	      n1 -= d0;
95918334Speter	      q1 = 1;
96018334Speter	    }
96118334Speter	  else
96218334Speter	    {
96318334Speter	      /* Normalize.  */
96418334Speter
96590280Sobrien	      b = W_TYPE_SIZE - bm;
96618334Speter
96718334Speter	      d0 = d0 << bm;
96818334Speter	      n2 = n1 >> b;
96918334Speter	      n1 = (n1 << bm) | (n0 >> b);
97018334Speter	      n0 = n0 << bm;
97118334Speter
97218334Speter	      udiv_qrnnd (q1, n1, n2, n1, d0);
97318334Speter	    }
97418334Speter
97550600Sobrien	  /* n1 != d0...  */
97618334Speter
97718334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
97818334Speter
97918334Speter	  /* Remainder in n0 >> bm.  */
98018334Speter	}
98118334Speter
98218334Speter      if (rp != 0)
98318334Speter	{
98418334Speter	  rr.s.low = n0 >> bm;
98518334Speter	  rr.s.high = 0;
98618334Speter	  *rp = rr.ll;
98718334Speter	}
98818334Speter    }
98918334Speter#endif /* UDIV_NEEDS_NORMALIZATION */
99018334Speter
99118334Speter  else
99218334Speter    {
99318334Speter      if (d1 > n1)
99418334Speter	{
99518334Speter	  /* 00 = nn / DD */
99618334Speter
99718334Speter	  q0 = 0;
99818334Speter	  q1 = 0;
99918334Speter
100018334Speter	  /* Remainder in n1n0.  */
100118334Speter	  if (rp != 0)
100218334Speter	    {
100318334Speter	      rr.s.low = n0;
100418334Speter	      rr.s.high = n1;
100518334Speter	      *rp = rr.ll;
100618334Speter	    }
100718334Speter	}
100818334Speter      else
100918334Speter	{
101018334Speter	  /* 0q = NN / dd */
101118334Speter
101218334Speter	  count_leading_zeros (bm, d1);
101318334Speter	  if (bm == 0)
101418334Speter	    {
101518334Speter	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
101618334Speter		 conclude (the most significant bit of n1 is set) /\ (the
101718334Speter		 quotient digit q0 = 0 or 1).
101818334Speter
101918334Speter		 This special case is necessary, not an optimization.  */
102018334Speter
102118334Speter	      /* The condition on the next line takes advantage of that
102218334Speter		 n1 >= d1 (true due to program flow).  */
102318334Speter	      if (n1 > d1 || n0 >= d0)
102418334Speter		{
102518334Speter		  q0 = 1;
102618334Speter		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
102718334Speter		}
102818334Speter	      else
102918334Speter		q0 = 0;
103018334Speter
103118334Speter	      q1 = 0;
103218334Speter
103318334Speter	      if (rp != 0)
103418334Speter		{
103518334Speter		  rr.s.low = n0;
103618334Speter		  rr.s.high = n1;
103718334Speter		  *rp = rr.ll;
103818334Speter		}
103918334Speter	    }
104018334Speter	  else
104118334Speter	    {
104290280Sobrien	      UWtype m1, m0;
104318334Speter	      /* Normalize.  */
104418334Speter
104590280Sobrien	      b = W_TYPE_SIZE - bm;
104618334Speter
104718334Speter	      d1 = (d1 << bm) | (d0 >> b);
104818334Speter	      d0 = d0 << bm;
104918334Speter	      n2 = n1 >> b;
105018334Speter	      n1 = (n1 << bm) | (n0 >> b);
105118334Speter	      n0 = n0 << bm;
105218334Speter
105318334Speter	      udiv_qrnnd (q0, n1, n2, n1, d1);
105418334Speter	      umul_ppmm (m1, m0, q0, d0);
105518334Speter
105618334Speter	      if (m1 > n1 || (m1 == n1 && m0 > n0))
105718334Speter		{
105818334Speter		  q0--;
105918334Speter		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
106018334Speter		}
106118334Speter
106218334Speter	      q1 = 0;
106318334Speter
106418334Speter	      /* Remainder in (n1n0 - m1m0) >> bm.  */
106518334Speter	      if (rp != 0)
106618334Speter		{
106718334Speter		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
106818334Speter		  rr.s.low = (n1 << b) | (n0 >> bm);
106918334Speter		  rr.s.high = n1 >> bm;
107018334Speter		  *rp = rr.ll;
107118334Speter		}
107218334Speter	    }
107318334Speter	}
107418334Speter    }
107518334Speter
1076132727Skan  const DWunion ww = {{.low = q0, .high = q1}};
107718334Speter  return ww.ll;
107818334Speter}
107918334Speter#endif
108018334Speter
108118334Speter#ifdef L_divdi3
108290280SobrienDWtype
108390280Sobrien__divdi3 (DWtype u, DWtype v)
108418334Speter{
108518334Speter  word_type c = 0;
1086132727Skan  DWunion uu = {.ll = u};
1087132727Skan  DWunion vv = {.ll = v};
108890280Sobrien  DWtype w;
108918334Speter
109018334Speter  if (uu.s.high < 0)
109118334Speter    c = ~c,
1092117404Skan    uu.ll = -uu.ll;
109318334Speter  if (vv.s.high < 0)
109418334Speter    c = ~c,
1095117404Skan    vv.ll = -vv.ll;
109618334Speter
109790280Sobrien  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
109818334Speter  if (c)
1099117404Skan    w = -w;
110018334Speter
110118334Speter  return w;
110218334Speter}
110318334Speter#endif
110418334Speter
110518334Speter#ifdef L_moddi3
110690280SobrienDWtype
110790280Sobrien__moddi3 (DWtype u, DWtype v)
110818334Speter{
110918334Speter  word_type c = 0;
1110132727Skan  DWunion uu = {.ll = u};
1111132727Skan  DWunion vv = {.ll = v};
111290280Sobrien  DWtype w;
111318334Speter
111418334Speter  if (uu.s.high < 0)
111518334Speter    c = ~c,
1116117404Skan    uu.ll = -uu.ll;
111718334Speter  if (vv.s.high < 0)
1118117404Skan    vv.ll = -vv.ll;
111918334Speter
1120169699Skan  (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
112118334Speter  if (c)
1122117404Skan    w = -w;
112318334Speter
112418334Speter  return w;
112518334Speter}
112618334Speter#endif
112718334Speter
112818334Speter#ifdef L_umoddi3
112990280SobrienUDWtype
113090280Sobrien__umoddi3 (UDWtype u, UDWtype v)
113118334Speter{
113290280Sobrien  UDWtype w;
113318334Speter
113418334Speter  (void) __udivmoddi4 (u, v, &w);
113518334Speter
113618334Speter  return w;
113718334Speter}
113818334Speter#endif
113918334Speter
114018334Speter#ifdef L_udivdi3
114190280SobrienUDWtype
114290280Sobrien__udivdi3 (UDWtype n, UDWtype d)
114318334Speter{
114490280Sobrien  return __udivmoddi4 (n, d, (UDWtype *) 0);
114518334Speter}
114618334Speter#endif
114718334Speter
114818334Speter#ifdef L_cmpdi2
114918334Speterword_type
115090280Sobrien__cmpdi2 (DWtype a, DWtype b)
115118334Speter{
1152132727Skan  const DWunion au = {.ll = a};
1153132727Skan  const DWunion bu = {.ll = b};
115418334Speter
115518334Speter  if (au.s.high < bu.s.high)
115618334Speter    return 0;
115718334Speter  else if (au.s.high > bu.s.high)
115818334Speter    return 2;
115990280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
116018334Speter    return 0;
116190280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
116218334Speter    return 2;
116318334Speter  return 1;
116418334Speter}
116518334Speter#endif
116618334Speter
116718334Speter#ifdef L_ucmpdi2
116818334Speterword_type
116990280Sobrien__ucmpdi2 (DWtype a, DWtype b)
117018334Speter{
1171132727Skan  const DWunion au = {.ll = a};
1172132727Skan  const DWunion bu = {.ll = b};
117318334Speter
117490280Sobrien  if ((UWtype) au.s.high < (UWtype) bu.s.high)
117518334Speter    return 0;
117690280Sobrien  else if ((UWtype) au.s.high > (UWtype) bu.s.high)
117718334Speter    return 2;
117890280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
117918334Speter    return 0;
118090280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
118118334Speter    return 2;
118218334Speter  return 1;
118318334Speter}
118418334Speter#endif
118518334Speter
1186169699Skan#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
118790280SobrienDWtype
118890280Sobrien__fixunstfDI (TFtype a)
118918334Speter{
119018334Speter  if (a < 0)
119118334Speter    return 0;
119218334Speter
119318334Speter  /* Compute high word of result, as a flonum.  */
1194169699Skan  const TFtype b = (a / Wtype_MAXp1_F);
119590280Sobrien  /* Convert that to fixed (but not to DWtype!),
119618334Speter     and shift it into the high word.  */
1197132727Skan  UDWtype v = (UWtype) b;
1198169699Skan  v <<= W_TYPE_SIZE;
119918334Speter  /* Remove high part from the TFtype, leaving the low part as flonum.  */
120018334Speter  a -= (TFtype)v;
120190280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
120218334Speter     Sometimes A comes out negative.  This is significant, since
120318334Speter     A has more bits than a long int does.  */
120418334Speter  if (a < 0)
120590280Sobrien    v -= (UWtype) (- a);
120618334Speter  else
120790280Sobrien    v += (UWtype) a;
120818334Speter  return v;
120918334Speter}
121018334Speter#endif
121118334Speter
1212169699Skan#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
121390280SobrienDWtype
121450600Sobrien__fixtfdi (TFtype a)
121518334Speter{
121618334Speter  if (a < 0)
121790280Sobrien    return - __fixunstfDI (-a);
121890280Sobrien  return __fixunstfDI (a);
121918334Speter}
122018334Speter#endif
122118334Speter
1222169699Skan#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
122390280SobrienDWtype
122490280Sobrien__fixunsxfDI (XFtype a)
122518334Speter{
122618334Speter  if (a < 0)
122718334Speter    return 0;
122818334Speter
122918334Speter  /* Compute high word of result, as a flonum.  */
1230169699Skan  const XFtype b = (a / Wtype_MAXp1_F);
123190280Sobrien  /* Convert that to fixed (but not to DWtype!),
123218334Speter     and shift it into the high word.  */
1233132727Skan  UDWtype v = (UWtype) b;
1234169699Skan  v <<= W_TYPE_SIZE;
123518334Speter  /* Remove high part from the XFtype, leaving the low part as flonum.  */
123618334Speter  a -= (XFtype)v;
123790280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
123818334Speter     Sometimes A comes out negative.  This is significant, since
123918334Speter     A has more bits than a long int does.  */
124018334Speter  if (a < 0)
124190280Sobrien    v -= (UWtype) (- a);
124218334Speter  else
124390280Sobrien    v += (UWtype) a;
124418334Speter  return v;
124518334Speter}
124618334Speter#endif
124718334Speter
1248169699Skan#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
124990280SobrienDWtype
125050600Sobrien__fixxfdi (XFtype a)
125118334Speter{
125218334Speter  if (a < 0)
125390280Sobrien    return - __fixunsxfDI (-a);
125490280Sobrien  return __fixunsxfDI (a);
125518334Speter}
125618334Speter#endif
125718334Speter
1258169699Skan#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
125990280SobrienDWtype
126090280Sobrien__fixunsdfDI (DFtype a)
126118334Speter{
1262132727Skan  /* Get high part of result.  The division here will just moves the radix
1263132727Skan     point and will not cause any rounding.  Then the conversion to integral
1264132727Skan     type chops result as desired.  */
1265169699Skan  const UWtype hi = a / Wtype_MAXp1_F;
126618334Speter
1267132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1268132727Skan     then subtract this from the number being converted.  This leaves the low
1269132727Skan     part.  Convert that to integral type.  */
1270169699Skan  const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
127118334Speter
1272132727Skan  /* Assemble result from the two parts.  */
1273169699Skan  return ((UDWtype) hi << W_TYPE_SIZE) | lo;
127418334Speter}
127518334Speter#endif
127618334Speter
1277169699Skan#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
127890280SobrienDWtype
127950600Sobrien__fixdfdi (DFtype a)
128018334Speter{
128118334Speter  if (a < 0)
128290280Sobrien    return - __fixunsdfDI (-a);
128390280Sobrien  return __fixunsdfDI (a);
128418334Speter}
128518334Speter#endif
128618334Speter
1287169699Skan#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE
128890280SobrienDWtype
1289169699Skan__fixunssfDI (SFtype a)
129018334Speter{
1291169699Skan#if LIBGCC2_HAS_DF_MODE
129218334Speter  /* Convert the SFtype to a DFtype, because that is surely not going
129318334Speter     to lose any bits.  Some day someone else can write a faster version
129418334Speter     that avoids converting to DFtype, and verify it really works right.  */
1295169699Skan  const DFtype dfa = a;
129618334Speter
1297132727Skan  /* Get high part of result.  The division here will just moves the radix
1298132727Skan     point and will not cause any rounding.  Then the conversion to integral
1299132727Skan     type chops result as desired.  */
1300169699Skan  const UWtype hi = dfa / Wtype_MAXp1_F;
130118334Speter
1302132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1303132727Skan     then subtract this from the number being converted.  This leaves the low
1304132727Skan     part.  Convert that to integral type.  */
1305169699Skan  const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
1306132727Skan
1307132727Skan  /* Assemble result from the two parts.  */
1308169699Skan  return ((UDWtype) hi << W_TYPE_SIZE) | lo;
1309169699Skan#elif FLT_MANT_DIG < W_TYPE_SIZE
1310169699Skan  if (a < 1)
1311169699Skan    return 0;
1312169699Skan  if (a < Wtype_MAXp1_F)
1313169699Skan    return (UWtype)a;
1314169699Skan  if (a < Wtype_MAXp1_F * Wtype_MAXp1_F)
1315169699Skan    {
1316169699Skan      /* Since we know that there are fewer significant bits in the SFmode
1317169699Skan	 quantity than in a word, we know that we can convert out all the
1318169699Skan	 significant bits in one step, and thus avoid losing bits.  */
1319169699Skan
1320169699Skan      /* ??? This following loop essentially performs frexpf.  If we could
1321169699Skan	 use the real libm function, or poke at the actual bits of the fp
1322169699Skan	 format, it would be significantly faster.  */
1323169699Skan
1324169699Skan      UWtype shift = 0, counter;
1325169699Skan      SFtype msb;
1326169699Skan
1327169699Skan      a /= Wtype_MAXp1_F;
1328169699Skan      for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1)
1329169699Skan	{
1330169699Skan	  SFtype counterf = (UWtype)1 << counter;
1331169699Skan	  if (a >= counterf)
1332169699Skan	    {
1333169699Skan	      shift |= counter;
1334169699Skan	      a /= counterf;
1335169699Skan	    }
1336169699Skan	}
1337169699Skan
1338169699Skan      /* Rescale into the range of one word, extract the bits of that
1339169699Skan	 one word, and shift the result into position.  */
1340169699Skan      a *= Wtype_MAXp1_F;
1341169699Skan      counter = a;
1342169699Skan      return (DWtype)counter << shift;
1343169699Skan    }
1344169699Skan  return -1;
1345169699Skan#else
1346169699Skan# error
1347169699Skan#endif
134818334Speter}
134918334Speter#endif
135018334Speter
1351169699Skan#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE
135290280SobrienDWtype
135318334Speter__fixsfdi (SFtype a)
135418334Speter{
135518334Speter  if (a < 0)
135690280Sobrien    return - __fixunssfDI (-a);
135790280Sobrien  return __fixunssfDI (a);
135818334Speter}
135918334Speter#endif
136018334Speter
1361169699Skan#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
136218334SpeterXFtype
136390280Sobrien__floatdixf (DWtype u)
136418334Speter{
1365169699Skan#if W_TYPE_SIZE > XF_SIZE
1366169699Skan# error
1367169699Skan#endif
1368169699Skan  XFtype d = (Wtype) (u >> W_TYPE_SIZE);
1369169699Skan  d *= Wtype_MAXp1_F;
1370169699Skan  d += (UWtype)u;
1371169699Skan  return d;
1372169699Skan}
1373169699Skan#endif
137418334Speter
1375169699Skan#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE
1376169699SkanXFtype
1377169699Skan__floatundixf (UDWtype u)
1378169699Skan{
1379169699Skan#if W_TYPE_SIZE > XF_SIZE
1380169699Skan# error
1381169699Skan#endif
1382169699Skan  XFtype d = (UWtype) (u >> W_TYPE_SIZE);
1383169699Skan  d *= Wtype_MAXp1_F;
1384169699Skan  d += (UWtype)u;
138550600Sobrien  return d;
138618334Speter}
138718334Speter#endif
138818334Speter
1389169699Skan#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
139018334SpeterTFtype
139190280Sobrien__floatditf (DWtype u)
139218334Speter{
1393169699Skan#if W_TYPE_SIZE > TF_SIZE
1394169699Skan# error
1395169699Skan#endif
1396169699Skan  TFtype d = (Wtype) (u >> W_TYPE_SIZE);
1397169699Skan  d *= Wtype_MAXp1_F;
1398169699Skan  d += (UWtype)u;
1399169699Skan  return d;
1400169699Skan}
1401169699Skan#endif
140218334Speter
1403169699Skan#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE
1404169699SkanTFtype
1405169699Skan__floatunditf (UDWtype u)
1406169699Skan{
1407169699Skan#if W_TYPE_SIZE > TF_SIZE
1408169699Skan# error
1409169699Skan#endif
1410169699Skan  TFtype d = (UWtype) (u >> W_TYPE_SIZE);
1411169699Skan  d *= Wtype_MAXp1_F;
1412169699Skan  d += (UWtype)u;
141350600Sobrien  return d;
141418334Speter}
141518334Speter#endif
141618334Speter
1417169699Skan#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE)	\
1418169699Skan     || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
1419169699Skan#define DI_SIZE (W_TYPE_SIZE * 2)
1420169699Skan#define F_MODE_OK(SIZE) \
1421169699Skan  (SIZE < DI_SIZE							\
1422169699Skan   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
1423260194Spfg   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
1424260194Spfg      The conversion from long double to float suffers from double	\
1425260194Spfg      rounding, because we convert via double.  In any case, the	\
1426260194Spfg      fallback code is faster.  */					\
1427260194Spfg   && !IS_IBM_EXTENDED (SIZE))
1428169699Skan#if defined(L_floatdisf)
1429169699Skan#define FUNC __floatdisf
1430169699Skan#define FSTYPE SFtype
1431169699Skan#define FSSIZE SF_SIZE
1432169699Skan#else
1433169699Skan#define FUNC __floatdidf
1434169699Skan#define FSTYPE DFtype
1435169699Skan#define FSSIZE DF_SIZE
1436169699Skan#endif
143718334Speter
1438169699SkanFSTYPE
1439169699SkanFUNC (DWtype u)
144018334Speter{
1441169699Skan#if FSSIZE >= W_TYPE_SIZE
1442169699Skan  /* When the word size is small, we never get any rounding error.  */
1443169699Skan  FSTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1444169699Skan  f *= Wtype_MAXp1_F;
1445169699Skan  f += (UWtype)u;
1446169699Skan  return f;
1447169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))	\
1448169699Skan     || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))	\
1449169699Skan     || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
145018334Speter
1451169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1452169699Skan# define FSIZE DF_SIZE
1453169699Skan# define FTYPE DFtype
1454169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1455169699Skan# define FSIZE XF_SIZE
1456169699Skan# define FTYPE XFtype
1457169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1458169699Skan# define FSIZE TF_SIZE
1459169699Skan# define FTYPE TFtype
1460169699Skan#else
1461169699Skan# error
1462169699Skan#endif
1463169699Skan
1464169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1465169699Skan
1466169699Skan  /* Protect against double-rounding error.
1467169699Skan     Represent any low-order bits, that might be truncated by a bit that
1468169699Skan     won't be lost.  The bit can go in anywhere below the rounding position
1469169699Skan     of the FSTYPE.  A fixed mask and bit position handles all usual
1470169699Skan     configurations.  */
1471169699Skan  if (! (- ((DWtype) 1 << FSIZE) < u
1472169699Skan	 && u < ((DWtype) 1 << FSIZE)))
1473169699Skan    {
1474169699Skan      if ((UDWtype) u & (REP_BIT - 1))
1475169699Skan	{
1476169699Skan	  u &= ~ (REP_BIT - 1);
1477169699Skan	  u |= REP_BIT;
1478169699Skan	}
1479169699Skan    }
1480169699Skan
1481169699Skan  /* Do the calculation in a wider type so that we don't lose any of
1482169699Skan     the precision of the high word while multiplying it.  */
1483169699Skan  FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1484169699Skan  f *= Wtype_MAXp1_F;
1485169699Skan  f += (UWtype)u;
1486169699Skan  return (FSTYPE) f;
1487169699Skan#else
1488169699Skan#if FSSIZE >= W_TYPE_SIZE - 2
1489169699Skan# error
1490169699Skan#endif
1491169699Skan  /* Finally, the word size is larger than the number of bits in the
1492169699Skan     required FSTYPE, and we've got no suitable wider type.  The only
1493169699Skan     way to avoid double rounding is to special case the
1494169699Skan     extraction.  */
1495169699Skan
1496169699Skan  /* If there are no high bits set, fall back to one conversion.  */
1497169699Skan  if ((Wtype)u == u)
1498169699Skan    return (FSTYPE)(Wtype)u;
1499169699Skan
1500169699Skan  /* Otherwise, find the power of two.  */
1501169699Skan  Wtype hi = u >> W_TYPE_SIZE;
1502169699Skan  if (hi < 0)
1503169699Skan    hi = -hi;
1504169699Skan
1505169699Skan  UWtype count, shift;
1506169699Skan  count_leading_zeros (count, hi);
1507169699Skan
1508169699Skan  /* No leading bits means u == minimum.  */
1509169699Skan  if (count == 0)
1510169699Skan    return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2));
1511169699Skan
1512169699Skan  shift = 1 + W_TYPE_SIZE - count;
1513169699Skan
1514169699Skan  /* Shift down the most significant bits.  */
1515169699Skan  hi = u >> shift;
1516169699Skan
1517169699Skan  /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
1518260194Spfg  if (u & (((DWtype)1 << shift) - 1))
1519169699Skan    hi |= 1;
1520169699Skan
1521169699Skan  /* Convert the one word of data, and rescale.  */
1522260194Spfg  FSTYPE f = hi;
1523260194Spfg  f *= (UDWtype)1 << shift;
1524260194Spfg  return f;
1525169699Skan#endif
152618334Speter}
152718334Speter#endif
152818334Speter
1529169699Skan#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE)	\
1530169699Skan     || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
1531169699Skan#define DI_SIZE (W_TYPE_SIZE * 2)
1532169699Skan#define F_MODE_OK(SIZE) \
1533169699Skan  (SIZE < DI_SIZE							\
1534169699Skan   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
1535260194Spfg   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
1536260194Spfg      The conversion from long double to float suffers from double	\
1537260194Spfg      rounding, because we convert via double.  In any case, the	\
1538260194Spfg      fallback code is faster.  */					\
1539260194Spfg   && !IS_IBM_EXTENDED (SIZE))
1540169699Skan#if defined(L_floatundisf)
1541169699Skan#define FUNC __floatundisf
1542169699Skan#define FSTYPE SFtype
1543169699Skan#define FSSIZE SF_SIZE
1544169699Skan#else
1545169699Skan#define FUNC __floatundidf
1546169699Skan#define FSTYPE DFtype
1547169699Skan#define FSSIZE DF_SIZE
1548169699Skan#endif
1549117404Skan
1550169699SkanFSTYPE
1551169699SkanFUNC (UDWtype u)
1552169699Skan{
1553169699Skan#if FSSIZE >= W_TYPE_SIZE
1554169699Skan  /* When the word size is small, we never get any rounding error.  */
1555169699Skan  FSTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1556169699Skan  f *= Wtype_MAXp1_F;
1557169699Skan  f += (UWtype)u;
1558169699Skan  return f;
1559169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))	\
1560169699Skan     || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))	\
1561169699Skan     || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
156218334Speter
1563169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1564169699Skan# define FSIZE DF_SIZE
1565169699Skan# define FTYPE DFtype
1566169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1567169699Skan# define FSIZE XF_SIZE
1568169699Skan# define FTYPE XFtype
1569169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1570169699Skan# define FSIZE TF_SIZE
1571169699Skan# define FTYPE TFtype
1572169699Skan#else
1573169699Skan# error
1574169699Skan#endif
1575169699Skan
1576169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1577169699Skan
157818334Speter  /* Protect against double-rounding error.
1579169699Skan     Represent any low-order bits, that might be truncated by a bit that
1580169699Skan     won't be lost.  The bit can go in anywhere below the rounding position
1581169699Skan     of the FSTYPE.  A fixed mask and bit position handles all usual
1582169699Skan     configurations.  */
1583169699Skan  if (u >= ((UDWtype) 1 << FSIZE))
158418334Speter    {
1585169699Skan      if ((UDWtype) u & (REP_BIT - 1))
158618334Speter	{
1587169699Skan	  u &= ~ (REP_BIT - 1);
1588169699Skan	  u |= REP_BIT;
158918334Speter	}
159018334Speter    }
159118334Speter
1592169699Skan  /* Do the calculation in a wider type so that we don't lose any of
1593169699Skan     the precision of the high word while multiplying it.  */
1594169699Skan  FTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1595169699Skan  f *= Wtype_MAXp1_F;
1596169699Skan  f += (UWtype)u;
1597169699Skan  return (FSTYPE) f;
1598169699Skan#else
1599169699Skan#if FSSIZE == W_TYPE_SIZE - 1
1600169699Skan# error
1601169699Skan#endif
1602169699Skan  /* Finally, the word size is larger than the number of bits in the
1603169699Skan     required FSTYPE, and we've got no suitable wider type.  The only
1604169699Skan     way to avoid double rounding is to special case the
1605169699Skan     extraction.  */
1606169699Skan
1607169699Skan  /* If there are no high bits set, fall back to one conversion.  */
1608169699Skan  if ((UWtype)u == u)
1609169699Skan    return (FSTYPE)(UWtype)u;
1610169699Skan
1611169699Skan  /* Otherwise, find the power of two.  */
1612169699Skan  UWtype hi = u >> W_TYPE_SIZE;
1613169699Skan
1614169699Skan  UWtype count, shift;
1615169699Skan  count_leading_zeros (count, hi);
1616169699Skan
1617169699Skan  shift = W_TYPE_SIZE - count;
1618169699Skan
1619169699Skan  /* Shift down the most significant bits.  */
1620169699Skan  hi = u >> shift;
1621169699Skan
1622169699Skan  /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
1623260194Spfg  if (u & (((UDWtype)1 << shift) - 1))
1624169699Skan    hi |= 1;
1625169699Skan
1626169699Skan  /* Convert the one word of data, and rescale.  */
1627260194Spfg  FSTYPE f = hi;
1628260194Spfg  f *= (UDWtype)1 << shift;
1629260194Spfg  return f;
1630169699Skan#endif
163118334Speter}
163218334Speter#endif
163318334Speter
1634169699Skan#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
163518334Speter/* Reenable the normal types, in case limits.h needs them.  */
163618334Speter#undef char
163718334Speter#undef short
163818334Speter#undef int
163918334Speter#undef long
164018334Speter#undef unsigned
164118334Speter#undef float
164218334Speter#undef double
164318334Speter#undef MIN
164418334Speter#undef MAX
164518334Speter#include <limits.h>
164618334Speter
164790280SobrienUWtype
164890280Sobrien__fixunsxfSI (XFtype a)
164918334Speter{
165090280Sobrien  if (a >= - (DFtype) Wtype_MIN)
165190280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
165290280Sobrien  return (Wtype) a;
165318334Speter}
165418334Speter#endif
165518334Speter
1656169699Skan#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
165718334Speter/* Reenable the normal types, in case limits.h needs them.  */
165818334Speter#undef char
165918334Speter#undef short
166018334Speter#undef int
166118334Speter#undef long
166218334Speter#undef unsigned
166318334Speter#undef float
166418334Speter#undef double
166518334Speter#undef MIN
166618334Speter#undef MAX
166718334Speter#include <limits.h>
166818334Speter
166990280SobrienUWtype
167090280Sobrien__fixunsdfSI (DFtype a)
167118334Speter{
167290280Sobrien  if (a >= - (DFtype) Wtype_MIN)
167390280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
167490280Sobrien  return (Wtype) a;
167518334Speter}
167618334Speter#endif
167718334Speter
1678169699Skan#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE
167918334Speter/* Reenable the normal types, in case limits.h needs them.  */
168018334Speter#undef char
168118334Speter#undef short
168218334Speter#undef int
168318334Speter#undef long
168418334Speter#undef unsigned
168518334Speter#undef float
168618334Speter#undef double
168718334Speter#undef MIN
168818334Speter#undef MAX
168918334Speter#include <limits.h>
169018334Speter
169190280SobrienUWtype
169290280Sobrien__fixunssfSI (SFtype a)
169318334Speter{
169490280Sobrien  if (a >= - (SFtype) Wtype_MIN)
169590280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
169690280Sobrien  return (Wtype) a;
169718334Speter}
169818334Speter#endif
169918334Speter
1700169699Skan/* Integer power helper used from __builtin_powi for non-constant
1701169699Skan   exponents.  */
1702169699Skan
1703169699Skan#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \
1704169699Skan    || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \
1705169699Skan    || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \
1706169699Skan    || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE)
1707169699Skan# if defined(L_powisf2)
1708169699Skan#  define TYPE SFtype
1709169699Skan#  define NAME __powisf2
1710169699Skan# elif defined(L_powidf2)
1711169699Skan#  define TYPE DFtype
1712169699Skan#  define NAME __powidf2
1713169699Skan# elif defined(L_powixf2)
1714169699Skan#  define TYPE XFtype
1715169699Skan#  define NAME __powixf2
1716169699Skan# elif defined(L_powitf2)
1717169699Skan#  define TYPE TFtype
1718169699Skan#  define NAME __powitf2
1719169699Skan# endif
1720169699Skan
1721169699Skan#undef int
1722169699Skan#undef unsigned
1723169699SkanTYPE
1724169699SkanNAME (TYPE x, int m)
1725169699Skan{
1726169699Skan  unsigned int n = m < 0 ? -m : m;
1727169699Skan  TYPE y = n % 2 ? x : 1;
1728169699Skan  while (n >>= 1)
1729169699Skan    {
1730169699Skan      x = x * x;
1731169699Skan      if (n % 2)
1732169699Skan	y = y * x;
1733169699Skan    }
1734169699Skan  return m < 0 ? 1/y : y;
1735169699Skan}
1736169699Skan
1737169699Skan#endif
1738169699Skan
1739169699Skan#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
1740169699Skan    || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
1741169699Skan    || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
1742169699Skan    || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE)
1743169699Skan
1744169699Skan#undef float
1745169699Skan#undef double
1746169699Skan#undef long
1747169699Skan
1748169699Skan#if defined(L_mulsc3) || defined(L_divsc3)
1749169699Skan# define MTYPE	SFtype
1750169699Skan# define CTYPE	SCtype
1751169699Skan# define MODE	sc
1752169699Skan# define CEXT	f
1753169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0
1754169699Skan#elif defined(L_muldc3) || defined(L_divdc3)
1755169699Skan# define MTYPE	DFtype
1756169699Skan# define CTYPE	DCtype
1757169699Skan# define MODE	dc
1758169699Skan# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64
1759169699Skan#  define CEXT	l
1760169699Skan#  define NOTRUNC 1
1761169699Skan# else
1762169699Skan#  define CEXT
1763169699Skan#  define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
1764169699Skan# endif
1765169699Skan#elif defined(L_mulxc3) || defined(L_divxc3)
1766169699Skan# define MTYPE	XFtype
1767169699Skan# define CTYPE	XCtype
1768169699Skan# define MODE	xc
1769169699Skan# define CEXT	l
1770169699Skan# define NOTRUNC 1
1771169699Skan#elif defined(L_multc3) || defined(L_divtc3)
1772169699Skan# define MTYPE	TFtype
1773169699Skan# define CTYPE	TCtype
1774169699Skan# define MODE	tc
1775169699Skan# define CEXT	l
1776169699Skan# define NOTRUNC 1
1777169699Skan#else
1778169699Skan# error
1779169699Skan#endif
1780169699Skan
1781169699Skan#define CONCAT3(A,B,C)	_CONCAT3(A,B,C)
1782169699Skan#define _CONCAT3(A,B,C)	A##B##C
1783169699Skan
1784169699Skan#define CONCAT2(A,B)	_CONCAT2(A,B)
1785169699Skan#define _CONCAT2(A,B)	A##B
1786169699Skan
1787169699Skan/* All of these would be present in a full C99 implementation of <math.h>
1788169699Skan   and <complex.h>.  Our problem is that only a few systems have such full
1789169699Skan   implementations.  Further, libgcc_s.so isn't currently linked against
1790169699Skan   libm.so, and even for systems that do provide full C99, the extra overhead
1791169699Skan   of all programs using libgcc having to link against libm.  So avoid it.  */
1792169699Skan
1793169699Skan#define isnan(x)	__builtin_expect ((x) != (x), 0)
1794169699Skan#define isfinite(x)	__builtin_expect (!isnan((x) - (x)), 1)
1795169699Skan#define isinf(x)	__builtin_expect (!isnan(x) & !isfinite(x), 0)
1796169699Skan
1797169699Skan#define INFINITY	CONCAT2(__builtin_inf, CEXT) ()
1798169699Skan#define I		1i
1799169699Skan
1800169699Skan/* Helpers to make the following code slightly less gross.  */
1801169699Skan#define COPYSIGN	CONCAT2(__builtin_copysign, CEXT)
1802169699Skan#define FABS		CONCAT2(__builtin_fabs, CEXT)
1803169699Skan
1804169699Skan/* Verify that MTYPE matches up with CEXT.  */
1805169699Skanextern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
1806169699Skan
1807169699Skan/* Ensure that we've lost any extra precision.  */
1808169699Skan#if NOTRUNC
1809169699Skan# define TRUNC(x)
1810169699Skan#else
1811169699Skan# define TRUNC(x)	__asm__ ("" : "=m"(x) : "m"(x))
1812169699Skan#endif
1813169699Skan
1814169699Skan#if defined(L_mulsc3) || defined(L_muldc3) \
1815169699Skan    || defined(L_mulxc3) || defined(L_multc3)
1816169699Skan
1817169699SkanCTYPE
1818169699SkanCONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1819169699Skan{
1820169699Skan  MTYPE ac, bd, ad, bc, x, y;
1821169699Skan
1822169699Skan  ac = a * c;
1823169699Skan  bd = b * d;
1824169699Skan  ad = a * d;
1825169699Skan  bc = b * c;
1826169699Skan
1827169699Skan  TRUNC (ac);
1828169699Skan  TRUNC (bd);
1829169699Skan  TRUNC (ad);
1830169699Skan  TRUNC (bc);
1831169699Skan
1832169699Skan  x = ac - bd;
1833169699Skan  y = ad + bc;
1834169699Skan
1835169699Skan  if (isnan (x) && isnan (y))
1836169699Skan    {
1837169699Skan      /* Recover infinities that computed as NaN + iNaN.  */
1838169699Skan      _Bool recalc = 0;
1839169699Skan      if (isinf (a) || isinf (b))
1840169699Skan	{
1841169699Skan	  /* z is infinite.  "Box" the infinity and change NaNs in
1842169699Skan	     the other factor to 0.  */
1843169699Skan	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
1844169699Skan	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
1845169699Skan	  if (isnan (c)) c = COPYSIGN (0, c);
1846169699Skan	  if (isnan (d)) d = COPYSIGN (0, d);
1847169699Skan          recalc = 1;
1848169699Skan	}
1849169699Skan     if (isinf (c) || isinf (d))
1850169699Skan	{
1851169699Skan	  /* w is infinite.  "Box" the infinity and change NaNs in
1852169699Skan	     the other factor to 0.  */
1853169699Skan	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
1854169699Skan	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
1855169699Skan	  if (isnan (a)) a = COPYSIGN (0, a);
1856169699Skan	  if (isnan (b)) b = COPYSIGN (0, b);
1857169699Skan	  recalc = 1;
1858169699Skan	}
1859169699Skan     if (!recalc
1860169699Skan	  && (isinf (ac) || isinf (bd)
1861169699Skan	      || isinf (ad) || isinf (bc)))
1862169699Skan	{
1863169699Skan	  /* Recover infinities from overflow by changing NaNs to 0.  */
1864169699Skan	  if (isnan (a)) a = COPYSIGN (0, a);
1865169699Skan	  if (isnan (b)) b = COPYSIGN (0, b);
1866169699Skan	  if (isnan (c)) c = COPYSIGN (0, c);
1867169699Skan	  if (isnan (d)) d = COPYSIGN (0, d);
1868169699Skan	  recalc = 1;
1869169699Skan	}
1870169699Skan      if (recalc)
1871169699Skan	{
1872169699Skan	  x = INFINITY * (a * c - b * d);
1873169699Skan	  y = INFINITY * (a * d + b * c);
1874169699Skan	}
1875169699Skan    }
1876169699Skan
1877169699Skan  return x + I * y;
1878169699Skan}
1879169699Skan#endif /* complex multiply */
1880169699Skan
1881169699Skan#if defined(L_divsc3) || defined(L_divdc3) \
1882169699Skan    || defined(L_divxc3) || defined(L_divtc3)
1883169699Skan
1884169699SkanCTYPE
1885169699SkanCONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1886169699Skan{
1887169699Skan  MTYPE denom, ratio, x, y;
1888169699Skan
1889258428Spfg  /* ??? We can get better behavior from logarithmic scaling instead of
1890169699Skan     the division.  But that would mean starting to link libgcc against
1891169699Skan     libm.  We could implement something akin to ldexp/frexp as gcc builtins
1892169699Skan     fairly easily...  */
1893169699Skan  if (FABS (c) < FABS (d))
1894169699Skan    {
1895169699Skan      ratio = c / d;
1896169699Skan      denom = (c * ratio) + d;
1897169699Skan      x = ((a * ratio) + b) / denom;
1898169699Skan      y = ((b * ratio) - a) / denom;
1899169699Skan    }
1900169699Skan  else
1901169699Skan    {
1902169699Skan      ratio = d / c;
1903169699Skan      denom = (d * ratio) + c;
1904169699Skan      x = ((b * ratio) + a) / denom;
1905169699Skan      y = (b - (a * ratio)) / denom;
1906169699Skan    }
1907169699Skan
1908169699Skan  /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
1909169699Skan     are nonzero/zero, infinite/finite, and finite/infinite.  */
1910169699Skan  if (isnan (x) && isnan (y))
1911169699Skan    {
1912169699Skan      if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
1913169699Skan	{
1914169699Skan	  x = COPYSIGN (INFINITY, c) * a;
1915169699Skan	  y = COPYSIGN (INFINITY, c) * b;
1916169699Skan	}
1917169699Skan      else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
1918169699Skan	{
1919169699Skan	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
1920169699Skan	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
1921169699Skan	  x = INFINITY * (a * c + b * d);
1922169699Skan	  y = INFINITY * (b * c - a * d);
1923169699Skan	}
1924169699Skan      else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
1925169699Skan	{
1926169699Skan	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
1927169699Skan	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
1928169699Skan	  x = 0.0 * (a * c + b * d);
1929169699Skan	  y = 0.0 * (b * c - a * d);
1930169699Skan	}
1931169699Skan    }
1932169699Skan
1933169699Skan  return x + I * y;
1934169699Skan}
1935169699Skan#endif /* complex divide */
1936169699Skan
1937169699Skan#endif /* all complex float routines */
1938169699Skan
193918334Speter/* From here on down, the routines use normal data types.  */
194018334Speter
194118334Speter#define SItype bogus_type
194218334Speter#define USItype bogus_type
194318334Speter#define DItype bogus_type
194418334Speter#define UDItype bogus_type
194518334Speter#define SFtype bogus_type
194618334Speter#define DFtype bogus_type
194790280Sobrien#undef Wtype
194890280Sobrien#undef UWtype
194990280Sobrien#undef HWtype
195090280Sobrien#undef UHWtype
195190280Sobrien#undef DWtype
195290280Sobrien#undef UDWtype
195318334Speter
195418334Speter#undef char
195518334Speter#undef short
195618334Speter#undef int
195718334Speter#undef long
195818334Speter#undef unsigned
195918334Speter#undef float
196018334Speter#undef double
196118334Speter
196218334Speter#ifdef L__gcc_bcmp
196318334Speter
196418334Speter/* Like bcmp except the sign is meaningful.
196518334Speter   Result is negative if S1 is less than S2,
196618334Speter   positive if S1 is greater, 0 if S1 and S2 are equal.  */
196718334Speter
196818334Speterint
196990280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
197018334Speter{
197118334Speter  while (size > 0)
197218334Speter    {
1973132727Skan      const unsigned char c1 = *s1++, c2 = *s2++;
197418334Speter      if (c1 != c2)
197518334Speter	return c1 - c2;
197618334Speter      size--;
197718334Speter    }
197818334Speter  return 0;
197918334Speter}
198018334Speter
198118334Speter#endif
198218334Speter
198390280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>.
198490280Sobrien   We no longer provide that header, but this routine remains in libgcc.a
198590280Sobrien   for binary backward compatibility.  Note that it is not included in
198690280Sobrien   the shared version of libgcc.  */
198718334Speter#ifdef L_eprintf
198818334Speter#ifndef inhibit_libc
198918334Speter
199018334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
199118334Speter#include <stdio.h>
199252561Sobrien
199318334Spetervoid
199450600Sobrien__eprintf (const char *string, const char *expression,
199550600Sobrien	   unsigned int line, const char *filename)
199618334Speter{
199718334Speter  fprintf (stderr, string, expression, line, filename);
199818334Speter  fflush (stderr);
199918334Speter  abort ();
200018334Speter}
200118334Speter
200218334Speter#endif
200318334Speter#endif
200418334Speter
200518334Speter
200618334Speter#ifdef L_clear_cache
200718334Speter/* Clear part of an instruction cache.  */
200818334Speter
200918334Spetervoid
2010261991Sdim__clear_cache (void *beg __attribute__((__unused__)),
2011261991Sdim	       void *end __attribute__((__unused__)))
201218334Speter{
201390280Sobrien#ifdef CLEAR_INSN_CACHE
201418334Speter  CLEAR_INSN_CACHE (beg, end);
201518334Speter#endif /* CLEAR_INSN_CACHE */
201618334Speter}
201718334Speter
201818334Speter#endif /* L_clear_cache */
201918334Speter
2020132727Skan#ifdef L_enable_execute_stack
2021132727Skan/* Attempt to turn on execute permission for the stack.  */
2022132727Skan
2023132727Skan#ifdef ENABLE_EXECUTE_STACK
2024132727Skan  ENABLE_EXECUTE_STACK
2025132727Skan#else
2026132727Skanvoid
2027132727Skan__enable_execute_stack (void *addr __attribute__((__unused__)))
2028132727Skan{}
2029132727Skan#endif /* ENABLE_EXECUTE_STACK */
2030132727Skan
2031132727Skan#endif /* L_enable_execute_stack */
2032132727Skan
203318334Speter#ifdef L_trampoline
203418334Speter
203518334Speter/* Jump to a trampoline, loading the static chain address.  */
203618334Speter
203752561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
203818334Speter
2039169699Skanint
204090280Sobriengetpagesize (void)
204118334Speter{
204218334Speter#ifdef _ALPHA_
204318334Speter  return 8192;
204418334Speter#else
204518334Speter  return 4096;
204618334Speter#endif
204718334Speter}
204818334Speter
204990280Sobrien#ifdef __i386__
205050600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
205150600Sobrien#endif
205250600Sobrien
205350600Sobrienint
205450600Sobrienmprotect (char *addr, int len, int prot)
205518334Speter{
205618334Speter  int np, op;
205718334Speter
205850600Sobrien  if (prot == 7)
205950600Sobrien    np = 0x40;
206050600Sobrien  else if (prot == 5)
206150600Sobrien    np = 0x20;
206250600Sobrien  else if (prot == 4)
206350600Sobrien    np = 0x10;
206450600Sobrien  else if (prot == 3)
206550600Sobrien    np = 0x04;
206650600Sobrien  else if (prot == 1)
206750600Sobrien    np = 0x02;
206850600Sobrien  else if (prot == 0)
206950600Sobrien    np = 0x01;
207018334Speter
207118334Speter  if (VirtualProtect (addr, len, np, &op))
207218334Speter    return 0;
207318334Speter  else
207418334Speter    return -1;
207518334Speter}
207618334Speter
207752561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
207818334Speter
207990280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE
208090280SobrienTRANSFER_FROM_TRAMPOLINE
208118334Speter#endif
208218334Speter#endif /* L_trampoline */
208318334Speter
208452561Sobrien#ifndef __CYGWIN__
208518334Speter#ifdef L__main
208618334Speter
208718334Speter#include "gbl-ctors.h"
2088169699Skan
208918334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these
209018334Speter   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
209118334Speter   give the same symbol without quotes for an alternative entry point.  You
209250600Sobrien   must define both, or neither.  */
209318334Speter#ifndef NAME__MAIN
209418334Speter#define NAME__MAIN "__main"
209518334Speter#define SYMBOL__MAIN __main
209618334Speter#endif
209718334Speter
2098169699Skan#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP)
209950600Sobrien#undef HAS_INIT_SECTION
210050600Sobrien#define HAS_INIT_SECTION
210150600Sobrien#endif
210250600Sobrien
210350600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
210490280Sobrien
210590280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
210690280Sobrien   code to run constructors.  In that case, we need to handle EH here, too.  */
210790280Sobrien
210890280Sobrien#ifdef EH_FRAME_SECTION_NAME
210990280Sobrien#include "unwind-dw2-fde.h"
211090280Sobrienextern unsigned char __EH_FRAME_BEGIN__[];
211190280Sobrien#endif
211290280Sobrien
211318334Speter/* Run all the global destructors on exit from the program.  */
211418334Speter
211518334Spetervoid
211690280Sobrien__do_global_dtors (void)
211718334Speter{
211818334Speter#ifdef DO_GLOBAL_DTORS_BODY
211918334Speter  DO_GLOBAL_DTORS_BODY;
212018334Speter#else
212150600Sobrien  static func_ptr *p = __DTOR_LIST__ + 1;
212250600Sobrien  while (*p)
212350600Sobrien    {
212450600Sobrien      p++;
212550600Sobrien      (*(p-1)) ();
212650600Sobrien    }
212718334Speter#endif
212890280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
212990280Sobrien  {
213090280Sobrien    static int completed = 0;
213190280Sobrien    if (! completed)
213290280Sobrien      {
213390280Sobrien	completed = 1;
213490280Sobrien	__deregister_frame_info (__EH_FRAME_BEGIN__);
213590280Sobrien      }
213690280Sobrien  }
213790280Sobrien#endif
213818334Speter}
213950600Sobrien#endif
214018334Speter
214150600Sobrien#ifndef HAS_INIT_SECTION
214218334Speter/* Run all the global constructors on entry to the program.  */
214318334Speter
214418334Spetervoid
214590280Sobrien__do_global_ctors (void)
214618334Speter{
214790280Sobrien#ifdef EH_FRAME_SECTION_NAME
214890280Sobrien  {
214990280Sobrien    static struct object object;
215090280Sobrien    __register_frame_info (__EH_FRAME_BEGIN__, &object);
215190280Sobrien  }
215290280Sobrien#endif
215318334Speter  DO_GLOBAL_CTORS_BODY;
215490280Sobrien  atexit (__do_global_dtors);
215518334Speter}
215650600Sobrien#endif /* no HAS_INIT_SECTION */
215718334Speter
215850600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
215918334Speter/* Subroutine called automatically by `main'.
216018334Speter   Compiling a global function named `main'
216118334Speter   produces an automatic call to this function at the beginning.
216218334Speter
216318334Speter   For many systems, this routine calls __do_global_ctors.
216418334Speter   For systems which support a .init section we use the .init section
216518334Speter   to run __do_global_ctors, so we need not do anything here.  */
216618334Speter
2167132727Skanextern void SYMBOL__MAIN (void);
216818334Spetervoid
2169132727SkanSYMBOL__MAIN (void)
217018334Speter{
217118334Speter  /* Support recursive calls to `main': run initializers just once.  */
217218334Speter  static int initialized;
217318334Speter  if (! initialized)
217418334Speter    {
217518334Speter      initialized = 1;
217618334Speter      __do_global_ctors ();
217718334Speter    }
217818334Speter}
217950600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */
218018334Speter
218118334Speter#endif /* L__main */
218252561Sobrien#endif /* __CYGWIN__ */
218318334Speter
218418334Speter#ifdef L_ctors
218518334Speter
218618334Speter#include "gbl-ctors.h"
218718334Speter
218818334Speter/* Provide default definitions for the lists of constructors and
218918334Speter   destructors, so that we don't get linker errors.  These symbols are
219018334Speter   intentionally bss symbols, so that gld and/or collect will provide
219118334Speter   the right values.  */
219218334Speter
219318334Speter/* We declare the lists here with two elements each,
219452561Sobrien   so that they are valid empty lists if no other definition is loaded.
219552561Sobrien
219652561Sobrien   If we are using the old "set" extensions to have the gnu linker
219752561Sobrien   collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
219852561Sobrien   must be in the bss/common section.
219952561Sobrien
220052561Sobrien   Long term no port should use those extensions.  But many still do.  */
220150600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
220290280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
220318334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0};
220418334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0};
220518334Speter#else
220618334Speterfunc_ptr __CTOR_LIST__[2];
220718334Speterfunc_ptr __DTOR_LIST__[2];
220818334Speter#endif
220918334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
221018334Speter#endif /* L_ctors */
2211169699Skan#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */
2212