]> gcc.gnu.org Git - gcc.git/blame - gcc/libgcc2.c
Update Copyright years for files modified in 2008 and/or 2009.
[gcc.git] / gcc / libgcc2.c
CommitLineData
203b91b9
RS
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
5d0e6486 3/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
66647d44
JJ
4 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
5 Free Software Foundation, Inc.
203b91b9 6
1322177d 7This file is part of GCC.
203b91b9 8
1322177d
LB
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 2, or (at your option) any later
12version.
203b91b9 13
f7af368f
JL
14In addition to the permissions in the GNU General Public License, the
15Free Software Foundation gives you unlimited permission to link the
16compiled version of this file into combinations with other programs,
17and to distribute those combinations without any restriction coming
18from the use of this file. (The General Public License restrictions
19do apply in other respects; for example, they cover modification of
20the file, and distribution when not linked into a combine
21executable.)
22
1322177d
LB
23GCC is distributed in the hope that it will be useful, but WITHOUT ANY
24WARRANTY; without even the implied warranty of MERCHANTABILITY or
25FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26for more details.
203b91b9
RS
27
28You should have received a copy of the GNU General Public License
1322177d 29along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
30Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
3102110-1301, USA. */
203b91b9 32
0dadecf6 33#include "tconfig.h"
2e39bdbe 34#include "tsystem.h"
4977bab6
ZW
35#include "coretypes.h"
36#include "tm.h"
2467749d 37
53585c36
RH
38#ifdef HAVE_GAS_HIDDEN
39#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
40#else
41#define ATTRIBUTE_HIDDEN
42#endif
43
baffad1f
RS
44#ifndef MIN_UNITS_PER_WORD
45#define MIN_UNITS_PER_WORD UNITS_PER_WORD
46#endif
47
b2a203c8
RS
48/* Work out the largest "word" size that we can deal with on this target. */
49#if MIN_UNITS_PER_WORD > 4
50# define LIBGCC2_MAX_UNITS_PER_WORD 8
51#elif (MIN_UNITS_PER_WORD > 2 \
52 || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
53# define LIBGCC2_MAX_UNITS_PER_WORD 4
54#else
55# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD
56#endif
57
58/* Work out what word size we are using for this compilation.
59 The value can be set on the command line. */
baffad1f 60#ifndef LIBGCC2_UNITS_PER_WORD
b2a203c8 61#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD
baffad1f
RS
62#endif
63
b2a203c8 64#if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD
baffad1f 65
299b83b7 66#include "libgcc2.h"
203b91b9 67\f
d8088c6f
BS
68#ifdef DECLARE_LIBRARY_RENAMES
69 DECLARE_LIBRARY_RENAMES
70#endif
71
b68daef4 72#if defined (L_negdi2)
3d2adde6
CC
73DWtype
74__negdi2 (DWtype u)
75{
b982024e
KG
76 const DWunion uu = {.ll = u};
77 const DWunion w = { {.low = -uu.s.low,
78 .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
3d2adde6
CC
79
80 return w.ll;
81}
82#endif
91ce572a
CC
83
84#ifdef L_addvsi3
66f77154 85Wtype
0aec6014 86__addvSI3 (Wtype a, Wtype b)
91ce572a 87{
9677aa89 88 const Wtype w = (UWtype) a + (UWtype) b;
91ce572a
CC
89
90 if (b >= 0 ? w < a : w > a)
91 abort ();
92
93 return w;
23190837 94}
0aec6014
EB
95#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
96SItype
97__addvsi3 (SItype a, SItype b)
98{
9677aa89 99 const SItype w = (USItype) a + (USItype) b;
0aec6014
EB
100
101 if (b >= 0 ? w < a : w > a)
102 abort ();
103
104 return w;
105}
106#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
3d2adde6 107#endif
91ce572a
CC
108\f
109#ifdef L_addvdi3
66f77154 110DWtype
0aec6014 111__addvDI3 (DWtype a, DWtype b)
91ce572a 112{
9677aa89 113 const DWtype w = (UDWtype) a + (UDWtype) b;
91ce572a
CC
114
115 if (b >= 0 ? w < a : w > a)
116 abort ();
117
118 return w;
119}
120#endif
121\f
122#ifdef L_subvsi3
66f77154 123Wtype
0aec6014 124__subvSI3 (Wtype a, Wtype b)
91ce572a 125{
9677aa89 126 const Wtype w = (UWtype) a - (UWtype) b;
91ce572a
CC
127
128 if (b >= 0 ? w > a : w < a)
129 abort ();
130
131 return w;
91ce572a 132}
0aec6014
EB
133#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
134SItype
135__subvsi3 (SItype a, SItype b)
136{
9677aa89 137 const SItype w = (USItype) a - (USItype) b;
0aec6014
EB
138
139 if (b >= 0 ? w > a : w < a)
140 abort ();
141
142 return w;
143}
144#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
91ce572a
CC
145#endif
146\f
147#ifdef L_subvdi3
66f77154 148DWtype
0aec6014 149__subvDI3 (DWtype a, DWtype b)
91ce572a 150{
9677aa89 151 const DWtype w = (UDWtype) a - (UDWtype) b;
91ce572a
CC
152
153 if (b >= 0 ? w > a : w < a)
154 abort ();
155
156 return w;
91ce572a
CC
157}
158#endif
159\f
160#ifdef L_mulvsi3
66f77154 161Wtype
0aec6014 162__mulvSI3 (Wtype a, Wtype b)
91ce572a 163{
b982024e 164 const DWtype w = (DWtype) a * (DWtype) b;
91ce572a 165
4f2e0d5e 166 if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
91ce572a
CC
167 abort ();
168
169 return w;
170}
0aec6014
EB
171#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
172#undef WORD_SIZE
173#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
174SItype
175__mulvsi3 (SItype a, SItype b)
176{
177 const DItype w = (DItype) a * (DItype) b;
178
179 if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
180 abort ();
181
182 return w;
183}
184#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
91ce572a
CC
185#endif
186\f
187#ifdef L_negvsi2
66f77154 188Wtype
0aec6014 189__negvSI2 (Wtype a)
91ce572a 190{
9677aa89 191 const Wtype w = -(UWtype) a;
91ce572a
CC
192
193 if (a >= 0 ? w > 0 : w < 0)
194 abort ();
195
196 return w;
197}
0aec6014
EB
198#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
199SItype
200__negvsi2 (SItype a)
201{
9677aa89 202 const SItype w = -(USItype) a;
0aec6014
EB
203
204 if (a >= 0 ? w > 0 : w < 0)
205 abort ();
206
207 return w;
208}
209#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
91ce572a
CC
210#endif
211\f
212#ifdef L_negvdi2
66f77154 213DWtype
0aec6014 214__negvDI2 (DWtype a)
91ce572a 215{
9677aa89 216 const DWtype w = -(UDWtype) a;
91ce572a
CC
217
218 if (a >= 0 ? w > 0 : w < 0)
219 abort ();
220
e11e816e 221 return w;
91ce572a
CC
222}
223#endif
224\f
225#ifdef L_absvsi2
66f77154 226Wtype
0aec6014 227__absvSI2 (Wtype a)
91ce572a 228{
e11e816e 229 Wtype w = a;
91ce572a 230
0aec6014
EB
231 if (a < 0)
232#ifdef L_negvsi2
233 w = __negvSI2 (a);
234#else
9677aa89 235 w = -(UWtype) a;
0aec6014
EB
236
237 if (w < 0)
238 abort ();
239#endif
240
241 return w;
242}
243#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
244SItype
245__absvsi2 (SItype a)
246{
247 SItype w = a;
248
e11e816e 249 if (a < 0)
91ce572a 250#ifdef L_negvsi2
e11e816e 251 w = __negvsi2 (a);
91ce572a 252#else
9677aa89 253 w = -(USItype) a;
91ce572a 254
e11e816e
KH
255 if (w < 0)
256 abort ();
91ce572a
CC
257#endif
258
259 return w;
260}
0aec6014 261#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
91ce572a
CC
262#endif
263\f
264#ifdef L_absvdi2
66f77154 265DWtype
0aec6014 266__absvDI2 (DWtype a)
91ce572a 267{
e11e816e 268 DWtype w = a;
91ce572a 269
e11e816e 270 if (a < 0)
4c20b2e7 271#ifdef L_negvdi2
0aec6014 272 w = __negvDI2 (a);
91ce572a 273#else
9677aa89 274 w = -(UDWtype) a;
91ce572a 275
e11e816e
KH
276 if (w < 0)
277 abort ();
91ce572a
CC
278#endif
279
e11e816e 280 return w;
91ce572a
CC
281}
282#endif
283\f
284#ifdef L_mulvdi3
66f77154 285DWtype
0aec6014 286__mulvDI3 (DWtype u, DWtype v)
91ce572a 287{
4c20b2e7
BH
288 /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
289 but the checked multiplication needs only two. */
b982024e
KG
290 const DWunion uu = {.ll = u};
291 const DWunion vv = {.ll = v};
91ce572a 292
4f2e0d5e 293 if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1))
4c20b2e7
BH
294 {
295 /* u fits in a single Wtype. */
4f2e0d5e 296 if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
4c20b2e7
BH
297 {
298 /* v fits in a single Wtype as well. */
299 /* A single multiplication. No overflow risk. */
300 return (DWtype) uu.s.low * (DWtype) vv.s.low;
301 }
302 else
303 {
304 /* Two multiplications. */
b982024e
KG
305 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
306 * (UDWtype) (UWtype) vv.s.low};
307 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
308 * (UDWtype) (UWtype) vv.s.high};
4c20b2e7 309
4c20b2e7
BH
310 if (vv.s.high < 0)
311 w1.s.high -= uu.s.low;
312 if (uu.s.low < 0)
313 w1.ll -= vv.ll;
314 w1.ll += (UWtype) w0.s.high;
4f2e0d5e 315 if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
4c20b2e7
BH
316 {
317 w0.s.high = w1.s.low;
318 return w0.ll;
319 }
320 }
321 }
322 else
323 {
4f2e0d5e 324 if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
4c20b2e7
BH
325 {
326 /* v fits into a single Wtype. */
327 /* Two multiplications. */
b982024e
KG
328 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
329 * (UDWtype) (UWtype) vv.s.low};
330 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
331 * (UDWtype) (UWtype) vv.s.low};
4c20b2e7 332
4c20b2e7
BH
333 if (uu.s.high < 0)
334 w1.s.high -= vv.s.low;
335 if (vv.s.low < 0)
336 w1.ll -= uu.ll;
337 w1.ll += (UWtype) w0.s.high;
4f2e0d5e 338 if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
4c20b2e7
BH
339 {
340 w0.s.high = w1.s.low;
341 return w0.ll;
342 }
343 }
344 else
345 {
346 /* A few sign checks and a single multiplication. */
347 if (uu.s.high >= 0)
348 {
349 if (vv.s.high >= 0)
350 {
351 if (uu.s.high == 0 && vv.s.high == 0)
352 {
b982024e
KG
353 const DWtype w = (UDWtype) (UWtype) uu.s.low
354 * (UDWtype) (UWtype) vv.s.low;
4c20b2e7
BH
355 if (__builtin_expect (w >= 0, 1))
356 return w;
357 }
358 }
359 else
360 {
361 if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
362 {
b982024e
KG
363 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
364 * (UDWtype) (UWtype) vv.s.low};
4c20b2e7 365
4c20b2e7
BH
366 ww.s.high -= uu.s.low;
367 if (__builtin_expect (ww.s.high < 0, 1))
368 return ww.ll;
369 }
370 }
371 }
372 else
373 {
374 if (vv.s.high >= 0)
375 {
376 if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
377 {
b982024e
KG
378 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
379 * (UDWtype) (UWtype) vv.s.low};
4c20b2e7 380
4c20b2e7
BH
381 ww.s.high -= vv.s.low;
382 if (__builtin_expect (ww.s.high < 0, 1))
383 return ww.ll;
384 }
385 }
386 else
387 {
388 if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
389 {
b982024e
KG
390 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
391 * (UDWtype) (UWtype) vv.s.low};
4c20b2e7 392
4c20b2e7
BH
393 ww.s.high -= uu.s.low;
394 ww.s.high -= vv.s.low;
395 if (__builtin_expect (ww.s.high >= 0, 1))
396 return ww.ll;
397 }
398 }
399 }
400 }
401 }
91ce572a 402
4c20b2e7
BH
403 /* Overflow. */
404 abort ();
91ce572a
CC
405}
406#endif
407\f
203b91b9 408
3d042e77 409/* Unless shift functions are defined with full ANSI prototypes,
c7ff6e7a 410 parameter b will be promoted to int if shift_count_type is smaller than an int. */
203b91b9 411#ifdef L_lshrdi3
996ed075 412DWtype
c7ff6e7a 413__lshrdi3 (DWtype u, shift_count_type b)
203b91b9 414{
203b91b9
RS
415 if (b == 0)
416 return u;
417
b982024e 418 const DWunion uu = {.ll = u};
c7ff6e7a 419 const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
b982024e 420 DWunion w;
203b91b9 421
203b91b9
RS
422 if (bm <= 0)
423 {
424 w.s.high = 0;
6da9c622 425 w.s.low = (UWtype) uu.s.high >> -bm;
203b91b9
RS
426 }
427 else
428 {
b982024e 429 const UWtype carries = (UWtype) uu.s.high << bm;
6da9c622
RK
430
431 w.s.high = (UWtype) uu.s.high >> b;
432 w.s.low = ((UWtype) uu.s.low >> b) | carries;
203b91b9
RS
433 }
434
435 return w.ll;
436}
437#endif
438
439#ifdef L_ashldi3
996ed075 440DWtype
c7ff6e7a 441__ashldi3 (DWtype u, shift_count_type b)
203b91b9 442{
203b91b9
RS
443 if (b == 0)
444 return u;
445
b982024e 446 const DWunion uu = {.ll = u};
c7ff6e7a 447 const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
b982024e 448 DWunion w;
203b91b9 449
203b91b9
RS
450 if (bm <= 0)
451 {
452 w.s.low = 0;
6da9c622 453 w.s.high = (UWtype) uu.s.low << -bm;
203b91b9
RS
454 }
455 else
456 {
b982024e 457 const UWtype carries = (UWtype) uu.s.low >> bm;
6da9c622
RK
458
459 w.s.low = (UWtype) uu.s.low << b;
460 w.s.high = ((UWtype) uu.s.high << b) | carries;
203b91b9
RS
461 }
462
463 return w.ll;
464}
465#endif
466
467#ifdef L_ashrdi3
996ed075 468DWtype
c7ff6e7a 469__ashrdi3 (DWtype u, shift_count_type b)
203b91b9 470{
203b91b9
RS
471 if (b == 0)
472 return u;
473
b982024e 474 const DWunion uu = {.ll = u};
c7ff6e7a 475 const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
b982024e 476 DWunion w;
203b91b9 477
203b91b9
RS
478 if (bm <= 0)
479 {
480 /* w.s.high = 1..1 or 0..0 */
996ed075 481 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
203b91b9
RS
482 w.s.low = uu.s.high >> -bm;
483 }
484 else
485 {
b982024e 486 const UWtype carries = (UWtype) uu.s.high << bm;
6da9c622 487
203b91b9 488 w.s.high = uu.s.high >> b;
6da9c622 489 w.s.low = ((UWtype) uu.s.low >> b) | carries;
203b91b9
RS
490 }
491
492 return w.ll;
493}
494#endif
495\f
167fa32c 496#ifdef L_bswapsi2
e4b6bec2
EC
497SItype
498__bswapsi2 (SItype u)
167fa32c
EC
499{
500 return ((((u) & 0xff000000) >> 24)
501 | (((u) & 0x00ff0000) >> 8)
502 | (((u) & 0x0000ff00) << 8)
503 | (((u) & 0x000000ff) << 24));
504}
505#endif
506#ifdef L_bswapdi2
e4b6bec2
EC
507DItype
508__bswapdi2 (DItype u)
167fa32c
EC
509{
510 return ((((u) & 0xff00000000000000ull) >> 56)
511 | (((u) & 0x00ff000000000000ull) >> 40)
512 | (((u) & 0x0000ff0000000000ull) >> 24)
513 | (((u) & 0x000000ff00000000ull) >> 8)
514 | (((u) & 0x00000000ff000000ull) << 8)
515 | (((u) & 0x0000000000ff0000ull) << 24)
516 | (((u) & 0x000000000000ff00ull) << 40)
517 | (((u) & 0x00000000000000ffull) << 56));
518}
519#endif
dfff898c
RH
520#ifdef L_ffssi2
521#undef int
dfff898c
RH
522int
523__ffsSI2 (UWtype u)
524{
525 UWtype count;
526
527 if (u == 0)
528 return 0;
529
530 count_trailing_zeros (count, u);
531 return count + 1;
532}
533#endif
534\f
aa66bd06 535#ifdef L_ffsdi2
dabb3f04 536#undef int
dabb3f04 537int
dfff898c 538__ffsDI2 (DWtype u)
aa66bd06 539{
b982024e 540 const DWunion uu = {.ll = u};
d6eacd48
RH
541 UWtype word, count, add;
542
d6eacd48
RH
543 if (uu.s.low != 0)
544 word = uu.s.low, add = 0;
545 else if (uu.s.high != 0)
546 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
547 else
548 return 0;
549
550 count_trailing_zeros (count, word);
551 return count + add + 1;
aa66bd06
RS
552}
553#endif
554\f
203b91b9 555#ifdef L_muldi3
996ed075
JJ
556DWtype
557__muldi3 (DWtype u, DWtype v)
203b91b9 558{
b982024e
KG
559 const DWunion uu = {.ll = u};
560 const DWunion vv = {.ll = v};
561 DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
203b91b9 562
996ed075
JJ
563 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
564 + (UWtype) uu.s.high * (UWtype) vv.s.low);
203b91b9
RS
565
566 return w.ll;
567}
568#endif
569\f
59798a0c
UW
570#if (defined (L_udivdi3) || defined (L_divdi3) || \
571 defined (L_umoddi3) || defined (L_moddi3))
f8eef883 572#if defined (sdiv_qrnnd)
59798a0c
UW
573#define L_udiv_w_sdiv
574#endif
f8eef883 575#endif
59798a0c 576
3904131a 577#ifdef L_udiv_w_sdiv
ce13d15f 578#if defined (sdiv_qrnnd)
59798a0c
UW
579#if (defined (L_udivdi3) || defined (L_divdi3) || \
580 defined (L_umoddi3) || defined (L_moddi3))
1ab9ba62 581static inline __attribute__ ((__always_inline__))
59798a0c 582#endif
996ed075
JJ
583UWtype
584__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
431b1ee0 585{
996ed075
JJ
586 UWtype q, r;
587 UWtype c0, c1, b1;
431b1ee0 588
996ed075 589 if ((Wtype) d >= 0)
431b1ee0 590 {
996ed075 591 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
431b1ee0 592 {
ea4b7848 593 /* Dividend, divisor, and quotient are nonnegative. */
431b1ee0
TG
594 sdiv_qrnnd (q, r, a1, a0, d);
595 }
596 else
597 {
ea4b7848 598 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */
996ed075 599 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
ea4b7848 600 /* Divide (c1*2^32 + c0) by d. */
431b1ee0 601 sdiv_qrnnd (q, r, c1, c0, d);
ea4b7848 602 /* Add 2^31 to quotient. */
996ed075 603 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
431b1ee0
TG
604 }
605 }
606 else
607 {
608 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
609 c1 = a1 >> 1; /* A/2 */
996ed075 610 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
431b1ee0
TG
611
612 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
613 {
614 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
615
616 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
617 if ((d & 1) != 0)
618 {
619 if (r >= q)
620 r = r - q;
621 else if (q - r <= d)
622 {
623 r = r - q + d;
624 q--;
625 }
626 else
627 {
628 r = r - q + 2*d;
629 q -= 2;
630 }
631 }
632 }
633 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
634 {
635 c1 = (b1 - 1) - c1;
636 c0 = ~c0; /* logical NOT */
637
638 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
639
640 q = ~q; /* (A/2)/b1 */
641 r = (b1 - 1) - r;
642
643 r = 2*r + (a0 & 1); /* A/(2*b1) */
644
645 if ((d & 1) != 0)
646 {
647 if (r >= q)
648 r = r - q;
649 else if (q - r <= d)
650 {
651 r = r - q + d;
652 q--;
653 }
654 else
655 {
656 r = r - q + 2*d;
657 q -= 2;
658 }
659 }
660 }
661 else /* Implies c1 = b1 */
662 { /* Hence a1 = d - 1 = 2*b1 - 1 */
663 if (a0 >= -d)
664 {
665 q = -1;
666 r = a0 + d;
667 }
668 else
669 {
670 q = -2;
671 r = a0 + 2*d;
672 }
673 }
674 }
675
676 *rp = r;
677 return q;
678}
ce13d15f
RK
679#else
680/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
996ed075
JJ
681UWtype
682__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
683 UWtype a1 __attribute__ ((__unused__)),
684 UWtype a0 __attribute__ ((__unused__)),
685 UWtype d __attribute__ ((__unused__)))
081f5e7e
KG
686{
687 return 0;
688}
ce13d15f 689#endif
431b1ee0
TG
690#endif
691\f
536bfcd0
RK
692#if (defined (L_udivdi3) || defined (L_divdi3) || \
693 defined (L_umoddi3) || defined (L_moddi3))
694#define L_udivmoddi4
695#endif
696
d6eacd48 697#ifdef L_clz
dcfae47c 698const UQItype __clz_tab[256] =
203b91b9
RS
699{
700 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,
701 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,
702 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,
703 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,
704 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,
705 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,
706 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,
dcfae47c 707 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
203b91b9 708};
d6eacd48 709#endif
2928cd7a
RH
710\f
711#ifdef L_clzsi2
dabb3f04 712#undef int
dabb3f04 713int
8275b011 714__clzSI2 (UWtype x)
2928cd7a 715{
53585c36 716 Wtype ret;
2928cd7a 717
8275b011 718 count_leading_zeros (ret, x);
53585c36
RH
719
720 return ret;
2928cd7a
RH
721}
722#endif
723\f
724#ifdef L_clzdi2
dabb3f04 725#undef int
dabb3f04 726int
8275b011 727__clzDI2 (UDWtype x)
2928cd7a 728{
b982024e 729 const DWunion uu = {.ll = x};
53585c36
RH
730 UWtype word;
731 Wtype ret, add;
732
8275b011
RH
733 if (uu.s.high)
734 word = uu.s.high, add = 0;
53585c36 735 else
8275b011 736 word = uu.s.low, add = W_TYPE_SIZE;
2928cd7a 737
53585c36
RH
738 count_leading_zeros (ret, word);
739 return ret + add;
2928cd7a
RH
740}
741#endif
742\f
743#ifdef L_ctzsi2
dabb3f04 744#undef int
dabb3f04 745int
8275b011 746__ctzSI2 (UWtype x)
2928cd7a 747{
53585c36 748 Wtype ret;
2928cd7a 749
53585c36 750 count_trailing_zeros (ret, x);
2928cd7a 751
53585c36 752 return ret;
2928cd7a
RH
753}
754#endif
755\f
756#ifdef L_ctzdi2
dabb3f04 757#undef int
dabb3f04 758int
8275b011 759__ctzDI2 (UDWtype x)
2928cd7a 760{
b982024e 761 const DWunion uu = {.ll = x};
53585c36
RH
762 UWtype word;
763 Wtype ret, add;
764
8275b011
RH
765 if (uu.s.low)
766 word = uu.s.low, add = 0;
53585c36 767 else
8275b011 768 word = uu.s.high, add = W_TYPE_SIZE;
2928cd7a 769
53585c36
RH
770 count_trailing_zeros (ret, word);
771 return ret + add;
2928cd7a
RH
772}
773#endif
774
2928cd7a 775#ifdef L_popcount_tab
dcfae47c 776const UQItype __popcount_tab[256] =
2928cd7a
RH
777{
778 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,
779 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,
780 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,
781 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,
782 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,
783 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,
784 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,
dcfae47c 785 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
2928cd7a
RH
786};
787#endif
788\f
789#ifdef L_popcountsi2
dabb3f04 790#undef int
dabb3f04 791int
8275b011 792__popcountSI2 (UWtype x)
2928cd7a 793{
4000debb 794 int i, ret = 0;
8275b011
RH
795
796 for (i = 0; i < W_TYPE_SIZE; i += 8)
797 ret += __popcount_tab[(x >> i) & 0xff];
798
799 return ret;
2928cd7a
RH
800}
801#endif
802\f
803#ifdef L_popcountdi2
dabb3f04 804#undef int
dabb3f04 805int
8275b011 806__popcountDI2 (UDWtype x)
2928cd7a 807{
4000debb 808 int i, ret = 0;
8275b011
RH
809
810 for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
811 ret += __popcount_tab[(x >> i) & 0xff];
812
813 return ret;
2928cd7a
RH
814}
815#endif
816\f
817#ifdef L_paritysi2
dabb3f04 818#undef int
dabb3f04 819int
8275b011 820__paritySI2 (UWtype x)
2928cd7a 821{
8275b011
RH
822#if W_TYPE_SIZE > 64
823# error "fill out the table"
824#endif
825#if W_TYPE_SIZE > 32
826 x ^= x >> 32;
827#endif
828#if W_TYPE_SIZE > 16
829 x ^= x >> 16;
830#endif
831 x ^= x >> 8;
832 x ^= x >> 4;
833 x &= 0xf;
834 return (0x6996 >> x) & 1;
2928cd7a
RH
835}
836#endif
837\f
838#ifdef L_paritydi2
dabb3f04 839#undef int
dabb3f04 840int
8275b011 841__parityDI2 (UDWtype x)
2928cd7a 842{
b982024e
KG
843 const DWunion uu = {.ll = x};
844 UWtype nx = uu.s.low ^ uu.s.high;
8275b011
RH
845
846#if W_TYPE_SIZE > 64
847# error "fill out the table"
848#endif
849#if W_TYPE_SIZE > 32
850 nx ^= nx >> 32;
851#endif
852#if W_TYPE_SIZE > 16
2928cd7a 853 nx ^= nx >> 16;
8275b011 854#endif
2928cd7a 855 nx ^= nx >> 8;
53585c36 856 nx ^= nx >> 4;
0c9ed856
RH
857 nx &= 0xf;
858 return (0x6996 >> nx) & 1;
2928cd7a
RH
859}
860#endif
d6eacd48
RH
861
862#ifdef L_udivmoddi4
203b91b9 863
536bfcd0
RK
864#if (defined (L_udivdi3) || defined (L_divdi3) || \
865 defined (L_umoddi3) || defined (L_moddi3))
1ab9ba62 866static inline __attribute__ ((__always_inline__))
536bfcd0 867#endif
996ed075
JJ
868UDWtype
869__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
203b91b9 870{
b982024e
KG
871 const DWunion nn = {.ll = n};
872 const DWunion dd = {.ll = d};
996ed075
JJ
873 DWunion rr;
874 UWtype d0, d1, n0, n1, n2;
875 UWtype q0, q1;
876 UWtype b, bm;
203b91b9 877
203b91b9
RS
878 d0 = dd.s.low;
879 d1 = dd.s.high;
880 n0 = nn.s.low;
881 n1 = nn.s.high;
882
883#if !UDIV_NEEDS_NORMALIZATION
884 if (d1 == 0)
885 {
886 if (d0 > n1)
887 {
888 /* 0q = nn / 0D */
889
890 udiv_qrnnd (q0, n0, n1, n0, d0);
891 q1 = 0;
892
893 /* Remainder in n0. */
894 }
895 else
896 {
897 /* qq = NN / 0d */
898
899 if (d0 == 0)
900 d0 = 1 / d0; /* Divide intentionally by zero. */
901
902 udiv_qrnnd (q1, n1, 0, n1, d0);
903 udiv_qrnnd (q0, n0, n1, n0, d0);
904
905 /* Remainder in n0. */
906 }
907
908 if (rp != 0)
909 {
910 rr.s.low = n0;
911 rr.s.high = 0;
912 *rp = rr.ll;
913 }
914 }
915
916#else /* UDIV_NEEDS_NORMALIZATION */
917
918 if (d1 == 0)
919 {
920 if (d0 > n1)
921 {
922 /* 0q = nn / 0D */
923
924 count_leading_zeros (bm, d0);
925
926 if (bm != 0)
927 {
928 /* Normalize, i.e. make the most significant bit of the
929 denominator set. */
930
931 d0 = d0 << bm;
996ed075 932 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
203b91b9
RS
933 n0 = n0 << bm;
934 }
935
936 udiv_qrnnd (q0, n0, n1, n0, d0);
937 q1 = 0;
938
939 /* Remainder in n0 >> bm. */
940 }
941 else
942 {
943 /* qq = NN / 0d */
944
945 if (d0 == 0)
946 d0 = 1 / d0; /* Divide intentionally by zero. */
947
948 count_leading_zeros (bm, d0);
949
950 if (bm == 0)
951 {
952 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
953 conclude (the most significant bit of n1 is set) /\ (the
954 leading quotient digit q1 = 1).
955
956 This special case is necessary, not an optimization.
996ed075 957 (Shifts counts of W_TYPE_SIZE are undefined.) */
203b91b9
RS
958
959 n1 -= d0;
960 q1 = 1;
961 }
962 else
963 {
964 /* Normalize. */
965
996ed075 966 b = W_TYPE_SIZE - bm;
203b91b9
RS
967
968 d0 = d0 << bm;
969 n2 = n1 >> b;
970 n1 = (n1 << bm) | (n0 >> b);
971 n0 = n0 << bm;
972
973 udiv_qrnnd (q1, n1, n2, n1, d0);
974 }
975
0f41302f 976 /* n1 != d0... */
203b91b9
RS
977
978 udiv_qrnnd (q0, n0, n1, n0, d0);
979
980 /* Remainder in n0 >> bm. */
981 }
982
983 if (rp != 0)
984 {
985 rr.s.low = n0 >> bm;
986 rr.s.high = 0;
987 *rp = rr.ll;
988 }
989 }
990#endif /* UDIV_NEEDS_NORMALIZATION */
991
992 else
993 {
994 if (d1 > n1)
995 {
996 /* 00 = nn / DD */
997
998 q0 = 0;
999 q1 = 0;
1000
1001 /* Remainder in n1n0. */
1002 if (rp != 0)
1003 {
1004 rr.s.low = n0;
1005 rr.s.high = n1;
1006 *rp = rr.ll;
1007 }
1008 }
1009 else
1010 {
1011 /* 0q = NN / dd */
1012
1013 count_leading_zeros (bm, d1);
1014 if (bm == 0)
1015 {
1016 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
1017 conclude (the most significant bit of n1 is set) /\ (the
1018 quotient digit q0 = 0 or 1).
1019
1020 This special case is necessary, not an optimization. */
1021
1022 /* The condition on the next line takes advantage of that
1023 n1 >= d1 (true due to program flow). */
1024 if (n1 > d1 || n0 >= d0)
1025 {
1026 q0 = 1;
1027 sub_ddmmss (n1, n0, n1, n0, d1, d0);
1028 }
1029 else
1030 q0 = 0;
1031
1032 q1 = 0;
1033
1034 if (rp != 0)
1035 {
1036 rr.s.low = n0;
1037 rr.s.high = n1;
1038 *rp = rr.ll;
1039 }
1040 }
1041 else
1042 {
996ed075 1043 UWtype m1, m0;
203b91b9
RS
1044 /* Normalize. */
1045
996ed075 1046 b = W_TYPE_SIZE - bm;
203b91b9
RS
1047
1048 d1 = (d1 << bm) | (d0 >> b);
1049 d0 = d0 << bm;
1050 n2 = n1 >> b;
1051 n1 = (n1 << bm) | (n0 >> b);
1052 n0 = n0 << bm;
1053
1054 udiv_qrnnd (q0, n1, n2, n1, d1);
1055 umul_ppmm (m1, m0, q0, d0);
1056
1057 if (m1 > n1 || (m1 == n1 && m0 > n0))
1058 {
1059 q0--;
1060 sub_ddmmss (m1, m0, m1, m0, d1, d0);
1061 }
1062
1063 q1 = 0;
1064
1065 /* Remainder in (n1n0 - m1m0) >> bm. */
1066 if (rp != 0)
1067 {
1068 sub_ddmmss (n1, n0, n1, n0, m1, m0);
1069 rr.s.low = (n1 << b) | (n0 >> bm);
1070 rr.s.high = n1 >> bm;
1071 *rp = rr.ll;
1072 }
1073 }
1074 }
1075 }
1076
b982024e 1077 const DWunion ww = {{.low = q0, .high = q1}};
203b91b9
RS
1078 return ww.ll;
1079}
1080#endif
1081
1082#ifdef L_divdi3
996ed075
JJ
1083DWtype
1084__divdi3 (DWtype u, DWtype v)
203b91b9 1085{
c7ff6e7a 1086 Wtype c = 0;
b982024e
KG
1087 DWunion uu = {.ll = u};
1088 DWunion vv = {.ll = v};
996ed075 1089 DWtype w;
203b91b9 1090
203b91b9
RS
1091 if (uu.s.high < 0)
1092 c = ~c,
b68daef4 1093 uu.ll = -uu.ll;
203b91b9
RS
1094 if (vv.s.high < 0)
1095 c = ~c,
b68daef4 1096 vv.ll = -vv.ll;
203b91b9 1097
996ed075 1098 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
203b91b9 1099 if (c)
b68daef4 1100 w = -w;
203b91b9
RS
1101
1102 return w;
1103}
1104#endif
1105
1106#ifdef L_moddi3
996ed075
JJ
1107DWtype
1108__moddi3 (DWtype u, DWtype v)
203b91b9 1109{
c7ff6e7a 1110 Wtype c = 0;
b982024e
KG
1111 DWunion uu = {.ll = u};
1112 DWunion vv = {.ll = v};
996ed075 1113 DWtype w;
203b91b9 1114
203b91b9
RS
1115 if (uu.s.high < 0)
1116 c = ~c,
b68daef4 1117 uu.ll = -uu.ll;
203b91b9 1118 if (vv.s.high < 0)
b68daef4 1119 vv.ll = -vv.ll;
203b91b9 1120
9c859be1 1121 (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
203b91b9 1122 if (c)
b68daef4 1123 w = -w;
203b91b9
RS
1124
1125 return w;
1126}
1127#endif
1128
1129#ifdef L_umoddi3
996ed075
JJ
1130UDWtype
1131__umoddi3 (UDWtype u, UDWtype v)
203b91b9 1132{
996ed075 1133 UDWtype w;
203b91b9
RS
1134
1135 (void) __udivmoddi4 (u, v, &w);
1136
1137 return w;
1138}
1139#endif
1140
1141#ifdef L_udivdi3
996ed075
JJ
1142UDWtype
1143__udivdi3 (UDWtype n, UDWtype d)
203b91b9 1144{
996ed075 1145 return __udivmoddi4 (n, d, (UDWtype *) 0);
203b91b9
RS
1146}
1147#endif
1148\f
1149#ifdef L_cmpdi2
c7ff6e7a 1150cmp_return_type
996ed075 1151__cmpdi2 (DWtype a, DWtype b)
203b91b9 1152{
b982024e
KG
1153 const DWunion au = {.ll = a};
1154 const DWunion bu = {.ll = b};
203b91b9
RS
1155
1156 if (au.s.high < bu.s.high)
1157 return 0;
1158 else if (au.s.high > bu.s.high)
1159 return 2;
996ed075 1160 if ((UWtype) au.s.low < (UWtype) bu.s.low)
203b91b9 1161 return 0;
996ed075 1162 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
203b91b9
RS
1163 return 2;
1164 return 1;
1165}
1166#endif
1167
1168#ifdef L_ucmpdi2
c7ff6e7a 1169cmp_return_type
996ed075 1170__ucmpdi2 (DWtype a, DWtype b)
203b91b9 1171{
b982024e
KG
1172 const DWunion au = {.ll = a};
1173 const DWunion bu = {.ll = b};
203b91b9 1174
996ed075 1175 if ((UWtype) au.s.high < (UWtype) bu.s.high)
203b91b9 1176 return 0;
996ed075 1177 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
203b91b9 1178 return 2;
996ed075 1179 if ((UWtype) au.s.low < (UWtype) bu.s.low)
203b91b9 1180 return 0;
996ed075 1181 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
203b91b9
RS
1182 return 2;
1183 return 1;
1184}
1185#endif
1186\f
4e9db8b2 1187#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
f139f5fa 1188UDWtype
6da9c622 1189__fixunstfDI (TFtype a)
ab495388 1190{
ab495388
RS
1191 if (a < 0)
1192 return 0;
1193
1194 /* Compute high word of result, as a flonum. */
4f2e0d5e 1195 const TFtype b = (a / Wtype_MAXp1_F);
996ed075 1196 /* Convert that to fixed (but not to DWtype!),
ab495388 1197 and shift it into the high word. */
b982024e 1198 UDWtype v = (UWtype) b;
4f2e0d5e 1199 v <<= W_TYPE_SIZE;
ab495388
RS
1200 /* Remove high part from the TFtype, leaving the low part as flonum. */
1201 a -= (TFtype)v;
996ed075 1202 /* Convert that to fixed (but not to DWtype!) and add it in.
ab495388
RS
1203 Sometimes A comes out negative. This is significant, since
1204 A has more bits than a long int does. */
1205 if (a < 0)
996ed075 1206 v -= (UWtype) (- a);
ab495388 1207 else
996ed075 1208 v += (UWtype) a;
ab495388
RS
1209 return v;
1210}
1211#endif
1212
4e9db8b2 1213#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
996ed075 1214DWtype
37ef1054 1215__fixtfdi (TFtype a)
ab495388
RS
1216{
1217 if (a < 0)
6da9c622
RK
1218 return - __fixunstfDI (-a);
1219 return __fixunstfDI (a);
ab495388
RS
1220}
1221#endif
1222
4e9db8b2 1223#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
f139f5fa 1224UDWtype
6da9c622 1225__fixunsxfDI (XFtype a)
e0799b34 1226{
e0799b34
RS
1227 if (a < 0)
1228 return 0;
1229
1230 /* Compute high word of result, as a flonum. */
4f2e0d5e 1231 const XFtype b = (a / Wtype_MAXp1_F);
996ed075 1232 /* Convert that to fixed (but not to DWtype!),
e0799b34 1233 and shift it into the high word. */
b982024e 1234 UDWtype v = (UWtype) b;
4f2e0d5e 1235 v <<= W_TYPE_SIZE;
e0799b34
RS
1236 /* Remove high part from the XFtype, leaving the low part as flonum. */
1237 a -= (XFtype)v;
996ed075 1238 /* Convert that to fixed (but not to DWtype!) and add it in.
e0799b34
RS
1239 Sometimes A comes out negative. This is significant, since
1240 A has more bits than a long int does. */
1241 if (a < 0)
996ed075 1242 v -= (UWtype) (- a);
e0799b34 1243 else
996ed075 1244 v += (UWtype) a;
e0799b34
RS
1245 return v;
1246}
1247#endif
1248
4e9db8b2 1249#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
996ed075 1250DWtype
37ef1054 1251__fixxfdi (XFtype a)
e0799b34
RS
1252{
1253 if (a < 0)
6da9c622
RK
1254 return - __fixunsxfDI (-a);
1255 return __fixunsxfDI (a);
e0799b34
RS
1256}
1257#endif
1258
4e9db8b2 1259#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
f139f5fa 1260UDWtype
6da9c622 1261__fixunsdfDI (DFtype a)
203b91b9 1262{
4977bab6
ZW
1263 /* Get high part of result. The division here will just moves the radix
1264 point and will not cause any rounding. Then the conversion to integral
1265 type chops result as desired. */
4f2e0d5e 1266 const UWtype hi = a / Wtype_MAXp1_F;
203b91b9 1267
4977bab6
ZW
1268 /* Get low part of result. Convert `hi' to floating type and scale it back,
1269 then subtract this from the number being converted. This leaves the low
1270 part. Convert that to integral type. */
4f2e0d5e 1271 const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
4977bab6
ZW
1272
1273 /* Assemble result from the two parts. */
4f2e0d5e 1274 return ((UDWtype) hi << W_TYPE_SIZE) | lo;
203b91b9
RS
1275}
1276#endif
1277
4e9db8b2 1278#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
996ed075 1279DWtype
37ef1054 1280__fixdfdi (DFtype a)
203b91b9
RS
1281{
1282 if (a < 0)
6da9c622
RK
1283 return - __fixunsdfDI (-a);
1284 return __fixunsdfDI (a);
203b91b9
RS
1285}
1286#endif
1287
cfa7bd9c 1288#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE
f139f5fa 1289UDWtype
4f2e0d5e 1290__fixunssfDI (SFtype a)
203b91b9 1291{
4e9db8b2 1292#if LIBGCC2_HAS_DF_MODE
ab495388 1293 /* Convert the SFtype to a DFtype, because that is surely not going
203b91b9 1294 to lose any bits. Some day someone else can write a faster version
ab495388 1295 that avoids converting to DFtype, and verify it really works right. */
4f2e0d5e 1296 const DFtype dfa = a;
203b91b9 1297
4977bab6
ZW
1298 /* Get high part of result. The division here will just moves the radix
1299 point and will not cause any rounding. Then the conversion to integral
1300 type chops result as desired. */
4f2e0d5e 1301 const UWtype hi = dfa / Wtype_MAXp1_F;
203b91b9 1302
4977bab6
ZW
1303 /* Get low part of result. Convert `hi' to floating type and scale it back,
1304 then subtract this from the number being converted. This leaves the low
1305 part. Convert that to integral type. */
4f2e0d5e 1306 const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
4977bab6
ZW
1307
1308 /* Assemble result from the two parts. */
4f2e0d5e
RH
1309 return ((UDWtype) hi << W_TYPE_SIZE) | lo;
1310#elif FLT_MANT_DIG < W_TYPE_SIZE
1311 if (a < 1)
1312 return 0;
1313 if (a < Wtype_MAXp1_F)
1314 return (UWtype)a;
1315 if (a < Wtype_MAXp1_F * Wtype_MAXp1_F)
1316 {
1317 /* Since we know that there are fewer significant bits in the SFmode
1318 quantity than in a word, we know that we can convert out all the
2e681715 1319 significant bits in one step, and thus avoid losing bits. */
4f2e0d5e
RH
1320
1321 /* ??? This following loop essentially performs frexpf. If we could
1322 use the real libm function, or poke at the actual bits of the fp
1323 format, it would be significantly faster. */
1324
1325 UWtype shift = 0, counter;
1326 SFtype msb;
1327
1328 a /= Wtype_MAXp1_F;
1329 for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1)
1330 {
1331 SFtype counterf = (UWtype)1 << counter;
1332 if (a >= counterf)
1333 {
1334 shift |= counter;
1335 a /= counterf;
1336 }
1337 }
1338
1339 /* Rescale into the range of one word, extract the bits of that
1340 one word, and shift the result into position. */
1341 a *= Wtype_MAXp1_F;
1342 counter = a;
1343 return (DWtype)counter << shift;
1344 }
1345 return -1;
1346#else
1347# error
1348#endif
203b91b9
RS
1349}
1350#endif
1351
cfa7bd9c 1352#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE
996ed075 1353DWtype
ab495388 1354__fixsfdi (SFtype a)
203b91b9
RS
1355{
1356 if (a < 0)
6da9c622
RK
1357 return - __fixunssfDI (-a);
1358 return __fixunssfDI (a);
203b91b9
RS
1359}
1360#endif
1361
4e9db8b2 1362#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
e0799b34 1363XFtype
996ed075 1364__floatdixf (DWtype u)
e0799b34 1365{
4a73d865
JM
1366#if W_TYPE_SIZE > XF_SIZE
1367# error
1368#endif
4f2e0d5e
RH
1369 XFtype d = (Wtype) (u >> W_TYPE_SIZE);
1370 d *= Wtype_MAXp1_F;
1371 d += (UWtype)u;
e5e809f4 1372 return d;
e0799b34
RS
1373}
1374#endif
1375
d7735880
JM
1376#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE
1377XFtype
1378__floatundixf (UDWtype u)
1379{
4a73d865
JM
1380#if W_TYPE_SIZE > XF_SIZE
1381# error
1382#endif
d7735880
JM
1383 XFtype d = (UWtype) (u >> W_TYPE_SIZE);
1384 d *= Wtype_MAXp1_F;
1385 d += (UWtype)u;
1386 return d;
1387}
1388#endif
1389
4e9db8b2 1390#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
ab495388 1391TFtype
996ed075 1392__floatditf (DWtype u)
ab495388 1393{
4a73d865
JM
1394#if W_TYPE_SIZE > TF_SIZE
1395# error
1396#endif
4f2e0d5e
RH
1397 TFtype d = (Wtype) (u >> W_TYPE_SIZE);
1398 d *= Wtype_MAXp1_F;
1399 d += (UWtype)u;
e5e809f4 1400 return d;
ab495388
RS
1401}
1402#endif
1403
d7735880
JM
1404#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE
1405TFtype
1406__floatunditf (UDWtype u)
1407{
4a73d865
JM
1408#if W_TYPE_SIZE > TF_SIZE
1409# error
203b91b9 1410#endif
4a73d865 1411 TFtype d = (UWtype) (u >> W_TYPE_SIZE);
d7735880
JM
1412 d *= Wtype_MAXp1_F;
1413 d += (UWtype)u;
1414 return d;
1415}
1416#endif
1417
4a73d865
JM
1418#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \
1419 || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
4f2e0d5e 1420#define DI_SIZE (W_TYPE_SIZE * 2)
b04c9063
AM
1421#define F_MODE_OK(SIZE) \
1422 (SIZE < DI_SIZE \
1423 && SIZE > (DI_SIZE - SIZE + FSSIZE) \
5fb54b91 1424 && !AVOID_FP_TYPE_CONVERSION(SIZE))
4a73d865
JM
1425#if defined(L_floatdisf)
1426#define FUNC __floatdisf
1427#define FSTYPE SFtype
1428#define FSSIZE SF_SIZE
1429#else
1430#define FUNC __floatdidf
1431#define FSTYPE DFtype
1432#define FSSIZE DF_SIZE
1433#endif
203b91b9 1434
4a73d865
JM
1435FSTYPE
1436FUNC (DWtype u)
203b91b9 1437{
4a73d865 1438#if FSSIZE >= W_TYPE_SIZE
4f2e0d5e 1439 /* When the word size is small, we never get any rounding error. */
4a73d865 1440 FSTYPE f = (Wtype) (u >> W_TYPE_SIZE);
4f2e0d5e
RH
1441 f *= Wtype_MAXp1_F;
1442 f += (UWtype)u;
1443 return f;
4a73d865
JM
1444#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \
1445 || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \
1446 || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1447
1448#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1449# define FSIZE DF_SIZE
1450# define FTYPE DFtype
1451#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1452# define FSIZE XF_SIZE
1453# define FTYPE XFtype
1454#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1455# define FSIZE TF_SIZE
1456# define FTYPE TFtype
4f2e0d5e
RH
1457#else
1458# error
1459#endif
1460
4a73d865 1461#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
4f2e0d5e 1462
d9e1ab8d 1463 /* Protect against double-rounding error.
4f2e0d5e
RH
1464 Represent any low-order bits, that might be truncated by a bit that
1465 won't be lost. The bit can go in anywhere below the rounding position
4a73d865
JM
1466 of the FSTYPE. A fixed mask and bit position handles all usual
1467 configurations. */
1468 if (! (- ((DWtype) 1 << FSIZE) < u
1469 && u < ((DWtype) 1 << FSIZE)))
d9e1ab8d 1470 {
4a73d865 1471 if ((UDWtype) u & (REP_BIT - 1))
d9e1ab8d 1472 {
4a73d865
JM
1473 u &= ~ (REP_BIT - 1);
1474 u |= REP_BIT;
d9e1ab8d
RK
1475 }
1476 }
203b91b9 1477
4a73d865
JM
1478 /* Do the calculation in a wider type so that we don't lose any of
1479 the precision of the high word while multiplying it. */
1480 FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
4f2e0d5e
RH
1481 f *= Wtype_MAXp1_F;
1482 f += (UWtype)u;
4a73d865 1483 return (FSTYPE) f;
4f2e0d5e 1484#else
4a73d865
JM
1485#if FSSIZE >= W_TYPE_SIZE - 2
1486# error
1487#endif
1488 /* Finally, the word size is larger than the number of bits in the
1489 required FSTYPE, and we've got no suitable wider type. The only
1490 way to avoid double rounding is to special case the
1491 extraction. */
4f2e0d5e
RH
1492
1493 /* If there are no high bits set, fall back to one conversion. */
1494 if ((Wtype)u == u)
4a73d865 1495 return (FSTYPE)(Wtype)u;
4f2e0d5e
RH
1496
1497 /* Otherwise, find the power of two. */
1498 Wtype hi = u >> W_TYPE_SIZE;
1499 if (hi < 0)
1500 hi = -hi;
1501
1502 UWtype count, shift;
1503 count_leading_zeros (count, hi);
1504
1505 /* No leading bits means u == minimum. */
1506 if (count == 0)
4a73d865 1507 return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2));
4f2e0d5e 1508
4a73d865 1509 shift = 1 + W_TYPE_SIZE - count;
4f2e0d5e
RH
1510
1511 /* Shift down the most significant bits. */
1512 hi = u >> shift;
1513
1514 /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
5fb54b91 1515 if ((UWtype)u << (W_TYPE_SIZE - shift))
4f2e0d5e
RH
1516 hi |= 1;
1517
1518 /* Convert the one word of data, and rescale. */
5fb54b91
RH
1519 FSTYPE f = hi, e;
1520 if (shift == W_TYPE_SIZE)
1521 e = Wtype_MAXp1_F;
1522 /* The following two cases could be merged if we knew that the target
1523 supported a native unsigned->float conversion. More often, we only
1524 have a signed conversion, and have to add extra fixup code. */
1525 else if (shift == W_TYPE_SIZE - 1)
1526 e = Wtype_MAXp1_F / 2;
1527 else
1528 e = (Wtype)1 << shift;
1529 return f * e;
4f2e0d5e 1530#endif
203b91b9
RS
1531}
1532#endif
1533
4a73d865
JM
1534#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \
1535 || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
d7735880 1536#define DI_SIZE (W_TYPE_SIZE * 2)
b04c9063
AM
1537#define F_MODE_OK(SIZE) \
1538 (SIZE < DI_SIZE \
1539 && SIZE > (DI_SIZE - SIZE + FSSIZE) \
5fb54b91 1540 && !AVOID_FP_TYPE_CONVERSION(SIZE))
4a73d865
JM
1541#if defined(L_floatundisf)
1542#define FUNC __floatundisf
1543#define FSTYPE SFtype
1544#define FSSIZE SF_SIZE
1545#else
1546#define FUNC __floatundidf
1547#define FSTYPE DFtype
1548#define FSSIZE DF_SIZE
1549#endif
d7735880 1550
4a73d865
JM
1551FSTYPE
1552FUNC (UDWtype u)
d7735880 1553{
4a73d865 1554#if FSSIZE >= W_TYPE_SIZE
d7735880 1555 /* When the word size is small, we never get any rounding error. */
4a73d865 1556 FSTYPE f = (UWtype) (u >> W_TYPE_SIZE);
d7735880
JM
1557 f *= Wtype_MAXp1_F;
1558 f += (UWtype)u;
1559 return f;
4a73d865
JM
1560#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \
1561 || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \
1562 || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1563
1564#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE))
1565# define FSIZE DF_SIZE
1566# define FTYPE DFtype
1567#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE))
1568# define FSIZE XF_SIZE
1569# define FTYPE XFtype
1570#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE))
1571# define FSIZE TF_SIZE
1572# define FTYPE TFtype
d7735880
JM
1573#else
1574# error
1575#endif
1576
4a73d865 1577#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
d7735880
JM
1578
1579 /* Protect against double-rounding error.
1580 Represent any low-order bits, that might be truncated by a bit that
1581 won't be lost. The bit can go in anywhere below the rounding position
4a73d865
JM
1582 of the FSTYPE. A fixed mask and bit position handles all usual
1583 configurations. */
1584 if (u >= ((UDWtype) 1 << FSIZE))
d7735880 1585 {
4a73d865 1586 if ((UDWtype) u & (REP_BIT - 1))
d7735880 1587 {
4a73d865
JM
1588 u &= ~ (REP_BIT - 1);
1589 u |= REP_BIT;
d7735880
JM
1590 }
1591 }
1592
4a73d865
JM
1593 /* Do the calculation in a wider type so that we don't lose any of
1594 the precision of the high word while multiplying it. */
1595 FTYPE f = (UWtype) (u >> W_TYPE_SIZE);
d7735880
JM
1596 f *= Wtype_MAXp1_F;
1597 f += (UWtype)u;
4a73d865 1598 return (FSTYPE) f;
d7735880 1599#else
4a73d865
JM
1600#if FSSIZE == W_TYPE_SIZE - 1
1601# error
1602#endif
1603 /* Finally, the word size is larger than the number of bits in the
1604 required FSTYPE, and we've got no suitable wider type. The only
1605 way to avoid double rounding is to special case the
1606 extraction. */
d7735880
JM
1607
1608 /* If there are no high bits set, fall back to one conversion. */
1609 if ((UWtype)u == u)
4a73d865 1610 return (FSTYPE)(UWtype)u;
d7735880
JM
1611
1612 /* Otherwise, find the power of two. */
1613 UWtype hi = u >> W_TYPE_SIZE;
1614
1615 UWtype count, shift;
1616 count_leading_zeros (count, hi);
1617
1618 shift = W_TYPE_SIZE - count;
1619
1620 /* Shift down the most significant bits. */
1621 hi = u >> shift;
1622
1623 /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
5fb54b91 1624 if ((UWtype)u << (W_TYPE_SIZE - shift))
d7735880
JM
1625 hi |= 1;
1626
1627 /* Convert the one word of data, and rescale. */
5fb54b91
RH
1628 FSTYPE f = hi, e;
1629 if (shift == W_TYPE_SIZE)
1630 e = Wtype_MAXp1_F;
1631 /* The following two cases could be merged if we knew that the target
1632 supported a native unsigned->float conversion. More often, we only
1633 have a signed conversion, and have to add extra fixup code. */
1634 else if (shift == W_TYPE_SIZE - 1)
1635 e = Wtype_MAXp1_F / 2;
1636 else
1637 e = (Wtype)1 << shift;
1638 return f * e;
d7735880
JM
1639#endif
1640}
1641#endif
1642
4e9db8b2 1643#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
3f3d2ec8
JW
1644/* Reenable the normal types, in case limits.h needs them. */
1645#undef char
1646#undef short
1647#undef int
1648#undef long
1649#undef unsigned
1650#undef float
1651#undef double
c07e26bd
RK
1652#undef MIN
1653#undef MAX
a99598c9 1654#include <limits.h>
e0799b34 1655
996ed075 1656UWtype
6da9c622 1657__fixunsxfSI (XFtype a)
e0799b34 1658{
5d0e6486
AO
1659 if (a >= - (DFtype) Wtype_MIN)
1660 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1661 return (Wtype) a;
e0799b34
RS
1662}
1663#endif
1664
4e9db8b2 1665#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
3f3d2ec8
JW
1666/* Reenable the normal types, in case limits.h needs them. */
1667#undef char
1668#undef short
1669#undef int
1670#undef long
1671#undef unsigned
1672#undef float
1673#undef double
c07e26bd
RK
1674#undef MIN
1675#undef MAX
a99598c9 1676#include <limits.h>
203b91b9 1677
996ed075 1678UWtype
6da9c622 1679__fixunsdfSI (DFtype a)
203b91b9 1680{
5d0e6486
AO
1681 if (a >= - (DFtype) Wtype_MIN)
1682 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1683 return (Wtype) a;
203b91b9
RS
1684}
1685#endif
1686
cfa7bd9c 1687#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE
3f3d2ec8
JW
1688/* Reenable the normal types, in case limits.h needs them. */
1689#undef char
1690#undef short
1691#undef int
1692#undef long
1693#undef unsigned
1694#undef float
1695#undef double
c07e26bd
RK
1696#undef MIN
1697#undef MAX
a99598c9 1698#include <limits.h>
203b91b9 1699
996ed075 1700UWtype
6da9c622 1701__fixunssfSI (SFtype a)
203b91b9 1702{
5d0e6486
AO
1703 if (a >= - (SFtype) Wtype_MIN)
1704 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1705 return (Wtype) a;
203b91b9 1706}
17684d46
RG
1707#endif
1708\f
1709/* Integer power helper used from __builtin_powi for non-constant
1710 exponents. */
1711
cfa7bd9c 1712#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \
4e9db8b2
SE
1713 || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \
1714 || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \
1715 || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE)
17684d46
RG
1716# if defined(L_powisf2)
1717# define TYPE SFtype
1718# define NAME __powisf2
1719# elif defined(L_powidf2)
1720# define TYPE DFtype
1721# define NAME __powidf2
1722# elif defined(L_powixf2)
1723# define TYPE XFtype
1724# define NAME __powixf2
1725# elif defined(L_powitf2)
1726# define TYPE TFtype
1727# define NAME __powitf2
1728# endif
1729
0b8495ae
FJ
1730#undef int
1731#undef unsigned
17684d46 1732TYPE
0b8495ae 1733NAME (TYPE x, int m)
17684d46 1734{
0b8495ae 1735 unsigned int n = m < 0 ? -m : m;
17684d46
RG
1736 TYPE y = n % 2 ? x : 1;
1737 while (n >>= 1)
1738 {
1739 x = x * x;
1740 if (n % 2)
1741 y = y * x;
1742 }
1743 return m < 0 ? 1/y : y;
1744}
1745
203b91b9
RS
1746#endif
1747\f
cfa7bd9c 1748#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
4e9db8b2
SE
1749 || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
1750 || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
1751 || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE)
7e7e470f
RH
1752
1753#undef float
1754#undef double
1755#undef long
1756
1757#if defined(L_mulsc3) || defined(L_divsc3)
1758# define MTYPE SFtype
1759# define CTYPE SCtype
1760# define MODE sc
1761# define CEXT f
1762# define NOTRUNC __FLT_EVAL_METHOD__ == 0
1763#elif defined(L_muldc3) || defined(L_divdc3)
1764# define MTYPE DFtype
1765# define CTYPE DCtype
1766# define MODE dc
1767# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64
1768# define CEXT l
1769# define NOTRUNC 1
1770# else
1771# define CEXT
1772# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
1773# endif
1774#elif defined(L_mulxc3) || defined(L_divxc3)
1775# define MTYPE XFtype
1776# define CTYPE XCtype
1777# define MODE xc
1778# define CEXT l
1779# define NOTRUNC 1
1780#elif defined(L_multc3) || defined(L_divtc3)
1781# define MTYPE TFtype
1782# define CTYPE TCtype
1783# define MODE tc
3353afbe
UB
1784# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
1785# define CEXT l
1786# else
1787# define CEXT LIBGCC2_TF_CEXT
1788# endif
7e7e470f
RH
1789# define NOTRUNC 1
1790#else
1791# error
1792#endif
1793
1794#define CONCAT3(A,B,C) _CONCAT3(A,B,C)
1795#define _CONCAT3(A,B,C) A##B##C
1796
1797#define CONCAT2(A,B) _CONCAT2(A,B)
1798#define _CONCAT2(A,B) A##B
1799
1800/* All of these would be present in a full C99 implementation of <math.h>
1801 and <complex.h>. Our problem is that only a few systems have such full
647eea9d 1802 implementations. Further, libgcc_s.so isn't currently linked against
7e7e470f
RH
1803 libm.so, and even for systems that do provide full C99, the extra overhead
1804 of all programs using libgcc having to link against libm. So avoid it. */
1805
1806#define isnan(x) __builtin_expect ((x) != (x), 0)
1807#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1)
1808#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0)
1809
1810#define INFINITY CONCAT2(__builtin_inf, CEXT) ()
1811#define I 1i
1812
1813/* Helpers to make the following code slightly less gross. */
1814#define COPYSIGN CONCAT2(__builtin_copysign, CEXT)
1815#define FABS CONCAT2(__builtin_fabs, CEXT)
1816
1817/* Verify that MTYPE matches up with CEXT. */
1818extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
1819
1820/* Ensure that we've lost any extra precision. */
1821#if NOTRUNC
1822# define TRUNC(x)
1823#else
1824# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x))
1825#endif
1826
1827#if defined(L_mulsc3) || defined(L_muldc3) \
1828 || defined(L_mulxc3) || defined(L_multc3)
1829
1830CTYPE
1831CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1832{
1833 MTYPE ac, bd, ad, bc, x, y;
1834
1835 ac = a * c;
1836 bd = b * d;
1837 ad = a * d;
1838 bc = b * c;
1839
1840 TRUNC (ac);
1841 TRUNC (bd);
1842 TRUNC (ad);
1843 TRUNC (bc);
1844
1845 x = ac - bd;
1846 y = ad + bc;
1847
1848 if (isnan (x) && isnan (y))
1849 {
1850 /* Recover infinities that computed as NaN + iNaN. */
1851 _Bool recalc = 0;
1852 if (isinf (a) || isinf (b))
1853 {
1854 /* z is infinite. "Box" the infinity and change NaNs in
1855 the other factor to 0. */
1856 a = COPYSIGN (isinf (a) ? 1 : 0, a);
1857 b = COPYSIGN (isinf (b) ? 1 : 0, b);
1858 if (isnan (c)) c = COPYSIGN (0, c);
1859 if (isnan (d)) d = COPYSIGN (0, d);
1860 recalc = 1;
1861 }
1862 if (isinf (c) || isinf (d))
1863 {
1864 /* w is infinite. "Box" the infinity and change NaNs in
1865 the other factor to 0. */
1866 c = COPYSIGN (isinf (c) ? 1 : 0, c);
1867 d = COPYSIGN (isinf (d) ? 1 : 0, d);
1868 if (isnan (a)) a = COPYSIGN (0, a);
1869 if (isnan (b)) b = COPYSIGN (0, b);
1870 recalc = 1;
1871 }
1872 if (!recalc
1873 && (isinf (ac) || isinf (bd)
1874 || isinf (ad) || isinf (bc)))
1875 {
1876 /* Recover infinities from overflow by changing NaNs to 0. */
1877 if (isnan (a)) a = COPYSIGN (0, a);
1878 if (isnan (b)) b = COPYSIGN (0, b);
1879 if (isnan (c)) c = COPYSIGN (0, c);
1880 if (isnan (d)) d = COPYSIGN (0, d);
1881 recalc = 1;
1882 }
1883 if (recalc)
1884 {
1885 x = INFINITY * (a * c - b * d);
1886 y = INFINITY * (a * d + b * c);
1887 }
1888 }
1889
1890 return x + I * y;
1891}
1892#endif /* complex multiply */
1893
1894#if defined(L_divsc3) || defined(L_divdc3) \
1895 || defined(L_divxc3) || defined(L_divtc3)
1896
1897CTYPE
1898CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1899{
1900 MTYPE denom, ratio, x, y;
1901
6300f037 1902 /* ??? We can get better behavior from logarithmic scaling instead of
7e7e470f
RH
1903 the division. But that would mean starting to link libgcc against
1904 libm. We could implement something akin to ldexp/frexp as gcc builtins
1905 fairly easily... */
1906 if (FABS (c) < FABS (d))
1907 {
1908 ratio = c / d;
1909 denom = (c * ratio) + d;
1910 x = ((a * ratio) + b) / denom;
1911 y = ((b * ratio) - a) / denom;
1912 }
1913 else
1914 {
1915 ratio = d / c;
1916 denom = (d * ratio) + c;
1917 x = ((b * ratio) + a) / denom;
1918 y = (b - (a * ratio)) / denom;
1919 }
1920
1921 /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
647eea9d 1922 are nonzero/zero, infinite/finite, and finite/infinite. */
7e7e470f
RH
1923 if (isnan (x) && isnan (y))
1924 {
698ac934 1925 if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
7e7e470f
RH
1926 {
1927 x = COPYSIGN (INFINITY, c) * a;
1928 y = COPYSIGN (INFINITY, c) * b;
1929 }
1930 else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
1931 {
1932 a = COPYSIGN (isinf (a) ? 1 : 0, a);
1933 b = COPYSIGN (isinf (b) ? 1 : 0, b);
1934 x = INFINITY * (a * c + b * d);
1935 y = INFINITY * (b * c - a * d);
1936 }
1937 else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
1938 {
1939 c = COPYSIGN (isinf (c) ? 1 : 0, c);
1940 d = COPYSIGN (isinf (d) ? 1 : 0, d);
1941 x = 0.0 * (a * c + b * d);
1942 y = 0.0 * (b * c - a * d);
1943 }
1944 }
1945
1946 return x + I * y;
1947}
1948#endif /* complex divide */
1949
1950#endif /* all complex float routines */
1951\f
ab495388
RS
1952/* From here on down, the routines use normal data types. */
1953
1954#define SItype bogus_type
1955#define USItype bogus_type
1956#define DItype bogus_type
1957#define UDItype bogus_type
1958#define SFtype bogus_type
1959#define DFtype bogus_type
996ed075
JJ
1960#undef Wtype
1961#undef UWtype
1962#undef HWtype
1963#undef UHWtype
1964#undef DWtype
1965#undef UDWtype
ab495388
RS
1966
1967#undef char
1968#undef short
1969#undef int
1970#undef long
1971#undef unsigned
1972#undef float
1973#undef double
9bd23d2c
RS
1974\f
1975#ifdef L__gcc_bcmp
1976
1977/* Like bcmp except the sign is meaningful.
9faa82d8 1978 Result is negative if S1 is less than S2,
9bd23d2c
RS
1979 positive if S1 is greater, 0 if S1 and S2 are equal. */
1980
1981int
299b83b7 1982__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
9bd23d2c
RS
1983{
1984 while (size > 0)
1985 {
b982024e 1986 const unsigned char c1 = *s1++, c2 = *s2++;
9bd23d2c
RS
1987 if (c1 != c2)
1988 return c1 - c2;
1989 size--;
1990 }
1991 return 0;
1992}
ab495388 1993
3fe68d0a
ZW
1994#endif
1995\f
1996/* __eprintf used to be used by GCC's private version of <assert.h>.
1997 We no longer provide that header, but this routine remains in libgcc.a
1998 for binary backward compatibility. Note that it is not included in
1999 the shared version of libgcc. */
2000#ifdef L_eprintf
2001#ifndef inhibit_libc
2002
2003#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2004#include <stdio.h>
2005
2006void
2007__eprintf (const char *string, const char *expression,
2008 unsigned int line, const char *filename)
2009{
2010 fprintf (stderr, string, expression, line, filename);
2011 fflush (stderr);
2012 abort ();
2013}
2014
2015#endif
203b91b9
RS
2016#endif
2017
203b91b9 2018\f
203b91b9
RS
2019#ifdef L_clear_cache
2020/* Clear part of an instruction cache. */
2021
203b91b9 2022void
139fa6f8
MM
2023__clear_cache (char *beg __attribute__((__unused__)),
2024 char *end __attribute__((__unused__)))
203b91b9 2025{
23190837 2026#ifdef CLEAR_INSN_CACHE
e1178973 2027 CLEAR_INSN_CACHE (beg, end);
e1178973 2028#endif /* CLEAR_INSN_CACHE */
203b91b9
RS
2029}
2030
2031#endif /* L_clear_cache */
2032\f
e7a742ec
EB
2033#ifdef L_enable_execute_stack
2034/* Attempt to turn on execute permission for the stack. */
2035
2036#ifdef ENABLE_EXECUTE_STACK
2037 ENABLE_EXECUTE_STACK
2038#else
2039void
2040__enable_execute_stack (void *addr __attribute__((__unused__)))
2041{}
2042#endif /* ENABLE_EXECUTE_STACK */
2043
2044#endif /* L_enable_execute_stack */
2045\f
203b91b9
RS
2046#ifdef L_trampoline
2047
2048/* Jump to a trampoline, loading the static chain address. */
2049
cd985f66 2050#if defined(WINNT) && ! defined(__CYGWIN__)
e3367a77 2051
94c1e7ac 2052int
3e7d8ef1 2053getpagesize (void)
f5ea9817
RK
2054{
2055#ifdef _ALPHA_
2056 return 8192;
2057#else
2058 return 4096;
2059#endif
2060}
2061
272e2587
RK
2062int
2063mprotect (char *addr, int len, int prot)
f5ea9817
RK
2064{
2065 int np, op;
2066
272e2587
RK
2067 if (prot == 7)
2068 np = 0x40;
2069 else if (prot == 5)
2070 np = 0x20;
2071 else if (prot == 4)
2072 np = 0x10;
2073 else if (prot == 3)
2074 np = 0x04;
2075 else if (prot == 1)
2076 np = 0x02;
2077 else if (prot == 0)
2078 np = 0x01;
f5ea9817
RK
2079
2080 if (VirtualProtect (addr, len, np, &op))
2081 return 0;
2082 else
2083 return -1;
f5ea9817
RK
2084}
2085
cd985f66 2086#endif /* WINNT && ! __CYGWIN__ */
f5ea9817 2087
23190837
AJ
2088#ifdef TRANSFER_FROM_TRAMPOLINE
2089TRANSFER_FROM_TRAMPOLINE
203b91b9 2090#endif
203b91b9
RS
2091#endif /* L_trampoline */
2092\f
cae21ae8 2093#ifndef __CYGWIN__
203b91b9
RS
2094#ifdef L__main
2095
2096#include "gbl-ctors.h"
7abc66b1 2097
c06cff95
RS
2098/* Some systems use __main in a way incompatible with its use in gcc, in these
2099 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2100 give the same symbol without quotes for an alternative entry point. You
0f41302f 2101 must define both, or neither. */
c06cff95
RS
2102#ifndef NAME__MAIN
2103#define NAME__MAIN "__main"
2104#define SYMBOL__MAIN __main
2105#endif
203b91b9 2106
7abc66b1 2107#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP)
fe1fd353
JM
2108#undef HAS_INIT_SECTION
2109#define HAS_INIT_SECTION
2110#endif
2111
2112#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
31cf0144
JM
2113
2114/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2115 code to run constructors. In that case, we need to handle EH here, too. */
2116
540ceb67 2117#ifdef EH_FRAME_SECTION_NAME
e4b776a6 2118#include "unwind-dw2-fde.h"
31cf0144
JM
2119extern unsigned char __EH_FRAME_BEGIN__[];
2120#endif
2121
203b91b9
RS
2122/* Run all the global destructors on exit from the program. */
2123
2124void
3e7d8ef1 2125__do_global_dtors (void)
203b91b9 2126{
89cf554b
RS
2127#ifdef DO_GLOBAL_DTORS_BODY
2128 DO_GLOBAL_DTORS_BODY;
2129#else
b40b9d93
MS
2130 static func_ptr *p = __DTOR_LIST__ + 1;
2131 while (*p)
2132 {
2133 p++;
2134 (*(p-1)) ();
2135 }
89cf554b 2136#endif
540ceb67 2137#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
a4ebb0e6
GRK
2138 {
2139 static int completed = 0;
2140 if (! completed)
2141 {
2142 completed = 1;
2143 __deregister_frame_info (__EH_FRAME_BEGIN__);
2144 }
2145 }
31cf0144 2146#endif
203b91b9 2147}
68d69835 2148#endif
203b91b9 2149
fe1fd353 2150#ifndef HAS_INIT_SECTION
203b91b9
RS
2151/* Run all the global constructors on entry to the program. */
2152
203b91b9 2153void
3e7d8ef1 2154__do_global_ctors (void)
203b91b9 2155{
540ceb67 2156#ifdef EH_FRAME_SECTION_NAME
31cf0144
JM
2157 {
2158 static struct object object;
2159 __register_frame_info (__EH_FRAME_BEGIN__, &object);
2160 }
2161#endif
203b91b9 2162 DO_GLOBAL_CTORS_BODY;
a218d5ba 2163 atexit (__do_global_dtors);
203b91b9 2164}
fe1fd353 2165#endif /* no HAS_INIT_SECTION */
203b91b9 2166
fe1fd353 2167#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
203b91b9
RS
2168/* Subroutine called automatically by `main'.
2169 Compiling a global function named `main'
2170 produces an automatic call to this function at the beginning.
2171
2172 For many systems, this routine calls __do_global_ctors.
2173 For systems which support a .init section we use the .init section
2174 to run __do_global_ctors, so we need not do anything here. */
2175
4043d9c1 2176extern void SYMBOL__MAIN (void);
203b91b9 2177void
4043d9c1 2178SYMBOL__MAIN (void)
203b91b9
RS
2179{
2180 /* Support recursive calls to `main': run initializers just once. */
7e6f1890 2181 static int initialized;
203b91b9
RS
2182 if (! initialized)
2183 {
2184 initialized = 1;
2185 __do_global_ctors ();
2186 }
2187}
fe1fd353 2188#endif /* no HAS_INIT_SECTION or INVOKE__main */
203b91b9
RS
2189
2190#endif /* L__main */
cae21ae8 2191#endif /* __CYGWIN__ */
203b91b9 2192\f
ad38743d 2193#ifdef L_ctors
203b91b9
RS
2194
2195#include "gbl-ctors.h"
2196
2197/* Provide default definitions for the lists of constructors and
657be7af
JL
2198 destructors, so that we don't get linker errors. These symbols are
2199 intentionally bss symbols, so that gld and/or collect will provide
2200 the right values. */
203b91b9
RS
2201
2202/* We declare the lists here with two elements each,
657be7af
JL
2203 so that they are valid empty lists if no other definition is loaded.
2204
2205 If we are using the old "set" extensions to have the gnu linker
2206 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2207 must be in the bss/common section.
2208
2209 Long term no port should use those extensions. But many still do. */
b335c2cc 2210#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
aa6ad1a6 2211#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
d15d0264
RS
2212func_ptr __CTOR_LIST__[2] = {0, 0};
2213func_ptr __DTOR_LIST__[2] = {0, 0};
657be7af
JL
2214#else
2215func_ptr __CTOR_LIST__[2];
2216func_ptr __DTOR_LIST__[2];
2217#endif
b335c2cc 2218#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
ad38743d 2219#endif /* L_ctors */
baffad1f 2220#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */
This page took 4.321915 seconds and 5 git commands to generate.