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