]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/libgcc2.c
Daily bump.
[thirdparty/gcc.git] / gcc / libgcc2.c
CommitLineData
62c63f32 1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
7429c938 3/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
08332e03 4 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
62c63f32 5
f12b58b3 6This file is part of GCC.
62c63f32 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
62c63f32 12
4c9b6e71 13In addition to the permissions in the GNU General Public License, the
14Free Software Foundation gives you unlimited permission to link the
15compiled version of this file into combinations with other programs,
16and to distribute those combinations without any restriction coming
17from the use of this file. (The General Public License restrictions
18do apply in other respects; for example, they cover modification of
19the file, and distribution when not linked into a combine
20executable.)
21
f12b58b3 22GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23WARRANTY; without even the implied warranty of MERCHANTABILITY or
24FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25for more details.
62c63f32 26
27You should have received a copy of the GNU General Public License
f12b58b3 28along with GCC; see the file COPYING. If not, write to the Free
29Software Foundation, 59 Temple Place - Suite 330, Boston, MA
3002111-1307, USA. */
62c63f32 31
395d450a 32
33/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
34 supposedly valid even though this is a "target" file. */
35#include "auto-host.h"
36
62c63f32 37/* It is incorrect to include config.h here, because this file is being
38 compiled for the target, and hence definitions concerning only the host
39 do not apply. */
c538053c 40#include "tconfig.h"
069631e1 41#include "tsystem.h"
805e22b2 42#include "coretypes.h"
43#include "tm.h"
8c304688 44
62c63f32 45/* Don't use `fancy_abort' here even if config.h says to use it. */
46#ifdef abort
47#undef abort
48#endif
49
395d450a 50#ifdef HAVE_GAS_HIDDEN
51#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
52#else
53#define ATTRIBUTE_HIDDEN
54#endif
55
b1e341a2 56#include "libgcc2.h"
62c63f32 57\f
856ba90e 58#ifdef DECLARE_LIBRARY_RENAMES
59 DECLARE_LIBRARY_RENAMES
60#endif
61
f4dbfb4e 62#if defined (L_negdi2)
e40ae714 63DWtype
64__negdi2 (DWtype u)
65{
ec7f942b 66 const DWunion uu = {.ll = u};
67 const DWunion w = { {.low = -uu.s.low,
68 .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
e40ae714 69
70 return w.ll;
71}
72#endif
bec2d490 73
74#ifdef L_addvsi3
578dc367 75Wtype
ad7a5867 76__addvSI3 (Wtype a, Wtype b)
bec2d490 77{
ec7f942b 78 const Wtype w = a + b;
bec2d490 79
80 if (b >= 0 ? w < a : w > a)
81 abort ();
82
83 return w;
87e97de6 84}
ad7a5867 85#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
86SItype
87__addvsi3 (SItype a, SItype b)
88{
89 const SItype w = a + b;
90
91 if (b >= 0 ? w < a : w > a)
92 abort ();
93
94 return w;
95}
96#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
e40ae714 97#endif
bec2d490 98\f
99#ifdef L_addvdi3
578dc367 100DWtype
ad7a5867 101__addvDI3 (DWtype a, DWtype b)
bec2d490 102{
ec7f942b 103 const DWtype w = a + b;
bec2d490 104
105 if (b >= 0 ? w < a : w > a)
106 abort ();
107
108 return w;
109}
110#endif
111\f
112#ifdef L_subvsi3
578dc367 113Wtype
ad7a5867 114__subvSI3 (Wtype a, Wtype b)
bec2d490 115{
ad7a5867 116 const Wtype w = a - b;
bec2d490 117
118 if (b >= 0 ? w > a : w < a)
119 abort ();
120
121 return w;
bec2d490 122}
ad7a5867 123#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
124SItype
125__subvsi3 (SItype a, SItype b)
126{
127 const SItype w = a - b;
128
129 if (b >= 0 ? w > a : w < a)
130 abort ();
131
132 return w;
133}
134#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
bec2d490 135#endif
136\f
137#ifdef L_subvdi3
578dc367 138DWtype
ad7a5867 139__subvDI3 (DWtype a, DWtype b)
bec2d490 140{
ec7f942b 141 const DWtype w = a - b;
bec2d490 142
143 if (b >= 0 ? w > a : w < a)
144 abort ();
145
146 return w;
bec2d490 147}
148#endif
149\f
150#ifdef L_mulvsi3
4772072d 151#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
578dc367 152Wtype
ad7a5867 153__mulvSI3 (Wtype a, Wtype b)
bec2d490 154{
ec7f942b 155 const DWtype w = (DWtype) a * (DWtype) b;
bec2d490 156
0cf3a1b4 157 if ((Wtype) (w >> WORD_SIZE) != (Wtype) w >> (WORD_SIZE - 1))
bec2d490 158 abort ();
159
160 return w;
161}
ad7a5867 162#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
163#undef WORD_SIZE
164#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
165SItype
166__mulvsi3 (SItype a, SItype b)
167{
168 const DItype w = (DItype) a * (DItype) b;
169
170 if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
171 abort ();
172
173 return w;
174}
175#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
bec2d490 176#endif
177\f
178#ifdef L_negvsi2
578dc367 179Wtype
ad7a5867 180__negvSI2 (Wtype a)
bec2d490 181{
ec7f942b 182 const Wtype w = -a;
bec2d490 183
184 if (a >= 0 ? w > 0 : w < 0)
185 abort ();
186
187 return w;
188}
ad7a5867 189#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
190SItype
191__negvsi2 (SItype a)
192{
193 const SItype w = -a;
194
195 if (a >= 0 ? w > 0 : w < 0)
196 abort ();
197
198 return w;
199}
200#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
bec2d490 201#endif
202\f
203#ifdef L_negvdi2
578dc367 204DWtype
ad7a5867 205__negvDI2 (DWtype a)
bec2d490 206{
ec7f942b 207 const DWtype w = -a;
bec2d490 208
209 if (a >= 0 ? w > 0 : w < 0)
210 abort ();
211
8851e806 212 return w;
bec2d490 213}
214#endif
215\f
216#ifdef L_absvsi2
578dc367 217Wtype
ad7a5867 218__absvSI2 (Wtype a)
bec2d490 219{
8851e806 220 Wtype w = a;
bec2d490 221
ad7a5867 222 if (a < 0)
223#ifdef L_negvsi2
224 w = __negvSI2 (a);
225#else
226 w = -a;
227
228 if (w < 0)
229 abort ();
230#endif
231
232 return w;
233}
234#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
235SItype
236__absvsi2 (SItype a)
237{
238 SItype w = a;
239
8851e806 240 if (a < 0)
bec2d490 241#ifdef L_negvsi2
8851e806 242 w = __negvsi2 (a);
bec2d490 243#else
8851e806 244 w = -a;
bec2d490 245
8851e806 246 if (w < 0)
247 abort ();
bec2d490 248#endif
249
250 return w;
251}
ad7a5867 252#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
bec2d490 253#endif
254\f
255#ifdef L_absvdi2
578dc367 256DWtype
ad7a5867 257__absvDI2 (DWtype a)
bec2d490 258{
8851e806 259 DWtype w = a;
bec2d490 260
8851e806 261 if (a < 0)
4772072d 262#ifdef L_negvdi2
ad7a5867 263 w = __negvDI2 (a);
bec2d490 264#else
8851e806 265 w = -a;
bec2d490 266
8851e806 267 if (w < 0)
268 abort ();
bec2d490 269#endif
270
8851e806 271 return w;
bec2d490 272}
273#endif
274\f
275#ifdef L_mulvdi3
4772072d 276#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
578dc367 277DWtype
ad7a5867 278__mulvDI3 (DWtype u, DWtype v)
bec2d490 279{
4772072d 280 /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
281 but the checked multiplication needs only two. */
ec7f942b 282 const DWunion uu = {.ll = u};
283 const DWunion vv = {.ll = v};
bec2d490 284
4772072d 285 if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1))
286 {
287 /* u fits in a single Wtype. */
288 if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
289 {
290 /* v fits in a single Wtype as well. */
291 /* A single multiplication. No overflow risk. */
292 return (DWtype) uu.s.low * (DWtype) vv.s.low;
293 }
294 else
295 {
296 /* Two multiplications. */
ec7f942b 297 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
298 * (UDWtype) (UWtype) vv.s.low};
299 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
300 * (UDWtype) (UWtype) vv.s.high};
4772072d 301
4772072d 302 if (vv.s.high < 0)
303 w1.s.high -= uu.s.low;
304 if (uu.s.low < 0)
305 w1.ll -= vv.ll;
306 w1.ll += (UWtype) w0.s.high;
307 if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
308 {
309 w0.s.high = w1.s.low;
310 return w0.ll;
311 }
312 }
313 }
314 else
315 {
316 if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
317 {
318 /* v fits into a single Wtype. */
319 /* Two multiplications. */
ec7f942b 320 DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
321 * (UDWtype) (UWtype) vv.s.low};
322 DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
323 * (UDWtype) (UWtype) vv.s.low};
4772072d 324
4772072d 325 if (uu.s.high < 0)
326 w1.s.high -= vv.s.low;
327 if (vv.s.low < 0)
328 w1.ll -= uu.ll;
329 w1.ll += (UWtype) w0.s.high;
330 if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
331 {
332 w0.s.high = w1.s.low;
333 return w0.ll;
334 }
335 }
336 else
337 {
338 /* A few sign checks and a single multiplication. */
339 if (uu.s.high >= 0)
340 {
341 if (vv.s.high >= 0)
342 {
343 if (uu.s.high == 0 && vv.s.high == 0)
344 {
ec7f942b 345 const DWtype w = (UDWtype) (UWtype) uu.s.low
346 * (UDWtype) (UWtype) vv.s.low;
4772072d 347 if (__builtin_expect (w >= 0, 1))
348 return w;
349 }
350 }
351 else
352 {
353 if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
354 {
ec7f942b 355 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
356 * (UDWtype) (UWtype) vv.s.low};
4772072d 357
4772072d 358 ww.s.high -= uu.s.low;
359 if (__builtin_expect (ww.s.high < 0, 1))
360 return ww.ll;
361 }
362 }
363 }
364 else
365 {
366 if (vv.s.high >= 0)
367 {
368 if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
369 {
ec7f942b 370 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
371 * (UDWtype) (UWtype) vv.s.low};
4772072d 372
4772072d 373 ww.s.high -= vv.s.low;
374 if (__builtin_expect (ww.s.high < 0, 1))
375 return ww.ll;
376 }
377 }
378 else
379 {
380 if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
381 {
ec7f942b 382 DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
383 * (UDWtype) (UWtype) vv.s.low};
4772072d 384
4772072d 385 ww.s.high -= uu.s.low;
386 ww.s.high -= vv.s.low;
387 if (__builtin_expect (ww.s.high >= 0, 1))
388 return ww.ll;
389 }
390 }
391 }
392 }
393 }
bec2d490 394
4772072d 395 /* Overflow. */
396 abort ();
bec2d490 397}
398#endif
399\f
62c63f32 400
b903337a 401/* Unless shift functions are defined with full ANSI prototypes,
4f195a89 402 parameter b will be promoted to int if word_type is smaller than an int. */
62c63f32 403#ifdef L_lshrdi3
cf378360 404DWtype
405__lshrdi3 (DWtype u, word_type b)
62c63f32 406{
62c63f32 407 if (b == 0)
408 return u;
409
ec7f942b 410 const DWunion uu = {.ll = u};
411 const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
412 DWunion w;
62c63f32 413
62c63f32 414 if (bm <= 0)
415 {
416 w.s.high = 0;
d1138980 417 w.s.low = (UWtype) uu.s.high >> -bm;
62c63f32 418 }
419 else
420 {
ec7f942b 421 const UWtype carries = (UWtype) uu.s.high << bm;
d1138980 422
423 w.s.high = (UWtype) uu.s.high >> b;
424 w.s.low = ((UWtype) uu.s.low >> b) | carries;
62c63f32 425 }
426
427 return w.ll;
428}
429#endif
430
431#ifdef L_ashldi3
cf378360 432DWtype
433__ashldi3 (DWtype u, word_type b)
62c63f32 434{
62c63f32 435 if (b == 0)
436 return u;
437
ec7f942b 438 const DWunion uu = {.ll = u};
439 const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
440 DWunion w;
62c63f32 441
62c63f32 442 if (bm <= 0)
443 {
444 w.s.low = 0;
d1138980 445 w.s.high = (UWtype) uu.s.low << -bm;
62c63f32 446 }
447 else
448 {
ec7f942b 449 const UWtype carries = (UWtype) uu.s.low >> bm;
d1138980 450
451 w.s.low = (UWtype) uu.s.low << b;
452 w.s.high = ((UWtype) uu.s.high << b) | carries;
62c63f32 453 }
454
455 return w.ll;
456}
457#endif
458
459#ifdef L_ashrdi3
cf378360 460DWtype
461__ashrdi3 (DWtype u, word_type b)
62c63f32 462{
62c63f32 463 if (b == 0)
464 return u;
465
ec7f942b 466 const DWunion uu = {.ll = u};
467 const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
468 DWunion w;
62c63f32 469
62c63f32 470 if (bm <= 0)
471 {
472 /* w.s.high = 1..1 or 0..0 */
cf378360 473 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
62c63f32 474 w.s.low = uu.s.high >> -bm;
475 }
476 else
477 {
ec7f942b 478 const UWtype carries = (UWtype) uu.s.high << bm;
d1138980 479
62c63f32 480 w.s.high = uu.s.high >> b;
d1138980 481 w.s.low = ((UWtype) uu.s.low >> b) | carries;
62c63f32 482 }
483
484 return w.ll;
485}
486#endif
487\f
092445b3 488#ifdef L_ffssi2
489#undef int
092445b3 490int
491__ffsSI2 (UWtype u)
492{
493 UWtype count;
494
495 if (u == 0)
496 return 0;
497
498 count_trailing_zeros (count, u);
499 return count + 1;
500}
501#endif
502\f
5e4e1583 503#ifdef L_ffsdi2
7a02b4da 504#undef int
7a02b4da 505int
092445b3 506__ffsDI2 (DWtype u)
5e4e1583 507{
ec7f942b 508 const DWunion uu = {.ll = u};
9ce1b52b 509 UWtype word, count, add;
510
9ce1b52b 511 if (uu.s.low != 0)
512 word = uu.s.low, add = 0;
513 else if (uu.s.high != 0)
514 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
515 else
516 return 0;
517
518 count_trailing_zeros (count, word);
519 return count + add + 1;
5e4e1583 520}
521#endif
522\f
62c63f32 523#ifdef L_muldi3
cf378360 524DWtype
525__muldi3 (DWtype u, DWtype v)
62c63f32 526{
ec7f942b 527 const DWunion uu = {.ll = u};
528 const DWunion vv = {.ll = v};
529 DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
62c63f32 530
cf378360 531 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
532 + (UWtype) uu.s.high * (UWtype) vv.s.low);
62c63f32 533
534 return w.ll;
535}
536#endif
537\f
1b3950b9 538#if (defined (L_udivdi3) || defined (L_divdi3) || \
539 defined (L_umoddi3) || defined (L_moddi3))
6b9d1b54 540#if defined (sdiv_qrnnd)
1b3950b9 541#define L_udiv_w_sdiv
542#endif
6b9d1b54 543#endif
1b3950b9 544
a46ef09f 545#ifdef L_udiv_w_sdiv
b10877f3 546#if defined (sdiv_qrnnd)
1b3950b9 547#if (defined (L_udivdi3) || defined (L_divdi3) || \
548 defined (L_umoddi3) || defined (L_moddi3))
9dae5ac3 549static inline __attribute__ ((__always_inline__))
1b3950b9 550#endif
cf378360 551UWtype
552__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
ba628a68 553{
cf378360 554 UWtype q, r;
555 UWtype c0, c1, b1;
ba628a68 556
cf378360 557 if ((Wtype) d >= 0)
ba628a68 558 {
cf378360 559 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
ba628a68 560 {
778ac06a 561 /* Dividend, divisor, and quotient are nonnegative. */
ba628a68 562 sdiv_qrnnd (q, r, a1, a0, d);
563 }
564 else
565 {
778ac06a 566 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */
cf378360 567 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
778ac06a 568 /* Divide (c1*2^32 + c0) by d. */
ba628a68 569 sdiv_qrnnd (q, r, c1, c0, d);
778ac06a 570 /* Add 2^31 to quotient. */
cf378360 571 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
ba628a68 572 }
573 }
574 else
575 {
576 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
577 c1 = a1 >> 1; /* A/2 */
cf378360 578 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
ba628a68 579
580 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
581 {
582 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
583
584 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
585 if ((d & 1) != 0)
586 {
587 if (r >= q)
588 r = r - q;
589 else if (q - r <= d)
590 {
591 r = r - q + d;
592 q--;
593 }
594 else
595 {
596 r = r - q + 2*d;
597 q -= 2;
598 }
599 }
600 }
601 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
602 {
603 c1 = (b1 - 1) - c1;
604 c0 = ~c0; /* logical NOT */
605
606 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
607
608 q = ~q; /* (A/2)/b1 */
609 r = (b1 - 1) - r;
610
611 r = 2*r + (a0 & 1); /* A/(2*b1) */
612
613 if ((d & 1) != 0)
614 {
615 if (r >= q)
616 r = r - q;
617 else if (q - r <= d)
618 {
619 r = r - q + d;
620 q--;
621 }
622 else
623 {
624 r = r - q + 2*d;
625 q -= 2;
626 }
627 }
628 }
629 else /* Implies c1 = b1 */
630 { /* Hence a1 = d - 1 = 2*b1 - 1 */
631 if (a0 >= -d)
632 {
633 q = -1;
634 r = a0 + d;
635 }
636 else
637 {
638 q = -2;
639 r = a0 + 2*d;
640 }
641 }
642 }
643
644 *rp = r;
645 return q;
646}
b10877f3 647#else
648/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
cf378360 649UWtype
650__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
651 UWtype a1 __attribute__ ((__unused__)),
652 UWtype a0 __attribute__ ((__unused__)),
653 UWtype d __attribute__ ((__unused__)))
73439ee0 654{
655 return 0;
656}
b10877f3 657#endif
ba628a68 658#endif
659\f
a47053cf 660#if (defined (L_udivdi3) || defined (L_divdi3) || \
661 defined (L_umoddi3) || defined (L_moddi3))
662#define L_udivmoddi4
663#endif
664
9ce1b52b 665#ifdef L_clz
666const UQItype __clz_tab[] =
62c63f32 667{
668 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,
669 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,
670 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,
671 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,
672 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,
673 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,
674 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,
675 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,
676};
9ce1b52b 677#endif
6a08d0ab 678\f
679#ifdef L_clzsi2
7a02b4da 680#undef int
7a02b4da 681int
0f186426 682__clzSI2 (UWtype x)
6a08d0ab 683{
395d450a 684 Wtype ret;
6a08d0ab 685
0f186426 686 count_leading_zeros (ret, x);
395d450a 687
688 return ret;
6a08d0ab 689}
690#endif
691\f
692#ifdef L_clzdi2
7a02b4da 693#undef int
7a02b4da 694int
0f186426 695__clzDI2 (UDWtype x)
6a08d0ab 696{
ec7f942b 697 const DWunion uu = {.ll = x};
395d450a 698 UWtype word;
699 Wtype ret, add;
700
0f186426 701 if (uu.s.high)
702 word = uu.s.high, add = 0;
395d450a 703 else
0f186426 704 word = uu.s.low, add = W_TYPE_SIZE;
6a08d0ab 705
395d450a 706 count_leading_zeros (ret, word);
707 return ret + add;
6a08d0ab 708}
709#endif
710\f
711#ifdef L_ctzsi2
7a02b4da 712#undef int
7a02b4da 713int
0f186426 714__ctzSI2 (UWtype x)
6a08d0ab 715{
395d450a 716 Wtype ret;
6a08d0ab 717
395d450a 718 count_trailing_zeros (ret, x);
6a08d0ab 719
395d450a 720 return ret;
6a08d0ab 721}
722#endif
723\f
724#ifdef L_ctzdi2
7a02b4da 725#undef int
7a02b4da 726int
0f186426 727__ctzDI2 (UDWtype x)
6a08d0ab 728{
ec7f942b 729 const DWunion uu = {.ll = x};
395d450a 730 UWtype word;
731 Wtype ret, add;
732
0f186426 733 if (uu.s.low)
734 word = uu.s.low, add = 0;
395d450a 735 else
0f186426 736 word = uu.s.high, add = W_TYPE_SIZE;
6a08d0ab 737
395d450a 738 count_trailing_zeros (ret, word);
739 return ret + add;
6a08d0ab 740}
741#endif
742
395d450a 743#if (defined (L_popcountsi2) || defined (L_popcountdi2) \
744 || defined (L_popcount_tab))
745extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
6a08d0ab 746#endif
747
748#ifdef L_popcount_tab
749const UQItype __popcount_tab[] =
750{
751 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,
752 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,
753 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,
754 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,
755 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,
756 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,
757 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,
758 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,
759};
760#endif
761\f
762#ifdef L_popcountsi2
7a02b4da 763#undef int
7a02b4da 764int
0f186426 765__popcountSI2 (UWtype x)
6a08d0ab 766{
0f186426 767 UWtype i, ret = 0;
768
769 for (i = 0; i < W_TYPE_SIZE; i += 8)
770 ret += __popcount_tab[(x >> i) & 0xff];
771
772 return ret;
6a08d0ab 773}
774#endif
775\f
776#ifdef L_popcountdi2
7a02b4da 777#undef int
7a02b4da 778int
0f186426 779__popcountDI2 (UDWtype x)
6a08d0ab 780{
0f186426 781 UWtype i, ret = 0;
782
783 for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
784 ret += __popcount_tab[(x >> i) & 0xff];
785
786 return ret;
6a08d0ab 787}
788#endif
789\f
790#ifdef L_paritysi2
7a02b4da 791#undef int
7a02b4da 792int
0f186426 793__paritySI2 (UWtype x)
6a08d0ab 794{
0f186426 795#if W_TYPE_SIZE > 64
796# error "fill out the table"
797#endif
798#if W_TYPE_SIZE > 32
799 x ^= x >> 32;
800#endif
801#if W_TYPE_SIZE > 16
802 x ^= x >> 16;
803#endif
804 x ^= x >> 8;
805 x ^= x >> 4;
806 x &= 0xf;
807 return (0x6996 >> x) & 1;
6a08d0ab 808}
809#endif
810\f
811#ifdef L_paritydi2
7a02b4da 812#undef int
7a02b4da 813int
0f186426 814__parityDI2 (UDWtype x)
6a08d0ab 815{
ec7f942b 816 const DWunion uu = {.ll = x};
817 UWtype nx = uu.s.low ^ uu.s.high;
0f186426 818
819#if W_TYPE_SIZE > 64
820# error "fill out the table"
821#endif
822#if W_TYPE_SIZE > 32
823 nx ^= nx >> 32;
824#endif
825#if W_TYPE_SIZE > 16
6a08d0ab 826 nx ^= nx >> 16;
0f186426 827#endif
6a08d0ab 828 nx ^= nx >> 8;
395d450a 829 nx ^= nx >> 4;
9acebba8 830 nx &= 0xf;
831 return (0x6996 >> nx) & 1;
6a08d0ab 832}
833#endif
9ce1b52b 834
835#ifdef L_udivmoddi4
62c63f32 836
a47053cf 837#if (defined (L_udivdi3) || defined (L_divdi3) || \
838 defined (L_umoddi3) || defined (L_moddi3))
9dae5ac3 839static inline __attribute__ ((__always_inline__))
a47053cf 840#endif
cf378360 841UDWtype
842__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
62c63f32 843{
ec7f942b 844 const DWunion nn = {.ll = n};
845 const DWunion dd = {.ll = d};
cf378360 846 DWunion rr;
847 UWtype d0, d1, n0, n1, n2;
848 UWtype q0, q1;
849 UWtype b, bm;
62c63f32 850
62c63f32 851 d0 = dd.s.low;
852 d1 = dd.s.high;
853 n0 = nn.s.low;
854 n1 = nn.s.high;
855
856#if !UDIV_NEEDS_NORMALIZATION
857 if (d1 == 0)
858 {
859 if (d0 > n1)
860 {
861 /* 0q = nn / 0D */
862
863 udiv_qrnnd (q0, n0, n1, n0, d0);
864 q1 = 0;
865
866 /* Remainder in n0. */
867 }
868 else
869 {
870 /* qq = NN / 0d */
871
872 if (d0 == 0)
873 d0 = 1 / d0; /* Divide intentionally by zero. */
874
875 udiv_qrnnd (q1, n1, 0, n1, d0);
876 udiv_qrnnd (q0, n0, n1, n0, d0);
877
878 /* Remainder in n0. */
879 }
880
881 if (rp != 0)
882 {
883 rr.s.low = n0;
884 rr.s.high = 0;
885 *rp = rr.ll;
886 }
887 }
888
889#else /* UDIV_NEEDS_NORMALIZATION */
890
891 if (d1 == 0)
892 {
893 if (d0 > n1)
894 {
895 /* 0q = nn / 0D */
896
897 count_leading_zeros (bm, d0);
898
899 if (bm != 0)
900 {
901 /* Normalize, i.e. make the most significant bit of the
902 denominator set. */
903
904 d0 = d0 << bm;
cf378360 905 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
62c63f32 906 n0 = n0 << bm;
907 }
908
909 udiv_qrnnd (q0, n0, n1, n0, d0);
910 q1 = 0;
911
912 /* Remainder in n0 >> bm. */
913 }
914 else
915 {
916 /* qq = NN / 0d */
917
918 if (d0 == 0)
919 d0 = 1 / d0; /* Divide intentionally by zero. */
920
921 count_leading_zeros (bm, d0);
922
923 if (bm == 0)
924 {
925 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
926 conclude (the most significant bit of n1 is set) /\ (the
927 leading quotient digit q1 = 1).
928
929 This special case is necessary, not an optimization.
cf378360 930 (Shifts counts of W_TYPE_SIZE are undefined.) */
62c63f32 931
932 n1 -= d0;
933 q1 = 1;
934 }
935 else
936 {
937 /* Normalize. */
938
cf378360 939 b = W_TYPE_SIZE - bm;
62c63f32 940
941 d0 = d0 << bm;
942 n2 = n1 >> b;
943 n1 = (n1 << bm) | (n0 >> b);
944 n0 = n0 << bm;
945
946 udiv_qrnnd (q1, n1, n2, n1, d0);
947 }
948
a92771b8 949 /* n1 != d0... */
62c63f32 950
951 udiv_qrnnd (q0, n0, n1, n0, d0);
952
953 /* Remainder in n0 >> bm. */
954 }
955
956 if (rp != 0)
957 {
958 rr.s.low = n0 >> bm;
959 rr.s.high = 0;
960 *rp = rr.ll;
961 }
962 }
963#endif /* UDIV_NEEDS_NORMALIZATION */
964
965 else
966 {
967 if (d1 > n1)
968 {
969 /* 00 = nn / DD */
970
971 q0 = 0;
972 q1 = 0;
973
974 /* Remainder in n1n0. */
975 if (rp != 0)
976 {
977 rr.s.low = n0;
978 rr.s.high = n1;
979 *rp = rr.ll;
980 }
981 }
982 else
983 {
984 /* 0q = NN / dd */
985
986 count_leading_zeros (bm, d1);
987 if (bm == 0)
988 {
989 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
990 conclude (the most significant bit of n1 is set) /\ (the
991 quotient digit q0 = 0 or 1).
992
993 This special case is necessary, not an optimization. */
994
995 /* The condition on the next line takes advantage of that
996 n1 >= d1 (true due to program flow). */
997 if (n1 > d1 || n0 >= d0)
998 {
999 q0 = 1;
1000 sub_ddmmss (n1, n0, n1, n0, d1, d0);
1001 }
1002 else
1003 q0 = 0;
1004
1005 q1 = 0;
1006
1007 if (rp != 0)
1008 {
1009 rr.s.low = n0;
1010 rr.s.high = n1;
1011 *rp = rr.ll;
1012 }
1013 }
1014 else
1015 {
cf378360 1016 UWtype m1, m0;
62c63f32 1017 /* Normalize. */
1018
cf378360 1019 b = W_TYPE_SIZE - bm;
62c63f32 1020
1021 d1 = (d1 << bm) | (d0 >> b);
1022 d0 = d0 << bm;
1023 n2 = n1 >> b;
1024 n1 = (n1 << bm) | (n0 >> b);
1025 n0 = n0 << bm;
1026
1027 udiv_qrnnd (q0, n1, n2, n1, d1);
1028 umul_ppmm (m1, m0, q0, d0);
1029
1030 if (m1 > n1 || (m1 == n1 && m0 > n0))
1031 {
1032 q0--;
1033 sub_ddmmss (m1, m0, m1, m0, d1, d0);
1034 }
1035
1036 q1 = 0;
1037
1038 /* Remainder in (n1n0 - m1m0) >> bm. */
1039 if (rp != 0)
1040 {
1041 sub_ddmmss (n1, n0, n1, n0, m1, m0);
1042 rr.s.low = (n1 << b) | (n0 >> bm);
1043 rr.s.high = n1 >> bm;
1044 *rp = rr.ll;
1045 }
1046 }
1047 }
1048 }
1049
ec7f942b 1050 const DWunion ww = {{.low = q0, .high = q1}};
62c63f32 1051 return ww.ll;
1052}
1053#endif
1054
1055#ifdef L_divdi3
cf378360 1056DWtype
1057__divdi3 (DWtype u, DWtype v)
62c63f32 1058{
60a744a6 1059 word_type c = 0;
ec7f942b 1060 DWunion uu = {.ll = u};
1061 DWunion vv = {.ll = v};
cf378360 1062 DWtype w;
62c63f32 1063
62c63f32 1064 if (uu.s.high < 0)
1065 c = ~c,
f4dbfb4e 1066 uu.ll = -uu.ll;
62c63f32 1067 if (vv.s.high < 0)
1068 c = ~c,
f4dbfb4e 1069 vv.ll = -vv.ll;
62c63f32 1070
cf378360 1071 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
62c63f32 1072 if (c)
f4dbfb4e 1073 w = -w;
62c63f32 1074
1075 return w;
1076}
1077#endif
1078
1079#ifdef L_moddi3
cf378360 1080DWtype
1081__moddi3 (DWtype u, DWtype v)
62c63f32 1082{
60a744a6 1083 word_type c = 0;
ec7f942b 1084 DWunion uu = {.ll = u};
1085 DWunion vv = {.ll = v};
cf378360 1086 DWtype w;
62c63f32 1087
62c63f32 1088 if (uu.s.high < 0)
1089 c = ~c,
f4dbfb4e 1090 uu.ll = -uu.ll;
62c63f32 1091 if (vv.s.high < 0)
f4dbfb4e 1092 vv.ll = -vv.ll;
62c63f32 1093
79cc8081 1094 (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
62c63f32 1095 if (c)
f4dbfb4e 1096 w = -w;
62c63f32 1097
1098 return w;
1099}
1100#endif
1101
1102#ifdef L_umoddi3
cf378360 1103UDWtype
1104__umoddi3 (UDWtype u, UDWtype v)
62c63f32 1105{
cf378360 1106 UDWtype w;
62c63f32 1107
1108 (void) __udivmoddi4 (u, v, &w);
1109
1110 return w;
1111}
1112#endif
1113
1114#ifdef L_udivdi3
cf378360 1115UDWtype
1116__udivdi3 (UDWtype n, UDWtype d)
62c63f32 1117{
cf378360 1118 return __udivmoddi4 (n, d, (UDWtype *) 0);
62c63f32 1119}
1120#endif
1121\f
1122#ifdef L_cmpdi2
61d95568 1123word_type
cf378360 1124__cmpdi2 (DWtype a, DWtype b)
62c63f32 1125{
ec7f942b 1126 const DWunion au = {.ll = a};
1127 const DWunion bu = {.ll = b};
62c63f32 1128
1129 if (au.s.high < bu.s.high)
1130 return 0;
1131 else if (au.s.high > bu.s.high)
1132 return 2;
cf378360 1133 if ((UWtype) au.s.low < (UWtype) bu.s.low)
62c63f32 1134 return 0;
cf378360 1135 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
62c63f32 1136 return 2;
1137 return 1;
1138}
1139#endif
1140
1141#ifdef L_ucmpdi2
61d95568 1142word_type
cf378360 1143__ucmpdi2 (DWtype a, DWtype b)
62c63f32 1144{
ec7f942b 1145 const DWunion au = {.ll = a};
1146 const DWunion bu = {.ll = b};
62c63f32 1147
cf378360 1148 if ((UWtype) au.s.high < (UWtype) bu.s.high)
62c63f32 1149 return 0;
cf378360 1150 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
62c63f32 1151 return 2;
cf378360 1152 if ((UWtype) au.s.low < (UWtype) bu.s.low)
62c63f32 1153 return 0;
cf378360 1154 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
62c63f32 1155 return 2;
1156 return 1;
1157}
1158#endif
1159\f
dd84cabc 1160#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
cf378360 1161#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1162#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
ade0e71b 1163
cf378360 1164DWtype
d1138980 1165__fixunstfDI (TFtype a)
ade0e71b 1166{
ade0e71b 1167 if (a < 0)
1168 return 0;
1169
1170 /* Compute high word of result, as a flonum. */
ec7f942b 1171 const TFtype b = (a / HIGH_WORD_COEFF);
cf378360 1172 /* Convert that to fixed (but not to DWtype!),
ade0e71b 1173 and shift it into the high word. */
ec7f942b 1174 UDWtype v = (UWtype) b;
ade0e71b 1175 v <<= WORD_SIZE;
1176 /* Remove high part from the TFtype, leaving the low part as flonum. */
1177 a -= (TFtype)v;
cf378360 1178 /* Convert that to fixed (but not to DWtype!) and add it in.
ade0e71b 1179 Sometimes A comes out negative. This is significant, since
1180 A has more bits than a long int does. */
1181 if (a < 0)
cf378360 1182 v -= (UWtype) (- a);
ade0e71b 1183 else
cf378360 1184 v += (UWtype) a;
ade0e71b 1185 return v;
1186}
1187#endif
1188
dd84cabc 1189#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
cf378360 1190DWtype
4f195a89 1191__fixtfdi (TFtype a)
ade0e71b 1192{
1193 if (a < 0)
d1138980 1194 return - __fixunstfDI (-a);
1195 return __fixunstfDI (a);
ade0e71b 1196}
1197#endif
1198
77d98cfe 1199#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
cf378360 1200#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1201#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
0e1cc047 1202
cf378360 1203DWtype
d1138980 1204__fixunsxfDI (XFtype a)
0e1cc047 1205{
0e1cc047 1206 if (a < 0)
1207 return 0;
1208
1209 /* Compute high word of result, as a flonum. */
ec7f942b 1210 const XFtype b = (a / HIGH_WORD_COEFF);
cf378360 1211 /* Convert that to fixed (but not to DWtype!),
0e1cc047 1212 and shift it into the high word. */
ec7f942b 1213 UDWtype v = (UWtype) b;
0e1cc047 1214 v <<= WORD_SIZE;
1215 /* Remove high part from the XFtype, leaving the low part as flonum. */
1216 a -= (XFtype)v;
cf378360 1217 /* Convert that to fixed (but not to DWtype!) and add it in.
0e1cc047 1218 Sometimes A comes out negative. This is significant, since
1219 A has more bits than a long int does. */
1220 if (a < 0)
cf378360 1221 v -= (UWtype) (- a);
0e1cc047 1222 else
cf378360 1223 v += (UWtype) a;
0e1cc047 1224 return v;
1225}
1226#endif
1227
77d98cfe 1228#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
cf378360 1229DWtype
4f195a89 1230__fixxfdi (XFtype a)
0e1cc047 1231{
1232 if (a < 0)
d1138980 1233 return - __fixunsxfDI (-a);
1234 return __fixunsxfDI (a);
0e1cc047 1235}
1236#endif
1237
62c63f32 1238#ifdef L_fixunsdfdi
cf378360 1239#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1240#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
62c63f32 1241
cf378360 1242DWtype
d1138980 1243__fixunsdfDI (DFtype a)
62c63f32 1244{
805e22b2 1245 /* Get high part of result. The division here will just moves the radix
1246 point and will not cause any rounding. Then the conversion to integral
1247 type chops result as desired. */
ec7f942b 1248 const UWtype hi = a / HIGH_WORD_COEFF;
62c63f32 1249
805e22b2 1250 /* Get low part of result. Convert `hi' to floating type and scale it back,
1251 then subtract this from the number being converted. This leaves the low
1252 part. Convert that to integral type. */
ec7f942b 1253 const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
805e22b2 1254
1255 /* Assemble result from the two parts. */
1256 return ((UDWtype) hi << WORD_SIZE) | lo;
62c63f32 1257}
1258#endif
1259
1260#ifdef L_fixdfdi
cf378360 1261DWtype
4f195a89 1262__fixdfdi (DFtype a)
62c63f32 1263{
1264 if (a < 0)
d1138980 1265 return - __fixunsdfDI (-a);
1266 return __fixunsdfDI (a);
62c63f32 1267}
1268#endif
1269
1270#ifdef L_fixunssfdi
cf378360 1271#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1272#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
62c63f32 1273
cf378360 1274DWtype
d1138980 1275__fixunssfDI (SFtype original_a)
62c63f32 1276{
ade0e71b 1277 /* Convert the SFtype to a DFtype, because that is surely not going
62c63f32 1278 to lose any bits. Some day someone else can write a faster version
ade0e71b 1279 that avoids converting to DFtype, and verify it really works right. */
ec7f942b 1280 const DFtype a = original_a;
62c63f32 1281
805e22b2 1282 /* Get high part of result. The division here will just moves the radix
1283 point and will not cause any rounding. Then the conversion to integral
1284 type chops result as desired. */
ec7f942b 1285 const UWtype hi = a / HIGH_WORD_COEFF;
62c63f32 1286
805e22b2 1287 /* Get low part of result. Convert `hi' to floating type and scale it back,
1288 then subtract this from the number being converted. This leaves the low
1289 part. Convert that to integral type. */
ec7f942b 1290 const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
805e22b2 1291
1292 /* Assemble result from the two parts. */
1293 return ((UDWtype) hi << WORD_SIZE) | lo;
62c63f32 1294}
1295#endif
1296
1297#ifdef L_fixsfdi
cf378360 1298DWtype
ade0e71b 1299__fixsfdi (SFtype a)
62c63f32 1300{
1301 if (a < 0)
d1138980 1302 return - __fixunssfDI (-a);
1303 return __fixunssfDI (a);
62c63f32 1304}
1305#endif
1306
77d98cfe 1307#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
cf378360 1308#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1309#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1310#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
0e1cc047 1311
1312XFtype
cf378360 1313__floatdixf (DWtype u)
0e1cc047 1314{
ec7f942b 1315 XFtype d = (Wtype) (u >> WORD_SIZE);
0e1cc047 1316 d *= HIGH_HALFWORD_COEFF;
1317 d *= HIGH_HALFWORD_COEFF;
cf378360 1318 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
0e1cc047 1319
997d68fe 1320 return d;
0e1cc047 1321}
1322#endif
1323
dd84cabc 1324#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
cf378360 1325#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1326#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1327#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
ade0e71b 1328
1329TFtype
cf378360 1330__floatditf (DWtype u)
ade0e71b 1331{
ec7f942b 1332 TFtype d = (Wtype) (u >> WORD_SIZE);
ade0e71b 1333 d *= HIGH_HALFWORD_COEFF;
1334 d *= HIGH_HALFWORD_COEFF;
cf378360 1335 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
ade0e71b 1336
997d68fe 1337 return d;
ade0e71b 1338}
1339#endif
1340
62c63f32 1341#ifdef L_floatdidf
cf378360 1342#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1343#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1344#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
62c63f32 1345
ade0e71b 1346DFtype
cf378360 1347__floatdidf (DWtype u)
62c63f32 1348{
ec7f942b 1349 DFtype d = (Wtype) (u >> WORD_SIZE);
62c63f32 1350 d *= HIGH_HALFWORD_COEFF;
1351 d *= HIGH_HALFWORD_COEFF;
cf378360 1352 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
62c63f32 1353
997d68fe 1354 return d;
62c63f32 1355}
1356#endif
1357
1358#ifdef L_floatdisf
cf378360 1359#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1360#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1361#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
87e97de6 1362
536f5fb1 1363#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
badfe841 1364#define DF_SIZE DBL_MANT_DIG
1365#define SF_SIZE FLT_MANT_DIG
62c63f32 1366
ade0e71b 1367SFtype
cf378360 1368__floatdisf (DWtype u)
62c63f32 1369{
b37ebc51 1370 /* Protect against double-rounding error.
1371 Represent any low-order bits, that might be truncated in DFmode,
1372 by a bit that won't be lost. The bit can go in anywhere below the
1373 rounding position of the SFmode. A fixed mask and bit position
1374 handles all usual configurations. It doesn't handle the case
1375 of 128-bit DImode, however. */
1376 if (DF_SIZE < DI_SIZE
1377 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1378 {
d1138980 1379#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
cf378360 1380 if (! (- ((DWtype) 1 << DF_SIZE) < u
1381 && u < ((DWtype) 1 << DF_SIZE)))
b37ebc51 1382 {
d1138980 1383 if ((UDWtype) u & (REP_BIT - 1))
f9c9dcd7 1384 {
1385 u &= ~ (REP_BIT - 1);
1386 u |= REP_BIT;
1387 }
b37ebc51 1388 }
1389 }
ec7f942b 1390 /* Do the calculation in DFmode
1391 so that we don't lose any of the precision of the high word
1392 while multiplying it. */
1393 DFtype f = (Wtype) (u >> WORD_SIZE);
62c63f32 1394 f *= HIGH_HALFWORD_COEFF;
1395 f *= HIGH_HALFWORD_COEFF;
cf378360 1396 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
62c63f32 1397
997d68fe 1398 return (SFtype) f;
62c63f32 1399}
1400#endif
1401
77d98cfe 1402#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80
3873e172 1403/* Reenable the normal types, in case limits.h needs them. */
1404#undef char
1405#undef short
1406#undef int
1407#undef long
1408#undef unsigned
1409#undef float
1410#undef double
35e6d592 1411#undef MIN
1412#undef MAX
ab195728 1413#include <limits.h>
0e1cc047 1414
cf378360 1415UWtype
d1138980 1416__fixunsxfSI (XFtype a)
0e1cc047 1417{
7429c938 1418 if (a >= - (DFtype) Wtype_MIN)
1419 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
cf378360 1420 return (Wtype) a;
0e1cc047 1421}
1422#endif
1423
62c63f32 1424#ifdef L_fixunsdfsi
3873e172 1425/* Reenable the normal types, in case limits.h needs them. */
1426#undef char
1427#undef short
1428#undef int
1429#undef long
1430#undef unsigned
1431#undef float
1432#undef double
35e6d592 1433#undef MIN
1434#undef MAX
ab195728 1435#include <limits.h>
62c63f32 1436
cf378360 1437UWtype
d1138980 1438__fixunsdfSI (DFtype a)
62c63f32 1439{
7429c938 1440 if (a >= - (DFtype) Wtype_MIN)
1441 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
cf378360 1442 return (Wtype) a;
62c63f32 1443}
1444#endif
1445
1446#ifdef L_fixunssfsi
3873e172 1447/* Reenable the normal types, in case limits.h needs them. */
1448#undef char
1449#undef short
1450#undef int
1451#undef long
1452#undef unsigned
1453#undef float
1454#undef double
35e6d592 1455#undef MIN
1456#undef MAX
ab195728 1457#include <limits.h>
62c63f32 1458
cf378360 1459UWtype
d1138980 1460__fixunssfSI (SFtype a)
62c63f32 1461{
7429c938 1462 if (a >= - (SFtype) Wtype_MIN)
1463 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
cf378360 1464 return (Wtype) a;
62c63f32 1465}
757c219d 1466#endif
1467\f
1468/* Integer power helper used from __builtin_powi for non-constant
1469 exponents. */
1470
1471#if defined(L_powisf2) || defined(L_powidf2) \
1472 || (defined(L_powixf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80) \
1473 || (defined(L_powitf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1474# if defined(L_powisf2)
1475# define TYPE SFtype
1476# define NAME __powisf2
1477# elif defined(L_powidf2)
1478# define TYPE DFtype
1479# define NAME __powidf2
1480# elif defined(L_powixf2)
1481# define TYPE XFtype
1482# define NAME __powixf2
1483# elif defined(L_powitf2)
1484# define TYPE TFtype
1485# define NAME __powitf2
1486# endif
1487
1488TYPE
1489NAME (TYPE x, Wtype m)
1490{
1491 UWtype n = m < 0 ? -m : m;
1492 TYPE y = n % 2 ? x : 1;
1493 while (n >>= 1)
1494 {
1495 x = x * x;
1496 if (n % 2)
1497 y = y * x;
1498 }
1499 return m < 0 ? 1/y : y;
1500}
1501
62c63f32 1502#endif
1503\f
ade0e71b 1504/* From here on down, the routines use normal data types. */
1505
1506#define SItype bogus_type
1507#define USItype bogus_type
1508#define DItype bogus_type
1509#define UDItype bogus_type
1510#define SFtype bogus_type
1511#define DFtype bogus_type
cf378360 1512#undef Wtype
1513#undef UWtype
1514#undef HWtype
1515#undef UHWtype
1516#undef DWtype
1517#undef UDWtype
ade0e71b 1518
1519#undef char
1520#undef short
1521#undef int
1522#undef long
1523#undef unsigned
1524#undef float
1525#undef double
e674bcb7 1526\f
1527#ifdef L__gcc_bcmp
1528
1529/* Like bcmp except the sign is meaningful.
c3418f42 1530 Result is negative if S1 is less than S2,
e674bcb7 1531 positive if S1 is greater, 0 if S1 and S2 are equal. */
1532
1533int
b1e341a2 1534__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
e674bcb7 1535{
1536 while (size > 0)
1537 {
ec7f942b 1538 const unsigned char c1 = *s1++, c2 = *s2++;
e674bcb7 1539 if (c1 != c2)
1540 return c1 - c2;
1541 size--;
1542 }
1543 return 0;
1544}
ade0e71b 1545
0bad1e66 1546#endif
1547\f
1548/* __eprintf used to be used by GCC's private version of <assert.h>.
1549 We no longer provide that header, but this routine remains in libgcc.a
1550 for binary backward compatibility. Note that it is not included in
1551 the shared version of libgcc. */
1552#ifdef L_eprintf
1553#ifndef inhibit_libc
1554
1555#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1556#include <stdio.h>
1557
1558void
1559__eprintf (const char *string, const char *expression,
1560 unsigned int line, const char *filename)
1561{
1562 fprintf (stderr, string, expression, line, filename);
1563 fflush (stderr);
1564 abort ();
1565}
1566
1567#endif
62c63f32 1568#endif
1569
62c63f32 1570\f
62c63f32 1571#ifdef L_clear_cache
1572/* Clear part of an instruction cache. */
1573
62c63f32 1574void
abbe5a3d 1575__clear_cache (char *beg __attribute__((__unused__)),
1576 char *end __attribute__((__unused__)))
62c63f32 1577{
87e97de6 1578#ifdef CLEAR_INSN_CACHE
efa58f1a 1579 CLEAR_INSN_CACHE (beg, end);
efa58f1a 1580#endif /* CLEAR_INSN_CACHE */
62c63f32 1581}
1582
1583#endif /* L_clear_cache */
1584\f
5577e296 1585#ifdef L_enable_execute_stack
1586/* Attempt to turn on execute permission for the stack. */
1587
1588#ifdef ENABLE_EXECUTE_STACK
1589 ENABLE_EXECUTE_STACK
1590#else
1591void
1592__enable_execute_stack (void *addr __attribute__((__unused__)))
1593{}
1594#endif /* ENABLE_EXECUTE_STACK */
1595
1596#endif /* L_enable_execute_stack */
1597\f
62c63f32 1598#ifdef L_trampoline
1599
1600/* Jump to a trampoline, loading the static chain address. */
1601
f1959ea2 1602#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
8e782fcd 1603
4281d316 1604int
71218a21 1605getpagesize (void)
e30b7e49 1606{
1607#ifdef _ALPHA_
1608 return 8192;
1609#else
1610 return 4096;
1611#endif
1612}
1613
1ec6144c 1614#ifdef __i386__
bdf89453 1615extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1616#endif
1617
38e911c3 1618int
1619mprotect (char *addr, int len, int prot)
e30b7e49 1620{
1621 int np, op;
1622
38e911c3 1623 if (prot == 7)
1624 np = 0x40;
1625 else if (prot == 5)
1626 np = 0x20;
1627 else if (prot == 4)
1628 np = 0x10;
1629 else if (prot == 3)
1630 np = 0x04;
1631 else if (prot == 1)
1632 np = 0x02;
1633 else if (prot == 0)
1634 np = 0x01;
e30b7e49 1635
1636 if (VirtualProtect (addr, len, np, &op))
1637 return 0;
1638 else
1639 return -1;
e30b7e49 1640}
1641
f1959ea2 1642#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
e30b7e49 1643
87e97de6 1644#ifdef TRANSFER_FROM_TRAMPOLINE
1645TRANSFER_FROM_TRAMPOLINE
62c63f32 1646#endif
62c63f32 1647#endif /* L_trampoline */
1648\f
e678484c 1649#ifndef __CYGWIN__
62c63f32 1650#ifdef L__main
1651
1652#include "gbl-ctors.h"
0c945479 1653/* Some systems use __main in a way incompatible with its use in gcc, in these
1654 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1655 give the same symbol without quotes for an alternative entry point. You
a92771b8 1656 must define both, or neither. */
0c945479 1657#ifndef NAME__MAIN
1658#define NAME__MAIN "__main"
1659#define SYMBOL__MAIN __main
1660#endif
62c63f32 1661
8313a782 1662#ifdef INIT_SECTION_ASM_OP
1663#undef HAS_INIT_SECTION
1664#define HAS_INIT_SECTION
1665#endif
1666
1667#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
a6881cf3 1668
1669/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1670 code to run constructors. In that case, we need to handle EH here, too. */
1671
eb86c6db 1672#ifdef EH_FRAME_SECTION_NAME
899c9389 1673#include "unwind-dw2-fde.h"
a6881cf3 1674extern unsigned char __EH_FRAME_BEGIN__[];
1675#endif
1676
62c63f32 1677/* Run all the global destructors on exit from the program. */
1678
1679void
71218a21 1680__do_global_dtors (void)
62c63f32 1681{
3a158972 1682#ifdef DO_GLOBAL_DTORS_BODY
1683 DO_GLOBAL_DTORS_BODY;
1684#else
113f9ca7 1685 static func_ptr *p = __DTOR_LIST__ + 1;
1686 while (*p)
1687 {
1688 p++;
1689 (*(p-1)) ();
1690 }
3a158972 1691#endif
eb86c6db 1692#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
3b1bfdbe 1693 {
1694 static int completed = 0;
1695 if (! completed)
1696 {
1697 completed = 1;
1698 __deregister_frame_info (__EH_FRAME_BEGIN__);
1699 }
1700 }
a6881cf3 1701#endif
62c63f32 1702}
b7c87ff2 1703#endif
62c63f32 1704
8313a782 1705#ifndef HAS_INIT_SECTION
62c63f32 1706/* Run all the global constructors on entry to the program. */
1707
62c63f32 1708void
71218a21 1709__do_global_ctors (void)
62c63f32 1710{
eb86c6db 1711#ifdef EH_FRAME_SECTION_NAME
a6881cf3 1712 {
1713 static struct object object;
1714 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1715 }
1716#endif
62c63f32 1717 DO_GLOBAL_CTORS_BODY;
bd84a596 1718 atexit (__do_global_dtors);
62c63f32 1719}
8313a782 1720#endif /* no HAS_INIT_SECTION */
62c63f32 1721
8313a782 1722#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
62c63f32 1723/* Subroutine called automatically by `main'.
1724 Compiling a global function named `main'
1725 produces an automatic call to this function at the beginning.
1726
1727 For many systems, this routine calls __do_global_ctors.
1728 For systems which support a .init section we use the .init section
1729 to run __do_global_ctors, so we need not do anything here. */
1730
f2dc410e 1731extern void SYMBOL__MAIN (void);
62c63f32 1732void
f2dc410e 1733SYMBOL__MAIN (void)
62c63f32 1734{
1735 /* Support recursive calls to `main': run initializers just once. */
5233d224 1736 static int initialized;
62c63f32 1737 if (! initialized)
1738 {
1739 initialized = 1;
1740 __do_global_ctors ();
1741 }
1742}
8313a782 1743#endif /* no HAS_INIT_SECTION or INVOKE__main */
62c63f32 1744
1745#endif /* L__main */
e678484c 1746#endif /* __CYGWIN__ */
62c63f32 1747\f
a0f2694a 1748#ifdef L_ctors
62c63f32 1749
1750#include "gbl-ctors.h"
1751
1752/* Provide default definitions for the lists of constructors and
98ae6ed6 1753 destructors, so that we don't get linker errors. These symbols are
1754 intentionally bss symbols, so that gld and/or collect will provide
1755 the right values. */
62c63f32 1756
1757/* We declare the lists here with two elements each,
98ae6ed6 1758 so that they are valid empty lists if no other definition is loaded.
1759
1760 If we are using the old "set" extensions to have the gnu linker
1761 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1762 must be in the bss/common section.
1763
1764 Long term no port should use those extensions. But many still do. */
b13ae905 1765#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
e535c327 1766#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
d069195c 1767func_ptr __CTOR_LIST__[2] = {0, 0};
1768func_ptr __DTOR_LIST__[2] = {0, 0};
98ae6ed6 1769#else
1770func_ptr __CTOR_LIST__[2];
1771func_ptr __DTOR_LIST__[2];
1772#endif
b13ae905 1773#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
a0f2694a 1774#endif /* L_ctors */
62c63f32 1775