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