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
495132727Skan#ifdef L_ffssi2
496132727Skan#undef int
497132727Skanint
498132727Skan__ffsSI2 (UWtype u)
499132727Skan{
500132727Skan  UWtype count;
501132727Skan
502132727Skan  if (u == 0)
503132727Skan    return 0;
504132727Skan
505132727Skan  count_trailing_zeros (count, u);
506132727Skan  return count + 1;
507132727Skan}
508132727Skan#endif
509132727Skan
51018334Speter#ifdef L_ffsdi2
511132727Skan#undef int
512132727Skanint
513132727Skan__ffsDI2 (DWtype u)
51418334Speter{
515132727Skan  const DWunion uu = {.ll = u};
51690280Sobrien  UWtype word, count, add;
51790280Sobrien
51890280Sobrien  if (uu.s.low != 0)
51990280Sobrien    word = uu.s.low, add = 0;
52090280Sobrien  else if (uu.s.high != 0)
52190280Sobrien    word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
52290280Sobrien  else
52390280Sobrien    return 0;
52490280Sobrien
52590280Sobrien  count_trailing_zeros (count, word);
52690280Sobrien  return count + add + 1;
52718334Speter}
52818334Speter#endif
52918334Speter
53018334Speter#ifdef L_muldi3
53190280SobrienDWtype
53290280Sobrien__muldi3 (DWtype u, DWtype v)
53318334Speter{
534132727Skan  const DWunion uu = {.ll = u};
535132727Skan  const DWunion vv = {.ll = v};
536132727Skan  DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
53718334Speter
53890280Sobrien  w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
53990280Sobrien	       + (UWtype) uu.s.high * (UWtype) vv.s.low);
54018334Speter
54118334Speter  return w.ll;
54218334Speter}
54318334Speter#endif
54418334Speter
545117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
546117404Skan     defined (L_umoddi3) || defined (L_moddi3))
547117404Skan#if defined (sdiv_qrnnd)
548117404Skan#define L_udiv_w_sdiv
549117404Skan#endif
550117404Skan#endif
551117404Skan
55218334Speter#ifdef L_udiv_w_sdiv
55318334Speter#if defined (sdiv_qrnnd)
554117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \
555117404Skan     defined (L_umoddi3) || defined (L_moddi3))
556117404Skanstatic inline __attribute__ ((__always_inline__))
557117404Skan#endif
55890280SobrienUWtype
55990280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
56018334Speter{
56190280Sobrien  UWtype q, r;
56290280Sobrien  UWtype c0, c1, b1;
56318334Speter
56490280Sobrien  if ((Wtype) d >= 0)
56518334Speter    {
56690280Sobrien      if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
56718334Speter	{
568169699Skan	  /* Dividend, divisor, and quotient are nonnegative.  */
56918334Speter	  sdiv_qrnnd (q, r, a1, a0, d);
57018334Speter	}
57118334Speter      else
57218334Speter	{
573169699Skan	  /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d.  */
57490280Sobrien	  sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
575169699Skan	  /* Divide (c1*2^32 + c0) by d.  */
57618334Speter	  sdiv_qrnnd (q, r, c1, c0, d);
577169699Skan	  /* Add 2^31 to quotient.  */
57890280Sobrien	  q += (UWtype) 1 << (W_TYPE_SIZE - 1);
57918334Speter	}
58018334Speter    }
58118334Speter  else
58218334Speter    {
58318334Speter      b1 = d >> 1;			/* d/2, between 2^30 and 2^31 - 1 */
58418334Speter      c1 = a1 >> 1;			/* A/2 */
58590280Sobrien      c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
58618334Speter
58718334Speter      if (a1 < b1)			/* A < 2^32*b1, so A/2 < 2^31*b1 */
58818334Speter	{
58918334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
59018334Speter
59118334Speter	  r = 2*r + (a0 & 1);		/* Remainder from A/(2*b1) */
59218334Speter	  if ((d & 1) != 0)
59318334Speter	    {
59418334Speter	      if (r >= q)
59518334Speter		r = r - q;
59618334Speter	      else if (q - r <= d)
59718334Speter		{
59818334Speter		  r = r - q + d;
59918334Speter		  q--;
60018334Speter		}
60118334Speter	      else
60218334Speter		{
60318334Speter		  r = r - q + 2*d;
60418334Speter		  q -= 2;
60518334Speter		}
60618334Speter	    }
60718334Speter	}
60818334Speter      else if (c1 < b1)			/* So 2^31 <= (A/2)/b1 < 2^32 */
60918334Speter	{
61018334Speter	  c1 = (b1 - 1) - c1;
61118334Speter	  c0 = ~c0;			/* logical NOT */
61218334Speter
61318334Speter	  sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
61418334Speter
61518334Speter	  q = ~q;			/* (A/2)/b1 */
61618334Speter	  r = (b1 - 1) - r;
61718334Speter
61818334Speter	  r = 2*r + (a0 & 1);		/* A/(2*b1) */
61918334Speter
62018334Speter	  if ((d & 1) != 0)
62118334Speter	    {
62218334Speter	      if (r >= q)
62318334Speter		r = r - q;
62418334Speter	      else if (q - r <= d)
62518334Speter		{
62618334Speter		  r = r - q + d;
62718334Speter		  q--;
62818334Speter		}
62918334Speter	      else
63018334Speter		{
63118334Speter		  r = r - q + 2*d;
63218334Speter		  q -= 2;
63318334Speter		}
63418334Speter	    }
63518334Speter	}
63618334Speter      else				/* Implies c1 = b1 */
63718334Speter	{				/* Hence a1 = d - 1 = 2*b1 - 1 */
63818334Speter	  if (a0 >= -d)
63918334Speter	    {
64018334Speter	      q = -1;
64118334Speter	      r = a0 + d;
64218334Speter	    }
64318334Speter	  else
64418334Speter	    {
64518334Speter	      q = -2;
64618334Speter	      r = a0 + 2*d;
64718334Speter	    }
64818334Speter	}
64918334Speter    }
65018334Speter
65118334Speter  *rp = r;
65218334Speter  return q;
65318334Speter}
65418334Speter#else
65518334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
65690280SobrienUWtype
65790280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
65890280Sobrien	       UWtype a1 __attribute__ ((__unused__)),
65990280Sobrien	       UWtype a0 __attribute__ ((__unused__)),
66090280Sobrien	       UWtype d __attribute__ ((__unused__)))
66150600Sobrien{
66250600Sobrien  return 0;
66350600Sobrien}
66418334Speter#endif
66518334Speter#endif
66618334Speter
66718334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
66818334Speter     defined (L_umoddi3) || defined (L_moddi3))
66918334Speter#define L_udivmoddi4
67018334Speter#endif
67118334Speter
67290280Sobrien#ifdef L_clz
673169699Skanconst UQItype __clz_tab[256] =
67418334Speter{
67518334Speter  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,
67618334Speter  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,
67718334Speter  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,
67818334Speter  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,
67918334Speter  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,
68018334Speter  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,
68118334Speter  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,
682169699Skan  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
68318334Speter};
68490280Sobrien#endif
685132727Skan
686132727Skan#ifdef L_clzsi2
687132727Skan#undef int
688132727Skanint
689132727Skan__clzSI2 (UWtype x)
690132727Skan{
691132727Skan  Wtype ret;
69218334Speter
693132727Skan  count_leading_zeros (ret, x);
694132727Skan
695132727Skan  return ret;
696132727Skan}
697132727Skan#endif
698132727Skan
699132727Skan#ifdef L_clzdi2
700132727Skan#undef int
701132727Skanint
702132727Skan__clzDI2 (UDWtype x)
703132727Skan{
704132727Skan  const DWunion uu = {.ll = x};
705132727Skan  UWtype word;
706132727Skan  Wtype ret, add;
707132727Skan
708132727Skan  if (uu.s.high)
709132727Skan    word = uu.s.high, add = 0;
710132727Skan  else
711132727Skan    word = uu.s.low, add = W_TYPE_SIZE;
712132727Skan
713132727Skan  count_leading_zeros (ret, word);
714132727Skan  return ret + add;
715132727Skan}
716132727Skan#endif
717132727Skan
718132727Skan#ifdef L_ctzsi2
719132727Skan#undef int
720132727Skanint
721132727Skan__ctzSI2 (UWtype x)
722132727Skan{
723132727Skan  Wtype ret;
724132727Skan
725132727Skan  count_trailing_zeros (ret, x);
726132727Skan
727132727Skan  return ret;
728132727Skan}
729132727Skan#endif
730132727Skan
731132727Skan#ifdef L_ctzdi2
732132727Skan#undef int
733132727Skanint
734132727Skan__ctzDI2 (UDWtype x)
735132727Skan{
736132727Skan  const DWunion uu = {.ll = x};
737132727Skan  UWtype word;
738132727Skan  Wtype ret, add;
739132727Skan
740132727Skan  if (uu.s.low)
741132727Skan    word = uu.s.low, add = 0;
742132727Skan  else
743132727Skan    word = uu.s.high, add = W_TYPE_SIZE;
744132727Skan
745132727Skan  count_trailing_zeros (ret, word);
746132727Skan  return ret + add;
747132727Skan}
748132727Skan#endif
749132727Skan
750132727Skan#ifdef L_popcount_tab
751169699Skanconst UQItype __popcount_tab[256] =
752132727Skan{
753132727Skan    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,
754132727Skan    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,
755132727Skan    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,
756132727Skan    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,
757132727Skan    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,
758132727Skan    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,
759132727Skan    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,
760169699Skan    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
761132727Skan};
762132727Skan#endif
763132727Skan
764132727Skan#ifdef L_popcountsi2
765132727Skan#undef int
766132727Skanint
767132727Skan__popcountSI2 (UWtype x)
768132727Skan{
769169699Skan  int i, ret = 0;
770132727Skan
771132727Skan  for (i = 0; i < W_TYPE_SIZE; i += 8)
772132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
773132727Skan
774132727Skan  return ret;
775132727Skan}
776132727Skan#endif
777132727Skan
778132727Skan#ifdef L_popcountdi2
779132727Skan#undef int
780132727Skanint
781132727Skan__popcountDI2 (UDWtype x)
782132727Skan{
783169699Skan  int i, ret = 0;
784132727Skan
785132727Skan  for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
786132727Skan    ret += __popcount_tab[(x >> i) & 0xff];
787132727Skan
788132727Skan  return ret;
789132727Skan}
790132727Skan#endif
791132727Skan
792132727Skan#ifdef L_paritysi2
793132727Skan#undef int
794132727Skanint
795132727Skan__paritySI2 (UWtype x)
796132727Skan{
797132727Skan#if W_TYPE_SIZE > 64
798132727Skan# error "fill out the table"
799132727Skan#endif
800132727Skan#if W_TYPE_SIZE > 32
801132727Skan  x ^= x >> 32;
802132727Skan#endif
803132727Skan#if W_TYPE_SIZE > 16
804132727Skan  x ^= x >> 16;
805132727Skan#endif
806132727Skan  x ^= x >> 8;
807132727Skan  x ^= x >> 4;
808132727Skan  x &= 0xf;
809132727Skan  return (0x6996 >> x) & 1;
810132727Skan}
811132727Skan#endif
812132727Skan
813132727Skan#ifdef L_paritydi2
814132727Skan#undef int
815132727Skanint
816132727Skan__parityDI2 (UDWtype x)
817132727Skan{
818132727Skan  const DWunion uu = {.ll = x};
819132727Skan  UWtype nx = uu.s.low ^ uu.s.high;
820132727Skan
821132727Skan#if W_TYPE_SIZE > 64
822132727Skan# error "fill out the table"
823132727Skan#endif
824132727Skan#if W_TYPE_SIZE > 32
825132727Skan  nx ^= nx >> 32;
826132727Skan#endif
827132727Skan#if W_TYPE_SIZE > 16
828132727Skan  nx ^= nx >> 16;
829132727Skan#endif
830132727Skan  nx ^= nx >> 8;
831132727Skan  nx ^= nx >> 4;
832132727Skan  nx &= 0xf;
833132727Skan  return (0x6996 >> nx) & 1;
834132727Skan}
835132727Skan#endif
836132727Skan
83790280Sobrien#ifdef L_udivmoddi4
83890280Sobrien
83918334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \
84018334Speter     defined (L_umoddi3) || defined (L_moddi3))
841117404Skanstatic inline __attribute__ ((__always_inline__))
84218334Speter#endif
84390280SobrienUDWtype
84490280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
84518334Speter{
846132727Skan  const DWunion nn = {.ll = n};
847132727Skan  const DWunion dd = {.ll = d};
84890280Sobrien  DWunion rr;
84990280Sobrien  UWtype d0, d1, n0, n1, n2;
85090280Sobrien  UWtype q0, q1;
85190280Sobrien  UWtype b, bm;
85218334Speter
85318334Speter  d0 = dd.s.low;
85418334Speter  d1 = dd.s.high;
85518334Speter  n0 = nn.s.low;
85618334Speter  n1 = nn.s.high;
85718334Speter
85818334Speter#if !UDIV_NEEDS_NORMALIZATION
85918334Speter  if (d1 == 0)
86018334Speter    {
86118334Speter      if (d0 > n1)
86218334Speter	{
86318334Speter	  /* 0q = nn / 0D */
86418334Speter
86518334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
86618334Speter	  q1 = 0;
86718334Speter
86818334Speter	  /* Remainder in n0.  */
86918334Speter	}
87018334Speter      else
87118334Speter	{
87218334Speter	  /* qq = NN / 0d */
87318334Speter
87418334Speter	  if (d0 == 0)
87518334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
87618334Speter
87718334Speter	  udiv_qrnnd (q1, n1, 0, n1, d0);
87818334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
87918334Speter
88018334Speter	  /* Remainder in n0.  */
88118334Speter	}
88218334Speter
88318334Speter      if (rp != 0)
88418334Speter	{
88518334Speter	  rr.s.low = n0;
88618334Speter	  rr.s.high = 0;
88718334Speter	  *rp = rr.ll;
88818334Speter	}
88918334Speter    }
89018334Speter
89118334Speter#else /* UDIV_NEEDS_NORMALIZATION */
89218334Speter
89318334Speter  if (d1 == 0)
89418334Speter    {
89518334Speter      if (d0 > n1)
89618334Speter	{
89718334Speter	  /* 0q = nn / 0D */
89818334Speter
89918334Speter	  count_leading_zeros (bm, d0);
90018334Speter
90118334Speter	  if (bm != 0)
90218334Speter	    {
90318334Speter	      /* Normalize, i.e. make the most significant bit of the
90418334Speter		 denominator set.  */
90518334Speter
90618334Speter	      d0 = d0 << bm;
90790280Sobrien	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
90818334Speter	      n0 = n0 << bm;
90918334Speter	    }
91018334Speter
91118334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
91218334Speter	  q1 = 0;
91318334Speter
91418334Speter	  /* Remainder in n0 >> bm.  */
91518334Speter	}
91618334Speter      else
91718334Speter	{
91818334Speter	  /* qq = NN / 0d */
91918334Speter
92018334Speter	  if (d0 == 0)
92118334Speter	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
92218334Speter
92318334Speter	  count_leading_zeros (bm, d0);
92418334Speter
92518334Speter	  if (bm == 0)
92618334Speter	    {
92718334Speter	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
92818334Speter		 conclude (the most significant bit of n1 is set) /\ (the
92918334Speter		 leading quotient digit q1 = 1).
93018334Speter
93118334Speter		 This special case is necessary, not an optimization.
93290280Sobrien		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
93318334Speter
93418334Speter	      n1 -= d0;
93518334Speter	      q1 = 1;
93618334Speter	    }
93718334Speter	  else
93818334Speter	    {
93918334Speter	      /* Normalize.  */
94018334Speter
94190280Sobrien	      b = W_TYPE_SIZE - bm;
94218334Speter
94318334Speter	      d0 = d0 << bm;
94418334Speter	      n2 = n1 >> b;
94518334Speter	      n1 = (n1 << bm) | (n0 >> b);
94618334Speter	      n0 = n0 << bm;
94718334Speter
94818334Speter	      udiv_qrnnd (q1, n1, n2, n1, d0);
94918334Speter	    }
95018334Speter
95150600Sobrien	  /* n1 != d0...  */
95218334Speter
95318334Speter	  udiv_qrnnd (q0, n0, n1, n0, d0);
95418334Speter
95518334Speter	  /* Remainder in n0 >> bm.  */
95618334Speter	}
95718334Speter
95818334Speter      if (rp != 0)
95918334Speter	{
96018334Speter	  rr.s.low = n0 >> bm;
96118334Speter	  rr.s.high = 0;
96218334Speter	  *rp = rr.ll;
96318334Speter	}
96418334Speter    }
96518334Speter#endif /* UDIV_NEEDS_NORMALIZATION */
96618334Speter
96718334Speter  else
96818334Speter    {
96918334Speter      if (d1 > n1)
97018334Speter	{
97118334Speter	  /* 00 = nn / DD */
97218334Speter
97318334Speter	  q0 = 0;
97418334Speter	  q1 = 0;
97518334Speter
97618334Speter	  /* Remainder in n1n0.  */
97718334Speter	  if (rp != 0)
97818334Speter	    {
97918334Speter	      rr.s.low = n0;
98018334Speter	      rr.s.high = n1;
98118334Speter	      *rp = rr.ll;
98218334Speter	    }
98318334Speter	}
98418334Speter      else
98518334Speter	{
98618334Speter	  /* 0q = NN / dd */
98718334Speter
98818334Speter	  count_leading_zeros (bm, d1);
98918334Speter	  if (bm == 0)
99018334Speter	    {
99118334Speter	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
99218334Speter		 conclude (the most significant bit of n1 is set) /\ (the
99318334Speter		 quotient digit q0 = 0 or 1).
99418334Speter
99518334Speter		 This special case is necessary, not an optimization.  */
99618334Speter
99718334Speter	      /* The condition on the next line takes advantage of that
99818334Speter		 n1 >= d1 (true due to program flow).  */
99918334Speter	      if (n1 > d1 || n0 >= d0)
100018334Speter		{
100118334Speter		  q0 = 1;
100218334Speter		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
100318334Speter		}
100418334Speter	      else
100518334Speter		q0 = 0;
100618334Speter
100718334Speter	      q1 = 0;
100818334Speter
100918334Speter	      if (rp != 0)
101018334Speter		{
101118334Speter		  rr.s.low = n0;
101218334Speter		  rr.s.high = n1;
101318334Speter		  *rp = rr.ll;
101418334Speter		}
101518334Speter	    }
101618334Speter	  else
101718334Speter	    {
101890280Sobrien	      UWtype m1, m0;
101918334Speter	      /* Normalize.  */
102018334Speter
102190280Sobrien	      b = W_TYPE_SIZE - bm;
102218334Speter
102318334Speter	      d1 = (d1 << bm) | (d0 >> b);
102418334Speter	      d0 = d0 << bm;
102518334Speter	      n2 = n1 >> b;
102618334Speter	      n1 = (n1 << bm) | (n0 >> b);
102718334Speter	      n0 = n0 << bm;
102818334Speter
102918334Speter	      udiv_qrnnd (q0, n1, n2, n1, d1);
103018334Speter	      umul_ppmm (m1, m0, q0, d0);
103118334Speter
103218334Speter	      if (m1 > n1 || (m1 == n1 && m0 > n0))
103318334Speter		{
103418334Speter		  q0--;
103518334Speter		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
103618334Speter		}
103718334Speter
103818334Speter	      q1 = 0;
103918334Speter
104018334Speter	      /* Remainder in (n1n0 - m1m0) >> bm.  */
104118334Speter	      if (rp != 0)
104218334Speter		{
104318334Speter		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
104418334Speter		  rr.s.low = (n1 << b) | (n0 >> bm);
104518334Speter		  rr.s.high = n1 >> bm;
104618334Speter		  *rp = rr.ll;
104718334Speter		}
104818334Speter	    }
104918334Speter	}
105018334Speter    }
105118334Speter
1052132727Skan  const DWunion ww = {{.low = q0, .high = q1}};
105318334Speter  return ww.ll;
105418334Speter}
105518334Speter#endif
105618334Speter
105718334Speter#ifdef L_divdi3
105890280SobrienDWtype
105990280Sobrien__divdi3 (DWtype u, DWtype v)
106018334Speter{
106118334Speter  word_type c = 0;
1062132727Skan  DWunion uu = {.ll = u};
1063132727Skan  DWunion vv = {.ll = v};
106490280Sobrien  DWtype w;
106518334Speter
106618334Speter  if (uu.s.high < 0)
106718334Speter    c = ~c,
1068117404Skan    uu.ll = -uu.ll;
106918334Speter  if (vv.s.high < 0)
107018334Speter    c = ~c,
1071117404Skan    vv.ll = -vv.ll;
107218334Speter
107390280Sobrien  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
107418334Speter  if (c)
1075117404Skan    w = -w;
107618334Speter
107718334Speter  return w;
107818334Speter}
107918334Speter#endif
108018334Speter
108118334Speter#ifdef L_moddi3
108290280SobrienDWtype
108390280Sobrien__moddi3 (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)
1094117404Skan    vv.ll = -vv.ll;
109518334Speter
1096169699Skan  (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
109718334Speter  if (c)
1098117404Skan    w = -w;
109918334Speter
110018334Speter  return w;
110118334Speter}
110218334Speter#endif
110318334Speter
110418334Speter#ifdef L_umoddi3
110590280SobrienUDWtype
110690280Sobrien__umoddi3 (UDWtype u, UDWtype v)
110718334Speter{
110890280Sobrien  UDWtype w;
110918334Speter
111018334Speter  (void) __udivmoddi4 (u, v, &w);
111118334Speter
111218334Speter  return w;
111318334Speter}
111418334Speter#endif
111518334Speter
111618334Speter#ifdef L_udivdi3
111790280SobrienUDWtype
111890280Sobrien__udivdi3 (UDWtype n, UDWtype d)
111918334Speter{
112090280Sobrien  return __udivmoddi4 (n, d, (UDWtype *) 0);
112118334Speter}
112218334Speter#endif
112318334Speter
112418334Speter#ifdef L_cmpdi2
112518334Speterword_type
112690280Sobrien__cmpdi2 (DWtype a, DWtype b)
112718334Speter{
1128132727Skan  const DWunion au = {.ll = a};
1129132727Skan  const DWunion bu = {.ll = b};
113018334Speter
113118334Speter  if (au.s.high < bu.s.high)
113218334Speter    return 0;
113318334Speter  else if (au.s.high > bu.s.high)
113418334Speter    return 2;
113590280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
113618334Speter    return 0;
113790280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
113818334Speter    return 2;
113918334Speter  return 1;
114018334Speter}
114118334Speter#endif
114218334Speter
114318334Speter#ifdef L_ucmpdi2
114418334Speterword_type
114590280Sobrien__ucmpdi2 (DWtype a, DWtype b)
114618334Speter{
1147132727Skan  const DWunion au = {.ll = a};
1148132727Skan  const DWunion bu = {.ll = b};
114918334Speter
115090280Sobrien  if ((UWtype) au.s.high < (UWtype) bu.s.high)
115118334Speter    return 0;
115290280Sobrien  else if ((UWtype) au.s.high > (UWtype) bu.s.high)
115318334Speter    return 2;
115490280Sobrien  if ((UWtype) au.s.low < (UWtype) bu.s.low)
115518334Speter    return 0;
115690280Sobrien  else if ((UWtype) au.s.low > (UWtype) bu.s.low)
115718334Speter    return 2;
115818334Speter  return 1;
115918334Speter}
116018334Speter#endif
116118334Speter
1162169699Skan#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
116390280SobrienDWtype
116490280Sobrien__fixunstfDI (TFtype a)
116518334Speter{
116618334Speter  if (a < 0)
116718334Speter    return 0;
116818334Speter
116918334Speter  /* Compute high word of result, as a flonum.  */
1170169699Skan  const TFtype b = (a / Wtype_MAXp1_F);
117190280Sobrien  /* Convert that to fixed (but not to DWtype!),
117218334Speter     and shift it into the high word.  */
1173132727Skan  UDWtype v = (UWtype) b;
1174169699Skan  v <<= W_TYPE_SIZE;
117518334Speter  /* Remove high part from the TFtype, leaving the low part as flonum.  */
117618334Speter  a -= (TFtype)v;
117790280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
117818334Speter     Sometimes A comes out negative.  This is significant, since
117918334Speter     A has more bits than a long int does.  */
118018334Speter  if (a < 0)
118190280Sobrien    v -= (UWtype) (- a);
118218334Speter  else
118390280Sobrien    v += (UWtype) a;
118418334Speter  return v;
118518334Speter}
118618334Speter#endif
118718334Speter
1188169699Skan#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
118990280SobrienDWtype
119050600Sobrien__fixtfdi (TFtype a)
119118334Speter{
119218334Speter  if (a < 0)
119390280Sobrien    return - __fixunstfDI (-a);
119490280Sobrien  return __fixunstfDI (a);
119518334Speter}
119618334Speter#endif
119718334Speter
1198169699Skan#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
119990280SobrienDWtype
120090280Sobrien__fixunsxfDI (XFtype a)
120118334Speter{
120218334Speter  if (a < 0)
120318334Speter    return 0;
120418334Speter
120518334Speter  /* Compute high word of result, as a flonum.  */
1206169699Skan  const XFtype b = (a / Wtype_MAXp1_F);
120790280Sobrien  /* Convert that to fixed (but not to DWtype!),
120818334Speter     and shift it into the high word.  */
1209132727Skan  UDWtype v = (UWtype) b;
1210169699Skan  v <<= W_TYPE_SIZE;
121118334Speter  /* Remove high part from the XFtype, leaving the low part as flonum.  */
121218334Speter  a -= (XFtype)v;
121390280Sobrien  /* Convert that to fixed (but not to DWtype!) and add it in.
121418334Speter     Sometimes A comes out negative.  This is significant, since
121518334Speter     A has more bits than a long int does.  */
121618334Speter  if (a < 0)
121790280Sobrien    v -= (UWtype) (- a);
121818334Speter  else
121990280Sobrien    v += (UWtype) a;
122018334Speter  return v;
122118334Speter}
122218334Speter#endif
122318334Speter
1224169699Skan#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
122590280SobrienDWtype
122650600Sobrien__fixxfdi (XFtype a)
122718334Speter{
122818334Speter  if (a < 0)
122990280Sobrien    return - __fixunsxfDI (-a);
123090280Sobrien  return __fixunsxfDI (a);
123118334Speter}
123218334Speter#endif
123318334Speter
1234169699Skan#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
123590280SobrienDWtype
123690280Sobrien__fixunsdfDI (DFtype a)
123718334Speter{
1238132727Skan  /* Get high part of result.  The division here will just moves the radix
1239132727Skan     point and will not cause any rounding.  Then the conversion to integral
1240132727Skan     type chops result as desired.  */
1241169699Skan  const UWtype hi = a / Wtype_MAXp1_F;
124218334Speter
1243132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1244132727Skan     then subtract this from the number being converted.  This leaves the low
1245132727Skan     part.  Convert that to integral type.  */
1246169699Skan  const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
124718334Speter
1248132727Skan  /* Assemble result from the two parts.  */
1249169699Skan  return ((UDWtype) hi << W_TYPE_SIZE) | lo;
125018334Speter}
125118334Speter#endif
125218334Speter
1253169699Skan#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
125490280SobrienDWtype
125550600Sobrien__fixdfdi (DFtype a)
125618334Speter{
125718334Speter  if (a < 0)
125890280Sobrien    return - __fixunsdfDI (-a);
125990280Sobrien  return __fixunsdfDI (a);
126018334Speter}
126118334Speter#endif
126218334Speter
1263169699Skan#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE
126490280SobrienDWtype
1265169699Skan__fixunssfDI (SFtype a)
126618334Speter{
1267169699Skan#if LIBGCC2_HAS_DF_MODE
126818334Speter  /* Convert the SFtype to a DFtype, because that is surely not going
126918334Speter     to lose any bits.  Some day someone else can write a faster version
127018334Speter     that avoids converting to DFtype, and verify it really works right.  */
1271169699Skan  const DFtype dfa = a;
127218334Speter
1273132727Skan  /* Get high part of result.  The division here will just moves the radix
1274132727Skan     point and will not cause any rounding.  Then the conversion to integral
1275132727Skan     type chops result as desired.  */
1276169699Skan  const UWtype hi = dfa / Wtype_MAXp1_F;
127718334Speter
1278132727Skan  /* Get low part of result.  Convert `hi' to floating type and scale it back,
1279132727Skan     then subtract this from the number being converted.  This leaves the low
1280132727Skan     part.  Convert that to integral type.  */
1281169699Skan  const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
1282132727Skan
1283132727Skan  /* Assemble result from the two parts.  */
1284169699Skan  return ((UDWtype) hi << W_TYPE_SIZE) | lo;
1285169699Skan#elif FLT_MANT_DIG < W_TYPE_SIZE
1286169699Skan  if (a < 1)
1287169699Skan    return 0;
1288169699Skan  if (a < Wtype_MAXp1_F)
1289169699Skan    return (UWtype)a;
1290169699Skan  if (a < Wtype_MAXp1_F * Wtype_MAXp1_F)
1291169699Skan    {
1292169699Skan      /* Since we know that there are fewer significant bits in the SFmode
1293169699Skan	 quantity than in a word, we know that we can convert out all the
1294169699Skan	 significant bits in one step, and thus avoid losing bits.  */
1295169699Skan
1296169699Skan      /* ??? This following loop essentially performs frexpf.  If we could
1297169699Skan	 use the real libm function, or poke at the actual bits of the fp
1298169699Skan	 format, it would be significantly faster.  */
1299169699Skan
1300169699Skan      UWtype shift = 0, counter;
1301169699Skan      SFtype msb;
1302169699Skan
1303169699Skan      a /= Wtype_MAXp1_F;
1304169699Skan      for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1)
1305169699Skan	{
1306169699Skan	  SFtype counterf = (UWtype)1 << counter;
1307169699Skan	  if (a >= counterf)
1308169699Skan	    {
1309169699Skan	      shift |= counter;
1310169699Skan	      a /= counterf;
1311169699Skan	    }
1312169699Skan	}
1313169699Skan
1314169699Skan      /* Rescale into the range of one word, extract the bits of that
1315169699Skan	 one word, and shift the result into position.  */
1316169699Skan      a *= Wtype_MAXp1_F;
1317169699Skan      counter = a;
1318169699Skan      return (DWtype)counter << shift;
1319169699Skan    }
1320169699Skan  return -1;
1321169699Skan#else
1322169699Skan# error
1323169699Skan#endif
132418334Speter}
132518334Speter#endif
132618334Speter
1327169699Skan#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE
132890280SobrienDWtype
132918334Speter__fixsfdi (SFtype a)
133018334Speter{
133118334Speter  if (a < 0)
133290280Sobrien    return - __fixunssfDI (-a);
133390280Sobrien  return __fixunssfDI (a);
133418334Speter}
133518334Speter#endif
133618334Speter
1337169699Skan#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
133818334SpeterXFtype
133990280Sobrien__floatdixf (DWtype u)
134018334Speter{
1341169699Skan#if W_TYPE_SIZE > XF_SIZE
1342169699Skan# error
1343169699Skan#endif
1344169699Skan  XFtype d = (Wtype) (u >> W_TYPE_SIZE);
1345169699Skan  d *= Wtype_MAXp1_F;
1346169699Skan  d += (UWtype)u;
1347169699Skan  return d;
1348169699Skan}
1349169699Skan#endif
135018334Speter
1351169699Skan#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE
1352169699SkanXFtype
1353169699Skan__floatundixf (UDWtype u)
1354169699Skan{
1355169699Skan#if W_TYPE_SIZE > XF_SIZE
1356169699Skan# error
1357169699Skan#endif
1358169699Skan  XFtype d = (UWtype) (u >> W_TYPE_SIZE);
1359169699Skan  d *= Wtype_MAXp1_F;
1360169699Skan  d += (UWtype)u;
136150600Sobrien  return d;
136218334Speter}
136318334Speter#endif
136418334Speter
1365169699Skan#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
136618334SpeterTFtype
136790280Sobrien__floatditf (DWtype u)
136818334Speter{
1369169699Skan#if W_TYPE_SIZE > TF_SIZE
1370169699Skan# error
1371169699Skan#endif
1372169699Skan  TFtype d = (Wtype) (u >> W_TYPE_SIZE);
1373169699Skan  d *= Wtype_MAXp1_F;
1374169699Skan  d += (UWtype)u;
1375169699Skan  return d;
1376169699Skan}
1377169699Skan#endif
137818334Speter
1379169699Skan#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE
1380169699SkanTFtype
1381169699Skan__floatunditf (UDWtype u)
1382169699Skan{
1383169699Skan#if W_TYPE_SIZE > TF_SIZE
1384169699Skan# error
1385169699Skan#endif
1386169699Skan  TFtype d = (UWtype) (u >> W_TYPE_SIZE);
1387169699Skan  d *= Wtype_MAXp1_F;
1388169699Skan  d += (UWtype)u;
138950600Sobrien  return d;
139018334Speter}
139118334Speter#endif
139218334Speter
1393169699Skan#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE)	\
1394169699Skan     || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
1395169699Skan#define DI_SIZE (W_TYPE_SIZE * 2)
1396169699Skan#define F_MODE_OK(SIZE) \
1397169699Skan  (SIZE < DI_SIZE							\
1398169699Skan   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
1399169699Skan   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
1400169699Skan      The conversion from long double to float suffers from double	\
1401169699Skan      rounding, because we convert via double.  In any case, the	\
1402169699Skan      fallback code is faster.  */					\
1403169699Skan   && !IS_IBM_EXTENDED (SIZE))
1404169699Skan#if defined(L_floatdisf)
1405169699Skan#define FUNC __floatdisf
1406169699Skan#define FSTYPE SFtype
1407169699Skan#define FSSIZE SF_SIZE
1408169699Skan#else
1409169699Skan#define FUNC __floatdidf
1410169699Skan#define FSTYPE DFtype
1411169699Skan#define FSSIZE DF_SIZE
1412169699Skan#endif
141318334Speter
1414169699SkanFSTYPE
1415169699SkanFUNC (DWtype u)
141618334Speter{
1417169699Skan#if FSSIZE >= W_TYPE_SIZE
1418169699Skan  /* When the word size is small, we never get any rounding error.  */
1419169699Skan  FSTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1420169699Skan  f *= Wtype_MAXp1_F;
1421169699Skan  f += (UWtype)u;
1422169699Skan  return f;
1423169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))	\
1424169699Skan     || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))	\
1425169699Skan     || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
142618334Speter
1427169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1428169699Skan# define FSIZE DF_SIZE
1429169699Skan# define FTYPE DFtype
1430169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1431169699Skan# define FSIZE XF_SIZE
1432169699Skan# define FTYPE XFtype
1433169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1434169699Skan# define FSIZE TF_SIZE
1435169699Skan# define FTYPE TFtype
1436169699Skan#else
1437169699Skan# error
1438169699Skan#endif
1439169699Skan
1440169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1441169699Skan
1442169699Skan  /* Protect against double-rounding error.
1443169699Skan     Represent any low-order bits, that might be truncated by a bit that
1444169699Skan     won't be lost.  The bit can go in anywhere below the rounding position
1445169699Skan     of the FSTYPE.  A fixed mask and bit position handles all usual
1446169699Skan     configurations.  */
1447169699Skan  if (! (- ((DWtype) 1 << FSIZE) < u
1448169699Skan	 && u < ((DWtype) 1 << FSIZE)))
1449169699Skan    {
1450169699Skan      if ((UDWtype) u & (REP_BIT - 1))
1451169699Skan	{
1452169699Skan	  u &= ~ (REP_BIT - 1);
1453169699Skan	  u |= REP_BIT;
1454169699Skan	}
1455169699Skan    }
1456169699Skan
1457169699Skan  /* Do the calculation in a wider type so that we don't lose any of
1458169699Skan     the precision of the high word while multiplying it.  */
1459169699Skan  FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1460169699Skan  f *= Wtype_MAXp1_F;
1461169699Skan  f += (UWtype)u;
1462169699Skan  return (FSTYPE) f;
1463169699Skan#else
1464169699Skan#if FSSIZE >= W_TYPE_SIZE - 2
1465169699Skan# error
1466169699Skan#endif
1467169699Skan  /* Finally, the word size is larger than the number of bits in the
1468169699Skan     required FSTYPE, and we've got no suitable wider type.  The only
1469169699Skan     way to avoid double rounding is to special case the
1470169699Skan     extraction.  */
1471169699Skan
1472169699Skan  /* If there are no high bits set, fall back to one conversion.  */
1473169699Skan  if ((Wtype)u == u)
1474169699Skan    return (FSTYPE)(Wtype)u;
1475169699Skan
1476169699Skan  /* Otherwise, find the power of two.  */
1477169699Skan  Wtype hi = u >> W_TYPE_SIZE;
1478169699Skan  if (hi < 0)
1479169699Skan    hi = -hi;
1480169699Skan
1481169699Skan  UWtype count, shift;
1482169699Skan  count_leading_zeros (count, hi);
1483169699Skan
1484169699Skan  /* No leading bits means u == minimum.  */
1485169699Skan  if (count == 0)
1486169699Skan    return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2));
1487169699Skan
1488169699Skan  shift = 1 + W_TYPE_SIZE - count;
1489169699Skan
1490169699Skan  /* Shift down the most significant bits.  */
1491169699Skan  hi = u >> shift;
1492169699Skan
1493169699Skan  /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
1494169699Skan  if (u & (((DWtype)1 << shift) - 1))
1495169699Skan    hi |= 1;
1496169699Skan
1497169699Skan  /* Convert the one word of data, and rescale.  */
1498169699Skan  FSTYPE f = hi;
1499169699Skan  f *= (UDWtype)1 << shift;
1500169699Skan  return f;
1501169699Skan#endif
150218334Speter}
150318334Speter#endif
150418334Speter
1505169699Skan#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE)	\
1506169699Skan     || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
1507169699Skan#define DI_SIZE (W_TYPE_SIZE * 2)
1508169699Skan#define F_MODE_OK(SIZE) \
1509169699Skan  (SIZE < DI_SIZE							\
1510169699Skan   && SIZE > (DI_SIZE - SIZE + FSSIZE)					\
1511169699Skan   /* Don't use IBM Extended Double TFmode for TI->SF calculations.	\
1512169699Skan      The conversion from long double to float suffers from double	\
1513169699Skan      rounding, because we convert via double.  In any case, the	\
1514169699Skan      fallback code is faster.  */					\
1515169699Skan   && !IS_IBM_EXTENDED (SIZE))
1516169699Skan#if defined(L_floatundisf)
1517169699Skan#define FUNC __floatundisf
1518169699Skan#define FSTYPE SFtype
1519169699Skan#define FSSIZE SF_SIZE
1520169699Skan#else
1521169699Skan#define FUNC __floatundidf
1522169699Skan#define FSTYPE DFtype
1523169699Skan#define FSSIZE DF_SIZE
1524169699Skan#endif
1525117404Skan
1526169699SkanFSTYPE
1527169699SkanFUNC (UDWtype u)
1528169699Skan{
1529169699Skan#if FSSIZE >= W_TYPE_SIZE
1530169699Skan  /* When the word size is small, we never get any rounding error.  */
1531169699Skan  FSTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1532169699Skan  f *= Wtype_MAXp1_F;
1533169699Skan  f += (UWtype)u;
1534169699Skan  return f;
1535169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))	\
1536169699Skan     || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))	\
1537169699Skan     || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
153818334Speter
1539169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1540169699Skan# define FSIZE DF_SIZE
1541169699Skan# define FTYPE DFtype
1542169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1543169699Skan# define FSIZE XF_SIZE
1544169699Skan# define FTYPE XFtype
1545169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1546169699Skan# define FSIZE TF_SIZE
1547169699Skan# define FTYPE TFtype
1548169699Skan#else
1549169699Skan# error
1550169699Skan#endif
1551169699Skan
1552169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1553169699Skan
155418334Speter  /* Protect against double-rounding error.
1555169699Skan     Represent any low-order bits, that might be truncated by a bit that
1556169699Skan     won't be lost.  The bit can go in anywhere below the rounding position
1557169699Skan     of the FSTYPE.  A fixed mask and bit position handles all usual
1558169699Skan     configurations.  */
1559169699Skan  if (u >= ((UDWtype) 1 << FSIZE))
156018334Speter    {
1561169699Skan      if ((UDWtype) u & (REP_BIT - 1))
156218334Speter	{
1563169699Skan	  u &= ~ (REP_BIT - 1);
1564169699Skan	  u |= REP_BIT;
156518334Speter	}
156618334Speter    }
156718334Speter
1568169699Skan  /* Do the calculation in a wider type so that we don't lose any of
1569169699Skan     the precision of the high word while multiplying it.  */
1570169699Skan  FTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1571169699Skan  f *= Wtype_MAXp1_F;
1572169699Skan  f += (UWtype)u;
1573169699Skan  return (FSTYPE) f;
1574169699Skan#else
1575169699Skan#if FSSIZE == W_TYPE_SIZE - 1
1576169699Skan# error
1577169699Skan#endif
1578169699Skan  /* Finally, the word size is larger than the number of bits in the
1579169699Skan     required FSTYPE, and we've got no suitable wider type.  The only
1580169699Skan     way to avoid double rounding is to special case the
1581169699Skan     extraction.  */
1582169699Skan
1583169699Skan  /* If there are no high bits set, fall back to one conversion.  */
1584169699Skan  if ((UWtype)u == u)
1585169699Skan    return (FSTYPE)(UWtype)u;
1586169699Skan
1587169699Skan  /* Otherwise, find the power of two.  */
1588169699Skan  UWtype hi = u >> W_TYPE_SIZE;
1589169699Skan
1590169699Skan  UWtype count, shift;
1591169699Skan  count_leading_zeros (count, hi);
1592169699Skan
1593169699Skan  shift = W_TYPE_SIZE - count;
1594169699Skan
1595169699Skan  /* Shift down the most significant bits.  */
1596169699Skan  hi = u >> shift;
1597169699Skan
1598169699Skan  /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
1599169699Skan  if (u & (((UDWtype)1 << shift) - 1))
1600169699Skan    hi |= 1;
1601169699Skan
1602169699Skan  /* Convert the one word of data, and rescale.  */
1603169699Skan  FSTYPE f = hi;
1604169699Skan  f *= (UDWtype)1 << shift;
1605169699Skan  return f;
1606169699Skan#endif
160718334Speter}
160818334Speter#endif
160918334Speter
1610169699Skan#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
161118334Speter/* Reenable the normal types, in case limits.h needs them.  */
161218334Speter#undef char
161318334Speter#undef short
161418334Speter#undef int
161518334Speter#undef long
161618334Speter#undef unsigned
161718334Speter#undef float
161818334Speter#undef double
161918334Speter#undef MIN
162018334Speter#undef MAX
162118334Speter#include <limits.h>
162218334Speter
162390280SobrienUWtype
162490280Sobrien__fixunsxfSI (XFtype a)
162518334Speter{
162690280Sobrien  if (a >= - (DFtype) Wtype_MIN)
162790280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
162890280Sobrien  return (Wtype) a;
162918334Speter}
163018334Speter#endif
163118334Speter
1632169699Skan#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
163318334Speter/* Reenable the normal types, in case limits.h needs them.  */
163418334Speter#undef char
163518334Speter#undef short
163618334Speter#undef int
163718334Speter#undef long
163818334Speter#undef unsigned
163918334Speter#undef float
164018334Speter#undef double
164118334Speter#undef MIN
164218334Speter#undef MAX
164318334Speter#include <limits.h>
164418334Speter
164590280SobrienUWtype
164690280Sobrien__fixunsdfSI (DFtype a)
164718334Speter{
164890280Sobrien  if (a >= - (DFtype) Wtype_MIN)
164990280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
165090280Sobrien  return (Wtype) a;
165118334Speter}
165218334Speter#endif
165318334Speter
1654169699Skan#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE
165518334Speter/* Reenable the normal types, in case limits.h needs them.  */
165618334Speter#undef char
165718334Speter#undef short
165818334Speter#undef int
165918334Speter#undef long
166018334Speter#undef unsigned
166118334Speter#undef float
166218334Speter#undef double
166318334Speter#undef MIN
166418334Speter#undef MAX
166518334Speter#include <limits.h>
166618334Speter
166790280SobrienUWtype
166890280Sobrien__fixunssfSI (SFtype a)
166918334Speter{
167090280Sobrien  if (a >= - (SFtype) Wtype_MIN)
167190280Sobrien    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
167290280Sobrien  return (Wtype) a;
167318334Speter}
167418334Speter#endif
167518334Speter
1676169699Skan/* Integer power helper used from __builtin_powi for non-constant
1677169699Skan   exponents.  */
1678169699Skan
1679169699Skan#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \
1680169699Skan    || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \
1681169699Skan    || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \
1682169699Skan    || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE)
1683169699Skan# if defined(L_powisf2)
1684169699Skan#  define TYPE SFtype
1685169699Skan#  define NAME __powisf2
1686169699Skan# elif defined(L_powidf2)
1687169699Skan#  define TYPE DFtype
1688169699Skan#  define NAME __powidf2
1689169699Skan# elif defined(L_powixf2)
1690169699Skan#  define TYPE XFtype
1691169699Skan#  define NAME __powixf2
1692169699Skan# elif defined(L_powitf2)
1693169699Skan#  define TYPE TFtype
1694169699Skan#  define NAME __powitf2
1695169699Skan# endif
1696169699Skan
1697169699Skan#undef int
1698169699Skan#undef unsigned
1699169699SkanTYPE
1700169699SkanNAME (TYPE x, int m)
1701169699Skan{
1702169699Skan  unsigned int n = m < 0 ? -m : m;
1703169699Skan  TYPE y = n % 2 ? x : 1;
1704169699Skan  while (n >>= 1)
1705169699Skan    {
1706169699Skan      x = x * x;
1707169699Skan      if (n % 2)
1708169699Skan	y = y * x;
1709169699Skan    }
1710169699Skan  return m < 0 ? 1/y : y;
1711169699Skan}
1712169699Skan
1713169699Skan#endif
1714169699Skan
1715169699Skan#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
1716169699Skan    || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
1717169699Skan    || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
1718169699Skan    || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE)
1719169699Skan
1720169699Skan#undef float
1721169699Skan#undef double
1722169699Skan#undef long
1723169699Skan
1724169699Skan#if defined(L_mulsc3) || defined(L_divsc3)
1725169699Skan# define MTYPE	SFtype
1726169699Skan# define CTYPE	SCtype
1727169699Skan# define MODE	sc
1728169699Skan# define CEXT	f
1729169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0
1730169699Skan#elif defined(L_muldc3) || defined(L_divdc3)
1731169699Skan# define MTYPE	DFtype
1732169699Skan# define CTYPE	DCtype
1733169699Skan# define MODE	dc
1734169699Skan# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64
1735169699Skan#  define CEXT	l
1736169699Skan#  define NOTRUNC 1
1737169699Skan# else
1738169699Skan#  define CEXT
1739169699Skan#  define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
1740169699Skan# endif
1741169699Skan#elif defined(L_mulxc3) || defined(L_divxc3)
1742169699Skan# define MTYPE	XFtype
1743169699Skan# define CTYPE	XCtype
1744169699Skan# define MODE	xc
1745169699Skan# define CEXT	l
1746169699Skan# define NOTRUNC 1
1747169699Skan#elif defined(L_multc3) || defined(L_divtc3)
1748169699Skan# define MTYPE	TFtype
1749169699Skan# define CTYPE	TCtype
1750169699Skan# define MODE	tc
1751169699Skan# define CEXT	l
1752169699Skan# define NOTRUNC 1
1753169699Skan#else
1754169699Skan# error
1755169699Skan#endif
1756169699Skan
1757169699Skan#define CONCAT3(A,B,C)	_CONCAT3(A,B,C)
1758169699Skan#define _CONCAT3(A,B,C)	A##B##C
1759169699Skan
1760169699Skan#define CONCAT2(A,B)	_CONCAT2(A,B)
1761169699Skan#define _CONCAT2(A,B)	A##B
1762169699Skan
1763169699Skan/* All of these would be present in a full C99 implementation of <math.h>
1764169699Skan   and <complex.h>.  Our problem is that only a few systems have such full
1765169699Skan   implementations.  Further, libgcc_s.so isn't currently linked against
1766169699Skan   libm.so, and even for systems that do provide full C99, the extra overhead
1767169699Skan   of all programs using libgcc having to link against libm.  So avoid it.  */
1768169699Skan
1769169699Skan#define isnan(x)	__builtin_expect ((x) != (x), 0)
1770169699Skan#define isfinite(x)	__builtin_expect (!isnan((x) - (x)), 1)
1771169699Skan#define isinf(x)	__builtin_expect (!isnan(x) & !isfinite(x), 0)
1772169699Skan
1773169699Skan#define INFINITY	CONCAT2(__builtin_inf, CEXT) ()
1774169699Skan#define I		1i
1775169699Skan
1776169699Skan/* Helpers to make the following code slightly less gross.  */
1777169699Skan#define COPYSIGN	CONCAT2(__builtin_copysign, CEXT)
1778169699Skan#define FABS		CONCAT2(__builtin_fabs, CEXT)
1779169699Skan
1780169699Skan/* Verify that MTYPE matches up with CEXT.  */
1781169699Skanextern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
1782169699Skan
1783169699Skan/* Ensure that we've lost any extra precision.  */
1784169699Skan#if NOTRUNC
1785169699Skan# define TRUNC(x)
1786169699Skan#else
1787169699Skan# define TRUNC(x)	__asm__ ("" : "=m"(x) : "m"(x))
1788169699Skan#endif
1789169699Skan
1790169699Skan#if defined(L_mulsc3) || defined(L_muldc3) \
1791169699Skan    || defined(L_mulxc3) || defined(L_multc3)
1792169699Skan
1793169699SkanCTYPE
1794169699SkanCONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1795169699Skan{
1796169699Skan  MTYPE ac, bd, ad, bc, x, y;
1797169699Skan
1798169699Skan  ac = a * c;
1799169699Skan  bd = b * d;
1800169699Skan  ad = a * d;
1801169699Skan  bc = b * c;
1802169699Skan
1803169699Skan  TRUNC (ac);
1804169699Skan  TRUNC (bd);
1805169699Skan  TRUNC (ad);
1806169699Skan  TRUNC (bc);
1807169699Skan
1808169699Skan  x = ac - bd;
1809169699Skan  y = ad + bc;
1810169699Skan
1811169699Skan  if (isnan (x) && isnan (y))
1812169699Skan    {
1813169699Skan      /* Recover infinities that computed as NaN + iNaN.  */
1814169699Skan      _Bool recalc = 0;
1815169699Skan      if (isinf (a) || isinf (b))
1816169699Skan	{
1817169699Skan	  /* z is infinite.  "Box" the infinity and change NaNs in
1818169699Skan	     the other factor to 0.  */
1819169699Skan	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
1820169699Skan	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
1821169699Skan	  if (isnan (c)) c = COPYSIGN (0, c);
1822169699Skan	  if (isnan (d)) d = COPYSIGN (0, d);
1823169699Skan          recalc = 1;
1824169699Skan	}
1825169699Skan     if (isinf (c) || isinf (d))
1826169699Skan	{
1827169699Skan	  /* w is infinite.  "Box" the infinity and change NaNs in
1828169699Skan	     the other factor to 0.  */
1829169699Skan	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
1830169699Skan	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
1831169699Skan	  if (isnan (a)) a = COPYSIGN (0, a);
1832169699Skan	  if (isnan (b)) b = COPYSIGN (0, b);
1833169699Skan	  recalc = 1;
1834169699Skan	}
1835169699Skan     if (!recalc
1836169699Skan	  && (isinf (ac) || isinf (bd)
1837169699Skan	      || isinf (ad) || isinf (bc)))
1838169699Skan	{
1839169699Skan	  /* Recover infinities from overflow by changing NaNs to 0.  */
1840169699Skan	  if (isnan (a)) a = COPYSIGN (0, a);
1841169699Skan	  if (isnan (b)) b = COPYSIGN (0, b);
1842169699Skan	  if (isnan (c)) c = COPYSIGN (0, c);
1843169699Skan	  if (isnan (d)) d = COPYSIGN (0, d);
1844169699Skan	  recalc = 1;
1845169699Skan	}
1846169699Skan      if (recalc)
1847169699Skan	{
1848169699Skan	  x = INFINITY * (a * c - b * d);
1849169699Skan	  y = INFINITY * (a * d + b * c);
1850169699Skan	}
1851169699Skan    }
1852169699Skan
1853169699Skan  return x + I * y;
1854169699Skan}
1855169699Skan#endif /* complex multiply */
1856169699Skan
1857169699Skan#if defined(L_divsc3) || defined(L_divdc3) \
1858169699Skan    || defined(L_divxc3) || defined(L_divtc3)
1859169699Skan
1860169699SkanCTYPE
1861169699SkanCONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1862169699Skan{
1863169699Skan  MTYPE denom, ratio, x, y;
1864169699Skan
1865169699Skan  /* ??? We can get better behavior from logarithmic scaling instead of
1866169699Skan     the division.  But that would mean starting to link libgcc against
1867169699Skan     libm.  We could implement something akin to ldexp/frexp as gcc builtins
1868169699Skan     fairly easily...  */
1869169699Skan  if (FABS (c) < FABS (d))
1870169699Skan    {
1871169699Skan      ratio = c / d;
1872169699Skan      denom = (c * ratio) + d;
1873169699Skan      x = ((a * ratio) + b) / denom;
1874169699Skan      y = ((b * ratio) - a) / denom;
1875169699Skan    }
1876169699Skan  else
1877169699Skan    {
1878169699Skan      ratio = d / c;
1879169699Skan      denom = (d * ratio) + c;
1880169699Skan      x = ((b * ratio) + a) / denom;
1881169699Skan      y = (b - (a * ratio)) / denom;
1882169699Skan    }
1883169699Skan
1884169699Skan  /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
1885169699Skan     are nonzero/zero, infinite/finite, and finite/infinite.  */
1886169699Skan  if (isnan (x) && isnan (y))
1887169699Skan    {
1888169699Skan      if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
1889169699Skan	{
1890169699Skan	  x = COPYSIGN (INFINITY, c) * a;
1891169699Skan	  y = COPYSIGN (INFINITY, c) * b;
1892169699Skan	}
1893169699Skan      else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
1894169699Skan	{
1895169699Skan	  a = COPYSIGN (isinf (a) ? 1 : 0, a);
1896169699Skan	  b = COPYSIGN (isinf (b) ? 1 : 0, b);
1897169699Skan	  x = INFINITY * (a * c + b * d);
1898169699Skan	  y = INFINITY * (b * c - a * d);
1899169699Skan	}
1900169699Skan      else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
1901169699Skan	{
1902169699Skan	  c = COPYSIGN (isinf (c) ? 1 : 0, c);
1903169699Skan	  d = COPYSIGN (isinf (d) ? 1 : 0, d);
1904169699Skan	  x = 0.0 * (a * c + b * d);
1905169699Skan	  y = 0.0 * (b * c - a * d);
1906169699Skan	}
1907169699Skan    }
1908169699Skan
1909169699Skan  return x + I * y;
1910169699Skan}
1911169699Skan#endif /* complex divide */
1912169699Skan
1913169699Skan#endif /* all complex float routines */
1914169699Skan
191518334Speter/* From here on down, the routines use normal data types.  */
191618334Speter
191718334Speter#define SItype bogus_type
191818334Speter#define USItype bogus_type
191918334Speter#define DItype bogus_type
192018334Speter#define UDItype bogus_type
192118334Speter#define SFtype bogus_type
192218334Speter#define DFtype bogus_type
192390280Sobrien#undef Wtype
192490280Sobrien#undef UWtype
192590280Sobrien#undef HWtype
192690280Sobrien#undef UHWtype
192790280Sobrien#undef DWtype
192890280Sobrien#undef UDWtype
192918334Speter
193018334Speter#undef char
193118334Speter#undef short
193218334Speter#undef int
193318334Speter#undef long
193418334Speter#undef unsigned
193518334Speter#undef float
193618334Speter#undef double
193718334Speter
193818334Speter#ifdef L__gcc_bcmp
193918334Speter
194018334Speter/* Like bcmp except the sign is meaningful.
194118334Speter   Result is negative if S1 is less than S2,
194218334Speter   positive if S1 is greater, 0 if S1 and S2 are equal.  */
194318334Speter
194418334Speterint
194590280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
194618334Speter{
194718334Speter  while (size > 0)
194818334Speter    {
1949132727Skan      const unsigned char c1 = *s1++, c2 = *s2++;
195018334Speter      if (c1 != c2)
195118334Speter	return c1 - c2;
195218334Speter      size--;
195318334Speter    }
195418334Speter  return 0;
195518334Speter}
195618334Speter
195718334Speter#endif
195818334Speter
195990280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>.
196090280Sobrien   We no longer provide that header, but this routine remains in libgcc.a
196190280Sobrien   for binary backward compatibility.  Note that it is not included in
196290280Sobrien   the shared version of libgcc.  */
196318334Speter#ifdef L_eprintf
196418334Speter#ifndef inhibit_libc
196518334Speter
196618334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
196718334Speter#include <stdio.h>
196852561Sobrien
196918334Spetervoid
197050600Sobrien__eprintf (const char *string, const char *expression,
197150600Sobrien	   unsigned int line, const char *filename)
197218334Speter{
197318334Speter  fprintf (stderr, string, expression, line, filename);
197418334Speter  fflush (stderr);
197518334Speter  abort ();
197618334Speter}
197718334Speter
197818334Speter#endif
197918334Speter#endif
198018334Speter
198118334Speter
198218334Speter#ifdef L_clear_cache
198318334Speter/* Clear part of an instruction cache.  */
198418334Speter
198518334Spetervoid
198690280Sobrien__clear_cache (char *beg __attribute__((__unused__)),
198790280Sobrien	       char *end __attribute__((__unused__)))
198818334Speter{
198990280Sobrien#ifdef CLEAR_INSN_CACHE
199018334Speter  CLEAR_INSN_CACHE (beg, end);
199118334Speter#endif /* CLEAR_INSN_CACHE */
199218334Speter}
199318334Speter
199418334Speter#endif /* L_clear_cache */
199518334Speter
1996132727Skan#ifdef L_enable_execute_stack
1997132727Skan/* Attempt to turn on execute permission for the stack.  */
1998132727Skan
1999132727Skan#ifdef ENABLE_EXECUTE_STACK
2000132727Skan  ENABLE_EXECUTE_STACK
2001132727Skan#else
2002132727Skanvoid
2003132727Skan__enable_execute_stack (void *addr __attribute__((__unused__)))
2004132727Skan{}
2005132727Skan#endif /* ENABLE_EXECUTE_STACK */
2006132727Skan
2007132727Skan#endif /* L_enable_execute_stack */
2008132727Skan
200918334Speter#ifdef L_trampoline
201018334Speter
201118334Speter/* Jump to a trampoline, loading the static chain address.  */
201218334Speter
201352561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
201418334Speter
2015169699Skanint
201690280Sobriengetpagesize (void)
201718334Speter{
201818334Speter#ifdef _ALPHA_
201918334Speter  return 8192;
202018334Speter#else
202118334Speter  return 4096;
202218334Speter#endif
202318334Speter}
202418334Speter
202590280Sobrien#ifdef __i386__
202650600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
202750600Sobrien#endif
202850600Sobrien
202950600Sobrienint
203050600Sobrienmprotect (char *addr, int len, int prot)
203118334Speter{
203218334Speter  int np, op;
203318334Speter
203450600Sobrien  if (prot == 7)
203550600Sobrien    np = 0x40;
203650600Sobrien  else if (prot == 5)
203750600Sobrien    np = 0x20;
203850600Sobrien  else if (prot == 4)
203950600Sobrien    np = 0x10;
204050600Sobrien  else if (prot == 3)
204150600Sobrien    np = 0x04;
204250600Sobrien  else if (prot == 1)
204350600Sobrien    np = 0x02;
204450600Sobrien  else if (prot == 0)
204550600Sobrien    np = 0x01;
204618334Speter
204718334Speter  if (VirtualProtect (addr, len, np, &op))
204818334Speter    return 0;
204918334Speter  else
205018334Speter    return -1;
205118334Speter}
205218334Speter
205352561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
205418334Speter
205590280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE
205690280SobrienTRANSFER_FROM_TRAMPOLINE
205718334Speter#endif
205818334Speter#endif /* L_trampoline */
205918334Speter
206052561Sobrien#ifndef __CYGWIN__
206118334Speter#ifdef L__main
206218334Speter
206318334Speter#include "gbl-ctors.h"
2064169699Skan
206518334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these
206618334Speter   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
206718334Speter   give the same symbol without quotes for an alternative entry point.  You
206850600Sobrien   must define both, or neither.  */
206918334Speter#ifndef NAME__MAIN
207018334Speter#define NAME__MAIN "__main"
207118334Speter#define SYMBOL__MAIN __main
207218334Speter#endif
207318334Speter
2074169699Skan#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP)
207550600Sobrien#undef HAS_INIT_SECTION
207650600Sobrien#define HAS_INIT_SECTION
207750600Sobrien#endif
207850600Sobrien
207950600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
208090280Sobrien
208190280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
208290280Sobrien   code to run constructors.  In that case, we need to handle EH here, too.  */
208390280Sobrien
208490280Sobrien#ifdef EH_FRAME_SECTION_NAME
208590280Sobrien#include "unwind-dw2-fde.h"
208690280Sobrienextern unsigned char __EH_FRAME_BEGIN__[];
208790280Sobrien#endif
208890280Sobrien
208918334Speter/* Run all the global destructors on exit from the program.  */
209018334Speter
209118334Spetervoid
209290280Sobrien__do_global_dtors (void)
209318334Speter{
209418334Speter#ifdef DO_GLOBAL_DTORS_BODY
209518334Speter  DO_GLOBAL_DTORS_BODY;
209618334Speter#else
209750600Sobrien  static func_ptr *p = __DTOR_LIST__ + 1;
209850600Sobrien  while (*p)
209950600Sobrien    {
210050600Sobrien      p++;
210150600Sobrien      (*(p-1)) ();
210250600Sobrien    }
210318334Speter#endif
210490280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
210590280Sobrien  {
210690280Sobrien    static int completed = 0;
210790280Sobrien    if (! completed)
210890280Sobrien      {
210990280Sobrien	completed = 1;
211090280Sobrien	__deregister_frame_info (__EH_FRAME_BEGIN__);
211190280Sobrien      }
211290280Sobrien  }
211390280Sobrien#endif
211418334Speter}
211550600Sobrien#endif
211618334Speter
211750600Sobrien#ifndef HAS_INIT_SECTION
211818334Speter/* Run all the global constructors on entry to the program.  */
211918334Speter
212018334Spetervoid
212190280Sobrien__do_global_ctors (void)
212218334Speter{
212390280Sobrien#ifdef EH_FRAME_SECTION_NAME
212490280Sobrien  {
212590280Sobrien    static struct object object;
212690280Sobrien    __register_frame_info (__EH_FRAME_BEGIN__, &object);
212790280Sobrien  }
212890280Sobrien#endif
212918334Speter  DO_GLOBAL_CTORS_BODY;
213090280Sobrien  atexit (__do_global_dtors);
213118334Speter}
213250600Sobrien#endif /* no HAS_INIT_SECTION */
213318334Speter
213450600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
213518334Speter/* Subroutine called automatically by `main'.
213618334Speter   Compiling a global function named `main'
213718334Speter   produces an automatic call to this function at the beginning.
213818334Speter
213918334Speter   For many systems, this routine calls __do_global_ctors.
214018334Speter   For systems which support a .init section we use the .init section
214118334Speter   to run __do_global_ctors, so we need not do anything here.  */
214218334Speter
2143132727Skanextern void SYMBOL__MAIN (void);
214418334Spetervoid
2145132727SkanSYMBOL__MAIN (void)
214618334Speter{
214718334Speter  /* Support recursive calls to `main': run initializers just once.  */
214818334Speter  static int initialized;
214918334Speter  if (! initialized)
215018334Speter    {
215118334Speter      initialized = 1;
215218334Speter      __do_global_ctors ();
215318334Speter    }
215418334Speter}
215550600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */
215618334Speter
215718334Speter#endif /* L__main */
215852561Sobrien#endif /* __CYGWIN__ */
215918334Speter
216018334Speter#ifdef L_ctors
216118334Speter
216218334Speter#include "gbl-ctors.h"
216318334Speter
216418334Speter/* Provide default definitions for the lists of constructors and
216518334Speter   destructors, so that we don't get linker errors.  These symbols are
216618334Speter   intentionally bss symbols, so that gld and/or collect will provide
216718334Speter   the right values.  */
216818334Speter
216918334Speter/* We declare the lists here with two elements each,
217052561Sobrien   so that they are valid empty lists if no other definition is loaded.
217152561Sobrien
217252561Sobrien   If we are using the old "set" extensions to have the gnu linker
217352561Sobrien   collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
217452561Sobrien   must be in the bss/common section.
217552561Sobrien
217652561Sobrien   Long term no port should use those extensions.  But many still do.  */
217750600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
217890280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
217918334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0};
218018334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0};
218118334Speter#else
218218334Speterfunc_ptr __CTOR_LIST__[2];
218318334Speterfunc_ptr __DTOR_LIST__[2];
218418334Speter#endif
218518334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
218618334Speter#endif /* L_ctors */
2187169699Skan#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */
2188