]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/libgcc2.c
libgcc2.c (__paritysi2, [...]): Replace last two reduction rounds with a "bit table...
[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;
0c9ed856
RH
667 nx &= 0xf;
668 return (0x6996 >> nx) & 1;
2928cd7a
RH
669}
670#endif
671\f
672#ifdef L_paritydi2
dabb3f04
RH
673#undef int
674extern int __paritydi2 (UDItype x);
675int
2928cd7a
RH
676__paritydi2 (UDItype x)
677{
53585c36 678 UWtype nx = x ^ (x >> 32);
2928cd7a
RH
679 nx ^= nx >> 16;
680 nx ^= nx >> 8;
53585c36 681 nx ^= nx >> 4;
0c9ed856
RH
682 nx &= 0xf;
683 return (0x6996 >> nx) & 1;
2928cd7a
RH
684}
685#endif
d6eacd48
RH
686
687#ifdef L_udivmoddi4
203b91b9 688
536bfcd0
RK
689#if (defined (L_udivdi3) || defined (L_divdi3) || \
690 defined (L_umoddi3) || defined (L_moddi3))
1ab9ba62 691static inline __attribute__ ((__always_inline__))
536bfcd0 692#endif
996ed075
JJ
693UDWtype
694__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
203b91b9 695{
996ed075
JJ
696 DWunion ww;
697 DWunion nn, dd;
698 DWunion rr;
699 UWtype d0, d1, n0, n1, n2;
700 UWtype q0, q1;
701 UWtype b, bm;
203b91b9
RS
702
703 nn.ll = n;
704 dd.ll = d;
705
706 d0 = dd.s.low;
707 d1 = dd.s.high;
708 n0 = nn.s.low;
709 n1 = nn.s.high;
710
711#if !UDIV_NEEDS_NORMALIZATION
712 if (d1 == 0)
713 {
714 if (d0 > n1)
715 {
716 /* 0q = nn / 0D */
717
718 udiv_qrnnd (q0, n0, n1, n0, d0);
719 q1 = 0;
720
721 /* Remainder in n0. */
722 }
723 else
724 {
725 /* qq = NN / 0d */
726
727 if (d0 == 0)
728 d0 = 1 / d0; /* Divide intentionally by zero. */
729
730 udiv_qrnnd (q1, n1, 0, n1, d0);
731 udiv_qrnnd (q0, n0, n1, n0, d0);
732
733 /* Remainder in n0. */
734 }
735
736 if (rp != 0)
737 {
738 rr.s.low = n0;
739 rr.s.high = 0;
740 *rp = rr.ll;
741 }
742 }
743
744#else /* UDIV_NEEDS_NORMALIZATION */
745
746 if (d1 == 0)
747 {
748 if (d0 > n1)
749 {
750 /* 0q = nn / 0D */
751
752 count_leading_zeros (bm, d0);
753
754 if (bm != 0)
755 {
756 /* Normalize, i.e. make the most significant bit of the
757 denominator set. */
758
759 d0 = d0 << bm;
996ed075 760 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
203b91b9
RS
761 n0 = n0 << bm;
762 }
763
764 udiv_qrnnd (q0, n0, n1, n0, d0);
765 q1 = 0;
766
767 /* Remainder in n0 >> bm. */
768 }
769 else
770 {
771 /* qq = NN / 0d */
772
773 if (d0 == 0)
774 d0 = 1 / d0; /* Divide intentionally by zero. */
775
776 count_leading_zeros (bm, d0);
777
778 if (bm == 0)
779 {
780 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
781 conclude (the most significant bit of n1 is set) /\ (the
782 leading quotient digit q1 = 1).
783
784 This special case is necessary, not an optimization.
996ed075 785 (Shifts counts of W_TYPE_SIZE are undefined.) */
203b91b9
RS
786
787 n1 -= d0;
788 q1 = 1;
789 }
790 else
791 {
792 /* Normalize. */
793
996ed075 794 b = W_TYPE_SIZE - bm;
203b91b9
RS
795
796 d0 = d0 << bm;
797 n2 = n1 >> b;
798 n1 = (n1 << bm) | (n0 >> b);
799 n0 = n0 << bm;
800
801 udiv_qrnnd (q1, n1, n2, n1, d0);
802 }
803
0f41302f 804 /* n1 != d0... */
203b91b9
RS
805
806 udiv_qrnnd (q0, n0, n1, n0, d0);
807
808 /* Remainder in n0 >> bm. */
809 }
810
811 if (rp != 0)
812 {
813 rr.s.low = n0 >> bm;
814 rr.s.high = 0;
815 *rp = rr.ll;
816 }
817 }
818#endif /* UDIV_NEEDS_NORMALIZATION */
819
820 else
821 {
822 if (d1 > n1)
823 {
824 /* 00 = nn / DD */
825
826 q0 = 0;
827 q1 = 0;
828
829 /* Remainder in n1n0. */
830 if (rp != 0)
831 {
832 rr.s.low = n0;
833 rr.s.high = n1;
834 *rp = rr.ll;
835 }
836 }
837 else
838 {
839 /* 0q = NN / dd */
840
841 count_leading_zeros (bm, d1);
842 if (bm == 0)
843 {
844 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
845 conclude (the most significant bit of n1 is set) /\ (the
846 quotient digit q0 = 0 or 1).
847
848 This special case is necessary, not an optimization. */
849
850 /* The condition on the next line takes advantage of that
851 n1 >= d1 (true due to program flow). */
852 if (n1 > d1 || n0 >= d0)
853 {
854 q0 = 1;
855 sub_ddmmss (n1, n0, n1, n0, d1, d0);
856 }
857 else
858 q0 = 0;
859
860 q1 = 0;
861
862 if (rp != 0)
863 {
864 rr.s.low = n0;
865 rr.s.high = n1;
866 *rp = rr.ll;
867 }
868 }
869 else
870 {
996ed075 871 UWtype m1, m0;
203b91b9
RS
872 /* Normalize. */
873
996ed075 874 b = W_TYPE_SIZE - bm;
203b91b9
RS
875
876 d1 = (d1 << bm) | (d0 >> b);
877 d0 = d0 << bm;
878 n2 = n1 >> b;
879 n1 = (n1 << bm) | (n0 >> b);
880 n0 = n0 << bm;
881
882 udiv_qrnnd (q0, n1, n2, n1, d1);
883 umul_ppmm (m1, m0, q0, d0);
884
885 if (m1 > n1 || (m1 == n1 && m0 > n0))
886 {
887 q0--;
888 sub_ddmmss (m1, m0, m1, m0, d1, d0);
889 }
890
891 q1 = 0;
892
893 /* Remainder in (n1n0 - m1m0) >> bm. */
894 if (rp != 0)
895 {
896 sub_ddmmss (n1, n0, n1, n0, m1, m0);
897 rr.s.low = (n1 << b) | (n0 >> bm);
898 rr.s.high = n1 >> bm;
899 *rp = rr.ll;
900 }
901 }
902 }
903 }
904
905 ww.s.low = q0;
906 ww.s.high = q1;
907 return ww.ll;
908}
909#endif
910
911#ifdef L_divdi3
996ed075
JJ
912DWtype
913__divdi3 (DWtype u, DWtype v)
203b91b9 914{
b799cfc3 915 word_type c = 0;
996ed075
JJ
916 DWunion uu, vv;
917 DWtype w;
203b91b9
RS
918
919 uu.ll = u;
920 vv.ll = v;
921
922 if (uu.s.high < 0)
923 c = ~c,
b68daef4 924 uu.ll = -uu.ll;
203b91b9
RS
925 if (vv.s.high < 0)
926 c = ~c,
b68daef4 927 vv.ll = -vv.ll;
203b91b9 928
996ed075 929 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
203b91b9 930 if (c)
b68daef4 931 w = -w;
203b91b9
RS
932
933 return w;
934}
935#endif
936
937#ifdef L_moddi3
996ed075
JJ
938DWtype
939__moddi3 (DWtype u, DWtype v)
203b91b9 940{
b799cfc3 941 word_type c = 0;
996ed075
JJ
942 DWunion uu, vv;
943 DWtype w;
203b91b9
RS
944
945 uu.ll = u;
946 vv.ll = v;
947
948 if (uu.s.high < 0)
949 c = ~c,
b68daef4 950 uu.ll = -uu.ll;
203b91b9 951 if (vv.s.high < 0)
b68daef4 952 vv.ll = -vv.ll;
203b91b9
RS
953
954 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
955 if (c)
b68daef4 956 w = -w;
203b91b9
RS
957
958 return w;
959}
960#endif
961
962#ifdef L_umoddi3
996ed075
JJ
963UDWtype
964__umoddi3 (UDWtype u, UDWtype v)
203b91b9 965{
996ed075 966 UDWtype w;
203b91b9
RS
967
968 (void) __udivmoddi4 (u, v, &w);
969
970 return w;
971}
972#endif
973
974#ifdef L_udivdi3
996ed075
JJ
975UDWtype
976__udivdi3 (UDWtype n, UDWtype d)
203b91b9 977{
996ed075 978 return __udivmoddi4 (n, d, (UDWtype *) 0);
203b91b9
RS
979}
980#endif
981\f
982#ifdef L_cmpdi2
4be7c28f 983word_type
996ed075 984__cmpdi2 (DWtype a, DWtype b)
203b91b9 985{
996ed075 986 DWunion au, bu;
203b91b9
RS
987
988 au.ll = a, bu.ll = b;
989
990 if (au.s.high < bu.s.high)
991 return 0;
992 else if (au.s.high > bu.s.high)
993 return 2;
996ed075 994 if ((UWtype) au.s.low < (UWtype) bu.s.low)
203b91b9 995 return 0;
996ed075 996 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
203b91b9
RS
997 return 2;
998 return 1;
999}
1000#endif
1001
1002#ifdef L_ucmpdi2
4be7c28f 1003word_type
996ed075 1004__ucmpdi2 (DWtype a, DWtype b)
203b91b9 1005{
996ed075 1006 DWunion au, bu;
203b91b9
RS
1007
1008 au.ll = a, bu.ll = b;
1009
996ed075 1010 if ((UWtype) au.s.high < (UWtype) bu.s.high)
203b91b9 1011 return 0;
996ed075 1012 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
203b91b9 1013 return 2;
996ed075 1014 if ((UWtype) au.s.low < (UWtype) bu.s.low)
203b91b9 1015 return 0;
996ed075 1016 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
203b91b9
RS
1017 return 2;
1018 return 1;
1019}
1020#endif
1021\f
eaa4b44c 1022#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
996ed075
JJ
1023#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1024#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
ab495388 1025
996ed075 1026DWtype
6da9c622 1027__fixunstfDI (TFtype a)
ab495388
RS
1028{
1029 TFtype b;
996ed075 1030 UDWtype v;
ab495388
RS
1031
1032 if (a < 0)
1033 return 0;
1034
1035 /* Compute high word of result, as a flonum. */
1036 b = (a / HIGH_WORD_COEFF);
996ed075 1037 /* Convert that to fixed (but not to DWtype!),
ab495388 1038 and shift it into the high word. */
996ed075 1039 v = (UWtype) b;
ab495388
RS
1040 v <<= WORD_SIZE;
1041 /* Remove high part from the TFtype, leaving the low part as flonum. */
1042 a -= (TFtype)v;
996ed075 1043 /* Convert that to fixed (but not to DWtype!) and add it in.
ab495388
RS
1044 Sometimes A comes out negative. This is significant, since
1045 A has more bits than a long int does. */
1046 if (a < 0)
996ed075 1047 v -= (UWtype) (- a);
ab495388 1048 else
996ed075 1049 v += (UWtype) a;
ab495388
RS
1050 return v;
1051}
1052#endif
1053
eaa4b44c 1054#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
996ed075 1055DWtype
37ef1054 1056__fixtfdi (TFtype a)
ab495388
RS
1057{
1058 if (a < 0)
6da9c622
RK
1059 return - __fixunstfDI (-a);
1060 return __fixunstfDI (a);
ab495388
RS
1061}
1062#endif
1063
eaa4b44c 1064#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
996ed075
JJ
1065#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
e0799b34 1067
996ed075 1068DWtype
6da9c622 1069__fixunsxfDI (XFtype a)
e0799b34
RS
1070{
1071 XFtype b;
996ed075 1072 UDWtype v;
e0799b34
RS
1073
1074 if (a < 0)
1075 return 0;
1076
1077 /* Compute high word of result, as a flonum. */
1078 b = (a / HIGH_WORD_COEFF);
996ed075 1079 /* Convert that to fixed (but not to DWtype!),
e0799b34 1080 and shift it into the high word. */
996ed075 1081 v = (UWtype) b;
e0799b34
RS
1082 v <<= WORD_SIZE;
1083 /* Remove high part from the XFtype, leaving the low part as flonum. */
1084 a -= (XFtype)v;
996ed075 1085 /* Convert that to fixed (but not to DWtype!) and add it in.
e0799b34
RS
1086 Sometimes A comes out negative. This is significant, since
1087 A has more bits than a long int does. */
1088 if (a < 0)
996ed075 1089 v -= (UWtype) (- a);
e0799b34 1090 else
996ed075 1091 v += (UWtype) a;
e0799b34
RS
1092 return v;
1093}
1094#endif
1095
eaa4b44c 1096#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
996ed075 1097DWtype
37ef1054 1098__fixxfdi (XFtype a)
e0799b34
RS
1099{
1100 if (a < 0)
6da9c622
RK
1101 return - __fixunsxfDI (-a);
1102 return __fixunsxfDI (a);
e0799b34
RS
1103}
1104#endif
1105
203b91b9 1106#ifdef L_fixunsdfdi
996ed075
JJ
1107#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1108#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
203b91b9 1109
996ed075 1110DWtype
6da9c622 1111__fixunsdfDI (DFtype a)
203b91b9 1112{
4977bab6 1113 UWtype hi, lo;
203b91b9 1114
4977bab6
ZW
1115 /* Get high part of result. The division here will just moves the radix
1116 point and will not cause any rounding. Then the conversion to integral
1117 type chops result as desired. */
1118 hi = a / HIGH_WORD_COEFF;
203b91b9 1119
4977bab6
ZW
1120 /* Get low part of result. Convert `hi' to floating type and scale it back,
1121 then subtract this from the number being converted. This leaves the low
1122 part. Convert that to integral type. */
1123 lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1124
1125 /* Assemble result from the two parts. */
1126 return ((UDWtype) hi << WORD_SIZE) | lo;
203b91b9
RS
1127}
1128#endif
1129
1130#ifdef L_fixdfdi
996ed075 1131DWtype
37ef1054 1132__fixdfdi (DFtype a)
203b91b9
RS
1133{
1134 if (a < 0)
6da9c622
RK
1135 return - __fixunsdfDI (-a);
1136 return __fixunsdfDI (a);
203b91b9
RS
1137}
1138#endif
1139
1140#ifdef L_fixunssfdi
996ed075
JJ
1141#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1142#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
203b91b9 1143
996ed075 1144DWtype
6da9c622 1145__fixunssfDI (SFtype original_a)
203b91b9 1146{
ab495388 1147 /* Convert the SFtype to a DFtype, because that is surely not going
203b91b9 1148 to lose any bits. Some day someone else can write a faster version
ab495388
RS
1149 that avoids converting to DFtype, and verify it really works right. */
1150 DFtype a = original_a;
4977bab6 1151 UWtype hi, lo;
203b91b9 1152
4977bab6
ZW
1153 /* Get high part of result. The division here will just moves the radix
1154 point and will not cause any rounding. Then the conversion to integral
1155 type chops result as desired. */
1156 hi = a / HIGH_WORD_COEFF;
203b91b9 1157
4977bab6
ZW
1158 /* Get low part of result. Convert `hi' to floating type and scale it back,
1159 then subtract this from the number being converted. This leaves the low
1160 part. Convert that to integral type. */
1161 lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1162
1163 /* Assemble result from the two parts. */
1164 return ((UDWtype) hi << WORD_SIZE) | lo;
203b91b9
RS
1165}
1166#endif
1167
1168#ifdef L_fixsfdi
996ed075 1169DWtype
ab495388 1170__fixsfdi (SFtype a)
203b91b9
RS
1171{
1172 if (a < 0)
6da9c622
RK
1173 return - __fixunssfDI (-a);
1174 return __fixunssfDI (a);
203b91b9
RS
1175}
1176#endif
1177
eaa4b44c 1178#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
996ed075
JJ
1179#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1180#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1181#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
e0799b34
RS
1182
1183XFtype
996ed075 1184__floatdixf (DWtype u)
e0799b34
RS
1185{
1186 XFtype d;
e0799b34 1187
996ed075 1188 d = (Wtype) (u >> WORD_SIZE);
e0799b34
RS
1189 d *= HIGH_HALFWORD_COEFF;
1190 d *= HIGH_HALFWORD_COEFF;
996ed075 1191 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
e0799b34 1192
e5e809f4 1193 return d;
e0799b34
RS
1194}
1195#endif
1196
eaa4b44c 1197#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
996ed075
JJ
1198#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1199#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1200#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
ab495388
RS
1201
1202TFtype
996ed075 1203__floatditf (DWtype u)
ab495388
RS
1204{
1205 TFtype d;
ab495388 1206
996ed075 1207 d = (Wtype) (u >> WORD_SIZE);
ab495388
RS
1208 d *= HIGH_HALFWORD_COEFF;
1209 d *= HIGH_HALFWORD_COEFF;
996ed075 1210 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
ab495388 1211
e5e809f4 1212 return d;
ab495388
RS
1213}
1214#endif
1215
203b91b9 1216#ifdef L_floatdidf
996ed075
JJ
1217#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1218#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1219#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
203b91b9 1220
ab495388 1221DFtype
996ed075 1222__floatdidf (DWtype u)
203b91b9 1223{
ab495388 1224 DFtype d;
203b91b9 1225
996ed075 1226 d = (Wtype) (u >> WORD_SIZE);
203b91b9
RS
1227 d *= HIGH_HALFWORD_COEFF;
1228 d *= HIGH_HALFWORD_COEFF;
996ed075 1229 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
203b91b9 1230
e5e809f4 1231 return d;
203b91b9
RS
1232}
1233#endif
1234
1235#ifdef L_floatdisf
996ed075
JJ
1236#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1237#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1238#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
23190837 1239
15e5ad76 1240#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
b216cd4a
ZW
1241#define DF_SIZE DBL_MANT_DIG
1242#define SF_SIZE FLT_MANT_DIG
203b91b9 1243
ab495388 1244SFtype
996ed075 1245__floatdisf (DWtype u)
203b91b9 1246{
56b03d5f
RS
1247 /* Do the calculation in DFmode
1248 so that we don't lose any of the precision of the high word
1249 while multiplying it. */
1250 DFtype f;
203b91b9 1251
d9e1ab8d
RK
1252 /* Protect against double-rounding error.
1253 Represent any low-order bits, that might be truncated in DFmode,
1254 by a bit that won't be lost. The bit can go in anywhere below the
1255 rounding position of the SFmode. A fixed mask and bit position
1256 handles all usual configurations. It doesn't handle the case
1257 of 128-bit DImode, however. */
1258 if (DF_SIZE < DI_SIZE
1259 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1260 {
6da9c622 1261#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
996ed075
JJ
1262 if (! (- ((DWtype) 1 << DF_SIZE) < u
1263 && u < ((DWtype) 1 << DF_SIZE)))
d9e1ab8d 1264 {
6da9c622 1265 if ((UDWtype) u & (REP_BIT - 1))
cef1c1ba
AM
1266 {
1267 u &= ~ (REP_BIT - 1);
1268 u |= REP_BIT;
1269 }
d9e1ab8d
RK
1270 }
1271 }
996ed075 1272 f = (Wtype) (u >> WORD_SIZE);
203b91b9
RS
1273 f *= HIGH_HALFWORD_COEFF;
1274 f *= HIGH_HALFWORD_COEFF;
996ed075 1275 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
203b91b9 1276
e5e809f4 1277 return (SFtype) f;
203b91b9
RS
1278}
1279#endif
1280
eaa4b44c 1281#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
3f3d2ec8
JW
1282/* Reenable the normal types, in case limits.h needs them. */
1283#undef char
1284#undef short
1285#undef int
1286#undef long
1287#undef unsigned
1288#undef float
1289#undef double
c07e26bd
RK
1290#undef MIN
1291#undef MAX
a99598c9 1292#include <limits.h>
e0799b34 1293
996ed075 1294UWtype
6da9c622 1295__fixunsxfSI (XFtype a)
e0799b34 1296{
5d0e6486
AO
1297 if (a >= - (DFtype) Wtype_MIN)
1298 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1299 return (Wtype) a;
e0799b34
RS
1300}
1301#endif
1302
203b91b9 1303#ifdef L_fixunsdfsi
3f3d2ec8
JW
1304/* Reenable the normal types, in case limits.h needs them. */
1305#undef char
1306#undef short
1307#undef int
1308#undef long
1309#undef unsigned
1310#undef float
1311#undef double
c07e26bd
RK
1312#undef MIN
1313#undef MAX
a99598c9 1314#include <limits.h>
203b91b9 1315
996ed075 1316UWtype
6da9c622 1317__fixunsdfSI (DFtype a)
203b91b9 1318{
5d0e6486
AO
1319 if (a >= - (DFtype) Wtype_MIN)
1320 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1321 return (Wtype) a;
203b91b9
RS
1322}
1323#endif
1324
1325#ifdef L_fixunssfsi
3f3d2ec8
JW
1326/* Reenable the normal types, in case limits.h needs them. */
1327#undef char
1328#undef short
1329#undef int
1330#undef long
1331#undef unsigned
1332#undef float
1333#undef double
c07e26bd
RK
1334#undef MIN
1335#undef MAX
a99598c9 1336#include <limits.h>
203b91b9 1337
996ed075 1338UWtype
6da9c622 1339__fixunssfSI (SFtype a)
203b91b9 1340{
5d0e6486
AO
1341 if (a >= - (SFtype) Wtype_MIN)
1342 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
996ed075 1343 return (Wtype) a;
203b91b9
RS
1344}
1345#endif
1346\f
ab495388
RS
1347/* From here on down, the routines use normal data types. */
1348
1349#define SItype bogus_type
1350#define USItype bogus_type
1351#define DItype bogus_type
1352#define UDItype bogus_type
1353#define SFtype bogus_type
1354#define DFtype bogus_type
996ed075
JJ
1355#undef Wtype
1356#undef UWtype
1357#undef HWtype
1358#undef UHWtype
1359#undef DWtype
1360#undef UDWtype
ab495388
RS
1361
1362#undef char
1363#undef short
1364#undef int
1365#undef long
1366#undef unsigned
1367#undef float
1368#undef double
9bd23d2c
RS
1369\f
1370#ifdef L__gcc_bcmp
1371
1372/* Like bcmp except the sign is meaningful.
9faa82d8 1373 Result is negative if S1 is less than S2,
9bd23d2c
RS
1374 positive if S1 is greater, 0 if S1 and S2 are equal. */
1375
1376int
299b83b7 1377__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
9bd23d2c
RS
1378{
1379 while (size > 0)
1380 {
78e33213 1381 unsigned char c1 = *s1++, c2 = *s2++;
9bd23d2c
RS
1382 if (c1 != c2)
1383 return c1 - c2;
1384 size--;
1385 }
1386 return 0;
1387}
ab495388 1388
3fe68d0a
ZW
1389#endif
1390\f
1391/* __eprintf used to be used by GCC's private version of <assert.h>.
1392 We no longer provide that header, but this routine remains in libgcc.a
1393 for binary backward compatibility. Note that it is not included in
1394 the shared version of libgcc. */
1395#ifdef L_eprintf
1396#ifndef inhibit_libc
1397
1398#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1399#include <stdio.h>
1400
1401void
1402__eprintf (const char *string, const char *expression,
1403 unsigned int line, const char *filename)
1404{
1405 fprintf (stderr, string, expression, line, filename);
1406 fflush (stderr);
1407 abort ();
1408}
1409
1410#endif
203b91b9
RS
1411#endif
1412
203b91b9 1413\f
203b91b9
RS
1414#ifdef L_clear_cache
1415/* Clear part of an instruction cache. */
1416
1417#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1418
1419void
139fa6f8
MM
1420__clear_cache (char *beg __attribute__((__unused__)),
1421 char *end __attribute__((__unused__)))
203b91b9 1422{
23190837 1423#ifdef CLEAR_INSN_CACHE
e1178973
KKT
1424 CLEAR_INSN_CACHE (beg, end);
1425#else
203b91b9
RS
1426#ifdef INSN_CACHE_SIZE
1427 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
7e6f1890 1428 static int initialized;
203b91b9 1429 int offset;
b6422cca
RS
1430 void *start_addr
1431 void *end_addr;
3e7d8ef1 1432 typedef (*function_ptr) (void);
203b91b9
RS
1433
1434#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1435 /* It's cheaper to clear the whole cache.
1436 Put in a series of jump instructions so that calling the beginning
1437 of the cache will clear the whole thing. */
1438
1439 if (! initialized)
1440 {
1441 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1442 & -INSN_CACHE_LINE_WIDTH);
1443 int end_ptr = ptr + INSN_CACHE_SIZE;
1444
1445 while (ptr < end_ptr)
1446 {
1447 *(INSTRUCTION_TYPE *)ptr
1448 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1449 ptr += INSN_CACHE_LINE_WIDTH;
1450 }
0f41302f 1451 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
203b91b9
RS
1452
1453 initialized = 1;
1454 }
1455
1456 /* Call the beginning of the sequence. */
1457 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1458 & -INSN_CACHE_LINE_WIDTH))
1459 ());
1460
1461#else /* Cache is large. */
1462
1463 if (! initialized)
1464 {
1465 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1466 & -INSN_CACHE_LINE_WIDTH);
1467
1468 while (ptr < (int) array + sizeof array)
1469 {
1470 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1471 ptr += INSN_CACHE_LINE_WIDTH;
1472 }
1473
1474 initialized = 1;
1475 }
1476
1477 /* Find the location in array that occupies the same cache line as BEG. */
1478
1479 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1480 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1481 & -INSN_CACHE_PLANE_SIZE)
1482 + offset);
1483
1484 /* Compute the cache alignment of the place to stop clearing. */
1485#if 0 /* This is not needed for gcc's purposes. */
1486 /* If the block to clear is bigger than a cache plane,
23190837 1487 we clear the entire cache, and OFFSET is already correct. */
203b91b9
RS
1488 if (end < beg + INSN_CACHE_PLANE_SIZE)
1489#endif
1490 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1491 & -INSN_CACHE_LINE_WIDTH)
1492 & (INSN_CACHE_PLANE_SIZE - 1));
1493
1494#if INSN_CACHE_DEPTH > 1
1495 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1496 if (end_addr <= start_addr)
1497 end_addr += INSN_CACHE_PLANE_SIZE;
1498
1499 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1500 {
1501 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1502 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1503
1504 while (addr != stop)
1505 {
1506 /* Call the return instruction at ADDR. */
1507 ((function_ptr) addr) ();
1508
1509 addr += INSN_CACHE_LINE_WIDTH;
1510 }
1511 }
1512#else /* just one plane */
1513 do
1514 {
1515 /* Call the return instruction at START_ADDR. */
1516 ((function_ptr) start_addr) ();
1517
1518 start_addr += INSN_CACHE_LINE_WIDTH;
1519 }
1520 while ((start_addr % INSN_CACHE_SIZE) != offset);
1521#endif /* just one plane */
1522#endif /* Cache is large */
1523#endif /* Cache exists */
e1178973 1524#endif /* CLEAR_INSN_CACHE */
203b91b9
RS
1525}
1526
1527#endif /* L_clear_cache */
1528\f
1529#ifdef L_trampoline
1530
1531/* Jump to a trampoline, loading the static chain address. */
1532
b27d2bd5 1533#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
e3367a77 1534
3e7d8ef1
KG
1535long
1536getpagesize (void)
f5ea9817
RK
1537{
1538#ifdef _ALPHA_
1539 return 8192;
1540#else
1541 return 4096;
1542#endif
1543}
1544
d7ebf9ea 1545#ifdef __i386__
e4b15106
RK
1546extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1547#endif
1548
272e2587
RK
1549int
1550mprotect (char *addr, int len, int prot)
f5ea9817
RK
1551{
1552 int np, op;
1553
272e2587
RK
1554 if (prot == 7)
1555 np = 0x40;
1556 else if (prot == 5)
1557 np = 0x20;
1558 else if (prot == 4)
1559 np = 0x10;
1560 else if (prot == 3)
1561 np = 0x04;
1562 else if (prot == 1)
1563 np = 0x02;
1564 else if (prot == 0)
1565 np = 0x01;
f5ea9817
RK
1566
1567 if (VirtualProtect (addr, len, np, &op))
1568 return 0;
1569 else
1570 return -1;
f5ea9817
RK
1571}
1572
b27d2bd5 1573#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
f5ea9817 1574
23190837
AJ
1575#ifdef TRANSFER_FROM_TRAMPOLINE
1576TRANSFER_FROM_TRAMPOLINE
203b91b9
RS
1577#endif
1578
c85f7c16
JL
1579#ifdef __sysV68__
1580
1581#include <sys/signal.h>
1582#include <errno.h>
1583
1584/* Motorola forgot to put memctl.o in the libp version of libc881.a,
1585 so define it here, because we need it in __clear_insn_cache below */
3698f44e
MH
1586/* On older versions of this OS, no memctl or MCT_TEXT are defined;
1587 hence we enable this stuff only if MCT_TEXT is #define'd. */
c85f7c16 1588
3698f44e 1589#ifdef MCT_TEXT
c85f7c16
JL
1590asm("\n\
1591 global memctl\n\
1592memctl:\n\
1593 movq &75,%d0\n\
1594 trap &0\n\
1595 bcc.b noerror\n\
1596 jmp cerror%\n\
1597noerror:\n\
1598 movq &0,%d0\n\
1599 rts");
3698f44e 1600#endif
c85f7c16
JL
1601
1602/* Clear instruction cache so we can call trampolines on stack.
1603 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1604
1605void
3e7d8ef1 1606__clear_insn_cache (void)
c85f7c16 1607{
3698f44e 1608#ifdef MCT_TEXT
c85f7c16
JL
1609 int save_errno;
1610
1611 /* Preserve errno, because users would be surprised to have
dc297297 1612 errno changing without explicitly calling any system-call. */
c85f7c16
JL
1613 save_errno = errno;
1614
23190837 1615 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
dc297297 1616 No need to use an address derived from _start or %sp, as 0 works also. */
c85f7c16
JL
1617 memctl(0, 4096, MCT_TEXT);
1618 errno = save_errno;
3698f44e 1619#endif
c85f7c16
JL
1620}
1621
1622#endif /* __sysV68__ */
203b91b9
RS
1623#endif /* L_trampoline */
1624\f
cae21ae8 1625#ifndef __CYGWIN__
203b91b9
RS
1626#ifdef L__main
1627
1628#include "gbl-ctors.h"
c06cff95
RS
1629/* Some systems use __main in a way incompatible with its use in gcc, in these
1630 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1631 give the same symbol without quotes for an alternative entry point. You
0f41302f 1632 must define both, or neither. */
c06cff95
RS
1633#ifndef NAME__MAIN
1634#define NAME__MAIN "__main"
1635#define SYMBOL__MAIN __main
1636#endif
203b91b9 1637
fe1fd353
JM
1638#ifdef INIT_SECTION_ASM_OP
1639#undef HAS_INIT_SECTION
1640#define HAS_INIT_SECTION
1641#endif
1642
1643#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
31cf0144
JM
1644
1645/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1646 code to run constructors. In that case, we need to handle EH here, too. */
1647
540ceb67 1648#ifdef EH_FRAME_SECTION_NAME
e4b776a6 1649#include "unwind-dw2-fde.h"
31cf0144
JM
1650extern unsigned char __EH_FRAME_BEGIN__[];
1651#endif
1652
203b91b9
RS
1653/* Run all the global destructors on exit from the program. */
1654
1655void
3e7d8ef1 1656__do_global_dtors (void)
203b91b9 1657{
89cf554b
RS
1658#ifdef DO_GLOBAL_DTORS_BODY
1659 DO_GLOBAL_DTORS_BODY;
1660#else
b40b9d93
MS
1661 static func_ptr *p = __DTOR_LIST__ + 1;
1662 while (*p)
1663 {
1664 p++;
1665 (*(p-1)) ();
1666 }
89cf554b 1667#endif
540ceb67 1668#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
a4ebb0e6
GRK
1669 {
1670 static int completed = 0;
1671 if (! completed)
1672 {
1673 completed = 1;
1674 __deregister_frame_info (__EH_FRAME_BEGIN__);
1675 }
1676 }
31cf0144 1677#endif
203b91b9 1678}
68d69835 1679#endif
203b91b9 1680
fe1fd353 1681#ifndef HAS_INIT_SECTION
203b91b9
RS
1682/* Run all the global constructors on entry to the program. */
1683
203b91b9 1684void
3e7d8ef1 1685__do_global_ctors (void)
203b91b9 1686{
540ceb67 1687#ifdef EH_FRAME_SECTION_NAME
31cf0144
JM
1688 {
1689 static struct object object;
1690 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1691 }
1692#endif
203b91b9 1693 DO_GLOBAL_CTORS_BODY;
a218d5ba 1694 atexit (__do_global_dtors);
203b91b9 1695}
fe1fd353 1696#endif /* no HAS_INIT_SECTION */
203b91b9 1697
fe1fd353 1698#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
203b91b9
RS
1699/* Subroutine called automatically by `main'.
1700 Compiling a global function named `main'
1701 produces an automatic call to this function at the beginning.
1702
1703 For many systems, this routine calls __do_global_ctors.
1704 For systems which support a .init section we use the .init section
1705 to run __do_global_ctors, so we need not do anything here. */
1706
1707void
c06cff95 1708SYMBOL__MAIN ()
203b91b9
RS
1709{
1710 /* Support recursive calls to `main': run initializers just once. */
7e6f1890 1711 static int initialized;
203b91b9
RS
1712 if (! initialized)
1713 {
1714 initialized = 1;
1715 __do_global_ctors ();
1716 }
1717}
fe1fd353 1718#endif /* no HAS_INIT_SECTION or INVOKE__main */
203b91b9
RS
1719
1720#endif /* L__main */
cae21ae8 1721#endif /* __CYGWIN__ */
203b91b9 1722\f
ad38743d 1723#ifdef L_ctors
203b91b9
RS
1724
1725#include "gbl-ctors.h"
1726
1727/* Provide default definitions for the lists of constructors and
657be7af
JL
1728 destructors, so that we don't get linker errors. These symbols are
1729 intentionally bss symbols, so that gld and/or collect will provide
1730 the right values. */
203b91b9
RS
1731
1732/* We declare the lists here with two elements each,
657be7af
JL
1733 so that they are valid empty lists if no other definition is loaded.
1734
1735 If we are using the old "set" extensions to have the gnu linker
1736 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1737 must be in the bss/common section.
1738
1739 Long term no port should use those extensions. But many still do. */
b335c2cc 1740#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
aa6ad1a6 1741#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
d15d0264
RS
1742func_ptr __CTOR_LIST__[2] = {0, 0};
1743func_ptr __DTOR_LIST__[2] = {0, 0};
657be7af
JL
1744#else
1745func_ptr __CTOR_LIST__[2];
1746func_ptr __DTOR_LIST__[2];
1747#endif
b335c2cc 1748#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
ad38743d
RS
1749#endif /* L_ctors */
1750\f
1751#ifdef L_exit
1752
1753#include "gbl-ctors.h"
203b91b9 1754
8b7677be 1755#ifdef NEED_ATEXIT
8b7677be 1756
f75e8946 1757#ifndef ON_EXIT
203b91b9 1758
8b7677be
RK
1759# include <errno.h>
1760
920b13cc 1761static func_ptr *atexit_chain = 0;
8b7677be
RK
1762static long atexit_chain_length = 0;
1763static volatile long last_atexit_chain_slot = -1;
1764
c063dc98
JM
1765int
1766atexit (func_ptr func)
8b7677be
RK
1767{
1768 if (++last_atexit_chain_slot == atexit_chain_length)
1769 {
1770 atexit_chain_length += 32;
1771 if (atexit_chain)
a25cea96
RK
1772 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1773 * sizeof (func_ptr));
8b7677be 1774 else
a25cea96
RK
1775 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1776 * sizeof (func_ptr));
8b7677be
RK
1777 if (! atexit_chain)
1778 {
1779 atexit_chain_length = 0;
1780 last_atexit_chain_slot = -1;
1781 errno = ENOMEM;
1782 return (-1);
1783 }
1784 }
1785 atexit_chain[last_atexit_chain_slot] = func;
1786 return (0);
1787}
8b7677be 1788
3e7d8ef1
KG
1789extern void _cleanup (void);
1790extern void _exit (int) __attribute__ ((__noreturn__));
203b91b9 1791
23190837 1792void
37ef1054 1793exit (int status)
203b91b9 1794{
8b7677be
RK
1795 if (atexit_chain)
1796 {
1797 for ( ; last_atexit_chain_slot-- >= 0; )
1798 {
1799 (*atexit_chain[last_atexit_chain_slot + 1]) ();
920b13cc 1800 atexit_chain[last_atexit_chain_slot + 1] = 0;
8b7677be
RK
1801 }
1802 free (atexit_chain);
920b13cc 1803 atexit_chain = 0;
8b7677be 1804 }
203b91b9
RS
1805#ifdef EXIT_BODY
1806 EXIT_BODY;
1807#else
1808 _cleanup ();
1809#endif
1810 _exit (status);
1811}
1812
f75e8946 1813#else /* ON_EXIT */
bceb30e7 1814
c063dc98
JM
1815/* Simple; we just need a wrapper for ON_EXIT. */
1816int
1817atexit (func_ptr func)
bceb30e7 1818{
c063dc98 1819 return ON_EXIT (func);
bceb30e7 1820}
c063dc98 1821
f75e8946 1822#endif /* ON_EXIT */
c063dc98 1823#endif /* NEED_ATEXIT */
203b91b9
RS
1824
1825#endif /* L_exit */