|
|
1.1 root 1: /* More subroutines needed by GCC output code on some machines. */
2: /* Compile this one with gcc. */
3: /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: /* As a special exception, if you link this library with files
22: compiled with GCC to produce an executable, this does not cause
23: the resulting executable to be covered by the GNU General Public License.
24: This exception does not however invalidate any other reasons why
25: the executable file might be covered by the GNU General Public License. */
26:
27: /* It is incorrect to include config.h here, because this file is being
28: compiled for the target, and hence definitions concerning only the host
29: do not apply. */
30:
1.1.1.4 ! root 31: #include "tconfig.h"
! 32: #include "machmode.h"
1.1.1.2 root 33: #ifndef L_trampoline
1.1 root 34: #include "gstddef.h"
1.1.1.2 root 35: #endif
1.1 root 36:
37: /* Don't use `fancy_abort' here even if config.h says to use it. */
38: #ifdef abort
39: #undef abort
40: #endif
41:
1.1.1.4 ! root 42: /* In the first part of this file, we are interfacing to calls generated
! 43: by the compiler itself. These calls pass values into these routines
! 44: which have very specific modes (rather than very specific types), and
! 45: these compiler-generated calls also expect any return values to have
! 46: very specific modes (rather than very specific types). Thus, we need
! 47: to avoid using regular C language type names in this part of the file
! 48: because the sizes for those types can be configured to be anything.
! 49: Instead we use the following special type names. */
! 50:
! 51: typedef unsigned int UQItype __attribute__ ((mode (QI)));
! 52: typedef int SItype __attribute__ ((mode (SI)));
! 53: typedef unsigned int USItype __attribute__ ((mode (SI)));
! 54: typedef int DItype __attribute__ ((mode (DI)));
! 55: typedef unsigned int UDItype __attribute__ ((mode (DI)));
! 56: typedef float SFtype __attribute__ ((mode (SF)));
! 57: typedef float DFtype __attribute__ ((mode (DF)));
! 58: #if 0
! 59: typedef float XFtype __attribute__ ((mode (XF)));
! 60: #endif
! 61: #if LONG_DOUBLE_TYPE_SIZE == 128
! 62: typedef float TFtype __attribute__ ((mode (TF)));
! 63: #endif
! 64:
! 65: /* Make sure that we don't accidentaly use any normal C language built-in
! 66: type names in the first part of this file. Instead we want to use *only*
! 67: the type names defined above. The following macro definitions insure
! 68: that if we *do* accidently use soem normal C language built-in type name,
! 69: we will get a syntax error. */
! 70:
! 71: #define char bogus_type
! 72: #define short bogus_type
! 73: #define int bogus_type
! 74: #define long bogus_type
! 75: #define unsigned bogus_type
! 76: #define float bogus_type
! 77: #define double bogus_type
1.1 root 78:
1.1.1.4 ! root 79: #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1.1 root 80:
1.1.1.4 ! root 81: /* DIstructs are pairs of SItype values in the order determined by
1.1 root 82: WORDS_BIG_ENDIAN. */
83:
84: #if WORDS_BIG_ENDIAN
1.1.1.4 ! root 85: struct DIstruct {SItype high, low;};
1.1 root 86: #else
1.1.1.4 ! root 87: struct DIstruct {SItype low, high;};
1.1 root 88: #endif
89:
1.1.1.4 ! root 90: /* We need this union to unpack/pack DImode values, since we don't have
! 91: any arithmetic yet. Incoming DImode parameters are stored into the
! 92: `ll' field, and the unpacked result is read from the struct `s'. */
1.1 root 93:
94: typedef union
95: {
1.1.1.4 ! root 96: struct DIstruct s;
! 97: DItype ll;
! 98: } DIunion;
1.1 root 99:
1.1.1.4 ! root 100: #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
1.1 root 101:
102: #include "longlong.h"
103:
104: #endif /* udiv or mul */
105:
1.1.1.4 ! root 106: extern DItype __fixunssfdi (SFtype a);
! 107: extern DItype __fixunsdfdi (DFtype a);
1.1 root 108:
109: #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
110: #if defined (L_divdi3) || defined (L_moddi3)
111: static inline
112: #endif
1.1.1.4 ! root 113: DItype
1.1 root 114: __negdi2 (u)
1.1.1.4 ! root 115: DItype u;
1.1 root 116: {
1.1.1.4 ! root 117: DIunion w;
! 118: DIunion uu;
1.1 root 119:
120: uu.ll = u;
121:
122: w.s.low = -uu.s.low;
1.1.1.4 ! root 123: w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
1.1 root 124:
125: return w.ll;
126: }
127: #endif
128:
129: #ifdef L_lshldi3
1.1.1.4 ! root 130: DItype
1.1 root 131: __lshldi3 (u, b)
1.1.1.4 ! root 132: DItype u;
! 133: SItype b;
1.1 root 134: {
1.1.1.4 ! root 135: DIunion w;
! 136: SItype bm;
! 137: DIunion uu;
1.1 root 138:
139: if (b == 0)
140: return u;
141:
142: uu.ll = u;
143:
1.1.1.4 ! root 144: bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
1.1 root 145: if (bm <= 0)
146: {
147: w.s.low = 0;
1.1.1.4 ! root 148: w.s.high = (USItype)uu.s.low << -bm;
1.1 root 149: }
150: else
151: {
1.1.1.4 ! root 152: USItype carries = (USItype)uu.s.low >> bm;
! 153: w.s.low = (USItype)uu.s.low << b;
! 154: w.s.high = ((USItype)uu.s.high << b) | carries;
1.1 root 155: }
156:
157: return w.ll;
158: }
159: #endif
160:
161: #ifdef L_lshrdi3
1.1.1.4 ! root 162: DItype
1.1 root 163: __lshrdi3 (u, b)
1.1.1.4 ! root 164: DItype u;
! 165: SItype b;
1.1 root 166: {
1.1.1.4 ! root 167: DIunion w;
! 168: SItype bm;
! 169: DIunion uu;
1.1 root 170:
171: if (b == 0)
172: return u;
173:
174: uu.ll = u;
175:
1.1.1.4 ! root 176: bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
1.1 root 177: if (bm <= 0)
178: {
179: w.s.high = 0;
1.1.1.4 ! root 180: w.s.low = (USItype)uu.s.high >> -bm;
1.1 root 181: }
182: else
183: {
1.1.1.4 ! root 184: USItype carries = (USItype)uu.s.high << bm;
! 185: w.s.high = (USItype)uu.s.high >> b;
! 186: w.s.low = ((USItype)uu.s.low >> b) | carries;
1.1 root 187: }
188:
189: return w.ll;
190: }
191: #endif
192:
193: #ifdef L_ashldi3
1.1.1.4 ! root 194: DItype
1.1 root 195: __ashldi3 (u, b)
1.1.1.4 ! root 196: DItype u;
! 197: SItype b;
1.1 root 198: {
1.1.1.4 ! root 199: DIunion w;
! 200: SItype bm;
! 201: DIunion uu;
1.1 root 202:
203: if (b == 0)
204: return u;
205:
206: uu.ll = u;
207:
1.1.1.4 ! root 208: bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
1.1 root 209: if (bm <= 0)
210: {
211: w.s.low = 0;
1.1.1.4 ! root 212: w.s.high = (USItype)uu.s.low << -bm;
1.1 root 213: }
214: else
215: {
1.1.1.4 ! root 216: USItype carries = (USItype)uu.s.low >> bm;
! 217: w.s.low = (USItype)uu.s.low << b;
! 218: w.s.high = ((USItype)uu.s.high << b) | carries;
1.1 root 219: }
220:
221: return w.ll;
222: }
223: #endif
224:
225: #ifdef L_ashrdi3
1.1.1.4 ! root 226: DItype
1.1 root 227: __ashrdi3 (u, b)
1.1.1.4 ! root 228: DItype u;
! 229: SItype b;
1.1 root 230: {
1.1.1.4 ! root 231: DIunion w;
! 232: SItype bm;
! 233: DIunion uu;
1.1 root 234:
235: if (b == 0)
236: return u;
237:
238: uu.ll = u;
239:
1.1.1.4 ! root 240: bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
1.1 root 241: if (bm <= 0)
242: {
243: /* w.s.high = 1..1 or 0..0 */
1.1.1.4 ! root 244: w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
1.1 root 245: w.s.low = uu.s.high >> -bm;
246: }
247: else
248: {
1.1.1.4 ! root 249: USItype carries = (USItype)uu.s.high << bm;
1.1 root 250: w.s.high = uu.s.high >> b;
1.1.1.4 ! root 251: w.s.low = ((USItype)uu.s.low >> b) | carries;
1.1 root 252: }
253:
254: return w.ll;
255: }
256: #endif
257:
258: #ifdef L_muldi3
1.1.1.4 ! root 259: DItype
1.1 root 260: __muldi3 (u, v)
1.1.1.4 ! root 261: DItype u, v;
1.1 root 262: {
1.1.1.4 ! root 263: DIunion w;
! 264: DIunion uu, vv;
1.1 root 265:
266: uu.ll = u,
267: vv.ll = v;
268:
269: w.ll = __umulsidi3 (uu.s.low, vv.s.low);
1.1.1.4 ! root 270: w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
! 271: + (USItype) uu.s.high * (USItype) vv.s.low);
1.1 root 272:
273: return w.ll;
274: }
275: #endif
276:
1.1.1.4 ! root 277: #ifdef L_udiv_w_sdiv
! 278: USItype
! 279: __udiv_w_sdiv (rp, a1, a0, d)
! 280: USItype *rp, a1, a0, d;
! 281: {
! 282: USItype q, r;
! 283: USItype c0, c1, b1;
! 284:
! 285: if ((SItype) d >= 0)
! 286: {
! 287: if (a1 < d - a1 - (a0 >> 31))
! 288: {
! 289: /* dividend, divisor, and quotient are nonnegative */
! 290: sdiv_qrnnd (q, r, a1, a0, d);
! 291: }
! 292: else
! 293: {
! 294: /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
! 295: sub_ddmmss (c1, c0, a1, a0, d >> 1, d << 31);
! 296: /* Divide (c1*2^32 + c0) by d */
! 297: sdiv_qrnnd (q, r, c1, c0, d);
! 298: /* Add 2^31 to quotient */
! 299: q += (USItype) 1 << 31;
! 300: }
! 301: }
! 302: else
! 303: {
! 304: b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
! 305: c1 = a1 >> 1; /* A/2 */
! 306: c0 = (a1 << 31) + (a0 >> 1);
! 307:
! 308: if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
! 309: {
! 310: sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
! 311:
! 312: r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
! 313: if ((d & 1) != 0)
! 314: {
! 315: if (r >= q)
! 316: r = r - q;
! 317: else if (q - r <= d)
! 318: {
! 319: r = r - q + d;
! 320: q--;
! 321: }
! 322: else
! 323: {
! 324: r = r - q + 2*d;
! 325: q -= 2;
! 326: }
! 327: }
! 328: }
! 329: else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
! 330: {
! 331: c1 = (b1 - 1) - c1;
! 332: c0 = ~c0; /* logical NOT */
! 333:
! 334: sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
! 335:
! 336: q = ~q; /* (A/2)/b1 */
! 337: r = (b1 - 1) - r;
! 338:
! 339: r = 2*r + (a0 & 1); /* A/(2*b1) */
! 340:
! 341: if ((d & 1) != 0)
! 342: {
! 343: if (r >= q)
! 344: r = r - q;
! 345: else if (q - r <= d)
! 346: {
! 347: r = r - q + d;
! 348: q--;
! 349: }
! 350: else
! 351: {
! 352: r = r - q + 2*d;
! 353: q -= 2;
! 354: }
! 355: }
! 356: }
! 357: else /* Implies c1 = b1 */
! 358: { /* Hence a1 = d - 1 = 2*b1 - 1 */
! 359: if (a0 >= -d)
! 360: {
! 361: q = -1;
! 362: r = a0 + d;
! 363: }
! 364: else
! 365: {
! 366: q = -2;
! 367: r = a0 + 2*d;
! 368: }
! 369: }
! 370: }
! 371:
! 372: *rp = r;
! 373: return q;
! 374: }
! 375: #endif
! 376:
1.1 root 377: #ifdef L_udivmoddi4
1.1.1.4 ! root 378: static const UQItype __clz_tab[] =
1.1 root 379: {
380: 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,
381: 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,
382: 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,
383: 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,
384: 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,
385: 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,
386: 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,
387: 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,
388: };
389:
1.1.1.4 ! root 390: UDItype
1.1 root 391: __udivmoddi4 (n, d, rp)
1.1.1.4 ! root 392: UDItype n, d;
! 393: UDItype *rp;
1.1 root 394: {
1.1.1.4 ! root 395: DIunion ww;
! 396: DIunion nn, dd;
! 397: DIunion rr;
! 398: USItype d0, d1, n0, n1, n2;
! 399: USItype q0, q1;
! 400: USItype b, bm;
1.1 root 401:
402: nn.ll = n;
403: dd.ll = d;
404:
405: d0 = dd.s.low;
406: d1 = dd.s.high;
407: n0 = nn.s.low;
408: n1 = nn.s.high;
409:
410: #if !UDIV_NEEDS_NORMALIZATION
411: if (d1 == 0)
412: {
413: if (d0 > n1)
414: {
415: /* 0q = nn / 0D */
416:
417: udiv_qrnnd (q0, n0, n1, n0, d0);
418: q1 = 0;
419:
420: /* Remainder in n0. */
421: }
422: else
423: {
424: /* qq = NN / 0d */
425:
426: if (d0 == 0)
427: d0 = 1 / d0; /* Divide intentionally by zero. */
428:
429: udiv_qrnnd (q1, n1, 0, n1, d0);
430: udiv_qrnnd (q0, n0, n1, n0, d0);
431:
432: /* Remainder in n0. */
433: }
434:
435: if (rp != 0)
436: {
437: rr.s.low = n0;
438: rr.s.high = 0;
439: *rp = rr.ll;
440: }
441: }
442:
443: #else /* UDIV_NEEDS_NORMALIZATION */
444:
445: if (d1 == 0)
446: {
447: if (d0 > n1)
448: {
449: /* 0q = nn / 0D */
450:
451: count_leading_zeros (bm, d0);
452:
453: if (bm != 0)
454: {
455: /* Normalize, i.e. make the most significant bit of the
456: denominator set. */
457:
458: d0 = d0 << bm;
1.1.1.4 ! root 459: n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
1.1 root 460: n0 = n0 << bm;
461: }
462:
463: udiv_qrnnd (q0, n0, n1, n0, d0);
464: q1 = 0;
465:
466: /* Remainder in n0 >> bm. */
467: }
468: else
469: {
470: /* qq = NN / 0d */
471:
472: if (d0 == 0)
473: d0 = 1 / d0; /* Divide intentionally by zero. */
474:
475: count_leading_zeros (bm, d0);
476:
477: if (bm == 0)
478: {
479: /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
480: conclude (the most significant bit of n1 is set) /\ (the
481: leading quotient digit q1 = 1).
482:
483: This special case is necessary, not an optimization.
1.1.1.4 ! root 484: (Shifts counts of SI_TYPE_SIZE are undefined.) */
1.1 root 485:
486: n1 -= d0;
487: q1 = 1;
488: }
489: else
490: {
491: /* Normalize. */
492:
1.1.1.4 ! root 493: b = SI_TYPE_SIZE - bm;
1.1 root 494:
495: d0 = d0 << bm;
496: n2 = n1 >> b;
497: n1 = (n1 << bm) | (n0 >> b);
498: n0 = n0 << bm;
499:
500: udiv_qrnnd (q1, n1, n2, n1, d0);
501: }
502:
503: /* n1 != d0... */
504:
505: udiv_qrnnd (q0, n0, n1, n0, d0);
506:
507: /* Remainder in n0 >> bm. */
508: }
509:
510: if (rp != 0)
511: {
512: rr.s.low = n0 >> bm;
513: rr.s.high = 0;
514: *rp = rr.ll;
515: }
516: }
517: #endif /* UDIV_NEEDS_NORMALIZATION */
518:
519: else
520: {
521: if (d1 > n1)
522: {
523: /* 00 = nn / DD */
524:
525: q0 = 0;
526: q1 = 0;
527:
528: /* Remainder in n1n0. */
529: if (rp != 0)
530: {
531: rr.s.low = n0;
532: rr.s.high = n1;
533: *rp = rr.ll;
534: }
535: }
536: else
537: {
538: /* 0q = NN / dd */
539:
540: count_leading_zeros (bm, d1);
541: if (bm == 0)
542: {
543: /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
544: conclude (the most significant bit of n1 is set) /\ (the
545: quotient digit q0 = 0 or 1).
546:
547: This special case is necessary, not an optimization. */
548:
549: /* The condition on the next line takes advantage of that
550: n1 >= d1 (true due to program flow). */
551: if (n1 > d1 || n0 >= d0)
552: {
553: q0 = 1;
554: sub_ddmmss (n1, n0, n1, n0, d1, d0);
555: }
556: else
557: q0 = 0;
558:
559: q1 = 0;
560:
561: if (rp != 0)
562: {
563: rr.s.low = n0;
564: rr.s.high = n1;
565: *rp = rr.ll;
566: }
567: }
568: else
569: {
1.1.1.4 ! root 570: USItype m1, m0;
1.1 root 571: /* Normalize. */
572:
1.1.1.4 ! root 573: b = SI_TYPE_SIZE - bm;
1.1 root 574:
575: d1 = (d1 << bm) | (d0 >> b);
576: d0 = d0 << bm;
577: n2 = n1 >> b;
578: n1 = (n1 << bm) | (n0 >> b);
579: n0 = n0 << bm;
580:
581: udiv_qrnnd (q0, n1, n2, n1, d1);
582: umul_ppmm (m1, m0, q0, d0);
583:
584: if (m1 > n1 || (m1 == n1 && m0 > n0))
585: {
586: q0--;
587: sub_ddmmss (m1, m0, m1, m0, d1, d0);
588: }
589:
590: q1 = 0;
591:
592: /* Remainder in (n1n0 - m1m0) >> bm. */
593: if (rp != 0)
594: {
595: sub_ddmmss (n1, n0, n1, n0, m1, m0);
596: rr.s.low = (n1 << b) | (n0 >> bm);
597: rr.s.high = n1 >> bm;
598: *rp = rr.ll;
599: }
600: }
601: }
602: }
603:
604: ww.s.low = q0;
605: ww.s.high = q1;
606: return ww.ll;
607: }
608: #endif
609:
610: #ifdef L_divdi3
1.1.1.4 ! root 611: UDItype __udivmoddi4 ();
! 612: DItype
1.1 root 613: __divdi3 (u, v)
1.1.1.4 ! root 614: DItype u, v;
1.1 root 615: {
1.1.1.4 ! root 616: SItype c = 0;
! 617: DIunion uu, vv;
! 618: DItype w;
1.1 root 619:
620: uu.ll = u;
621: vv.ll = v;
622:
623: if (uu.s.high < 0)
624: c = ~c,
625: uu.ll = __negdi2 (uu.ll);
626: if (vv.s.high < 0)
627: c = ~c,
628: vv.ll = __negdi2 (vv.ll);
629:
1.1.1.4 ! root 630: w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
1.1 root 631: if (c)
632: w = __negdi2 (w);
633:
634: return w;
635: }
636: #endif
637:
638: #ifdef L_moddi3
1.1.1.4 ! root 639: UDItype __udivmoddi4 ();
! 640: DItype
1.1 root 641: __moddi3 (u, v)
1.1.1.4 ! root 642: DItype u, v;
1.1 root 643: {
1.1.1.4 ! root 644: SItype c = 0;
! 645: DIunion uu, vv;
! 646: DItype w;
1.1 root 647:
648: uu.ll = u;
649: vv.ll = v;
650:
651: if (uu.s.high < 0)
652: c = ~c,
653: uu.ll = __negdi2 (uu.ll);
654: if (vv.s.high < 0)
655: vv.ll = __negdi2 (vv.ll);
656:
657: (void) __udivmoddi4 (uu.ll, vv.ll, &w);
658: if (c)
659: w = __negdi2 (w);
660:
661: return w;
662: }
663: #endif
664:
665: #ifdef L_umoddi3
1.1.1.4 ! root 666: UDItype __udivmoddi4 ();
! 667: UDItype
1.1 root 668: __umoddi3 (u, v)
1.1.1.4 ! root 669: UDItype u, v;
1.1 root 670: {
1.1.1.4 ! root 671: DItype w;
1.1 root 672:
673: (void) __udivmoddi4 (u, v, &w);
674:
675: return w;
676: }
677: #endif
678:
679: #ifdef L_udivdi3
1.1.1.4 ! root 680: UDItype __udivmoddi4 ();
! 681: UDItype
1.1 root 682: __udivdi3 (n, d)
1.1.1.4 ! root 683: UDItype n, d;
1.1 root 684: {
1.1.1.4 ! root 685: return __udivmoddi4 (n, d, (UDItype *) 0);
1.1 root 686: }
687: #endif
688:
689: #ifdef L_cmpdi2
690: SItype
691: __cmpdi2 (a, b)
1.1.1.4 ! root 692: DItype a, b;
1.1 root 693: {
1.1.1.4 ! root 694: DIunion au, bu;
1.1 root 695:
696: au.ll = a, bu.ll = b;
697:
698: if (au.s.high < bu.s.high)
699: return 0;
700: else if (au.s.high > bu.s.high)
701: return 2;
1.1.1.4 ! root 702: if ((USItype) au.s.low < (USItype) bu.s.low)
1.1 root 703: return 0;
1.1.1.4 ! root 704: else if ((USItype) au.s.low > (USItype) bu.s.low)
1.1 root 705: return 2;
706: return 1;
707: }
708: #endif
709:
710: #ifdef L_ucmpdi2
711: SItype
712: __ucmpdi2 (a, b)
1.1.1.4 ! root 713: DItype a, b;
1.1 root 714: {
1.1.1.4 ! root 715: DIunion au, bu;
1.1 root 716:
717: au.ll = a, bu.ll = b;
718:
1.1.1.4 ! root 719: if ((USItype) au.s.high < (USItype) bu.s.high)
1.1 root 720: return 0;
1.1.1.4 ! root 721: else if ((USItype) au.s.high > (USItype) bu.s.high)
1.1 root 722: return 2;
1.1.1.4 ! root 723: if ((USItype) au.s.low < (USItype) bu.s.low)
1.1 root 724: return 0;
1.1.1.4 ! root 725: else if ((USItype) au.s.low > (USItype) bu.s.low)
1.1 root 726: return 2;
727: return 1;
728: }
729: #endif
730:
1.1.1.4 ! root 731: #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
! 732: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 733: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
! 734:
! 735: DItype
! 736: __fixunstfdi (a)
! 737: TFtype a;
! 738: {
! 739: TFtype b;
! 740: UDItype v;
! 741:
! 742: if (a < 0)
! 743: return 0;
! 744:
! 745: /* Compute high word of result, as a flonum. */
! 746: b = (a / HIGH_WORD_COEFF);
! 747: /* Convert that to fixed (but not to DItype!),
! 748: and shift it into the high word. */
! 749: v = (USItype) b;
! 750: v <<= WORD_SIZE;
! 751: /* Remove high part from the TFtype, leaving the low part as flonum. */
! 752: a -= (TFtype)v;
! 753: /* Convert that to fixed (but not to DItype!) and add it in.
! 754: Sometimes A comes out negative. This is significant, since
! 755: A has more bits than a long int does. */
! 756: if (a < 0)
! 757: v -= (USItype) (- a);
! 758: else
! 759: v += (USItype) a;
! 760: return v;
! 761: }
! 762: #endif
! 763:
! 764: #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
! 765: DItype
! 766: __fixtfdi (a)
! 767: TFtype a;
! 768: {
! 769: if (a < 0)
! 770: return - __fixunstfdi (-a);
! 771: return __fixunstfdi (a);
! 772: }
! 773: #endif
! 774:
1.1 root 775: #ifdef L_fixunsdfdi
1.1.1.4 ! root 776: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 777: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1.1 root 778:
1.1.1.4 ! root 779: DItype
1.1 root 780: __fixunsdfdi (a)
1.1.1.4 ! root 781: DFtype a;
1.1 root 782: {
1.1.1.4 ! root 783: DFtype b;
! 784: UDItype v;
1.1 root 785:
786: if (a < 0)
787: return 0;
788:
789: /* Compute high word of result, as a flonum. */
790: b = (a / HIGH_WORD_COEFF);
1.1.1.4 ! root 791: /* Convert that to fixed (but not to DItype!),
1.1 root 792: and shift it into the high word. */
1.1.1.4 ! root 793: v = (USItype) b;
1.1 root 794: v <<= WORD_SIZE;
1.1.1.4 ! root 795: /* Remove high part from the DFtype, leaving the low part as flonum. */
! 796: a -= (DFtype)v;
! 797: /* Convert that to fixed (but not to DItype!) and add it in.
1.1 root 798: Sometimes A comes out negative. This is significant, since
799: A has more bits than a long int does. */
800: if (a < 0)
1.1.1.4 ! root 801: v -= (USItype) (- a);
1.1 root 802: else
1.1.1.4 ! root 803: v += (USItype) a;
1.1 root 804: return v;
805: }
806: #endif
807:
808: #ifdef L_fixdfdi
1.1.1.4 ! root 809: DItype
1.1 root 810: __fixdfdi (a)
1.1.1.4 ! root 811: DFtype a;
1.1 root 812: {
813: if (a < 0)
814: return - __fixunsdfdi (-a);
815: return __fixunsdfdi (a);
816: }
817: #endif
818:
819: #ifdef L_fixunssfdi
1.1.1.4 ! root 820: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 821: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1.1 root 822:
1.1.1.4 ! root 823: DItype
! 824: __fixunssfdi (SFtype original_a)
1.1 root 825: {
1.1.1.4 ! root 826: /* Convert the SFtype to a DFtype, because that is surely not going
1.1 root 827: to lose any bits. Some day someone else can write a faster version
1.1.1.4 ! root 828: that avoids converting to DFtype, and verify it really works right. */
! 829: DFtype a = original_a;
! 830: DFtype b;
! 831: UDItype v;
1.1 root 832:
833: if (a < 0)
834: return 0;
835:
836: /* Compute high word of result, as a flonum. */
837: b = (a / HIGH_WORD_COEFF);
1.1.1.4 ! root 838: /* Convert that to fixed (but not to DItype!),
1.1 root 839: and shift it into the high word. */
1.1.1.4 ! root 840: v = (USItype) b;
1.1 root 841: v <<= WORD_SIZE;
1.1.1.4 ! root 842: /* Remove high part from the DFtype, leaving the low part as flonum. */
! 843: a -= (DFtype)v;
! 844: /* Convert that to fixed (but not to DItype!) and add it in.
1.1 root 845: Sometimes A comes out negative. This is significant, since
846: A has more bits than a long int does. */
847: if (a < 0)
1.1.1.4 ! root 848: v -= (USItype) (- a);
1.1 root 849: else
1.1.1.4 ! root 850: v += (USItype) a;
1.1 root 851: return v;
852: }
853: #endif
854:
855: #ifdef L_fixsfdi
1.1.1.4 ! root 856: DItype
! 857: __fixsfdi (SFtype a)
1.1 root 858: {
859: if (a < 0)
860: return - __fixunssfdi (-a);
861: return __fixunssfdi (a);
862: }
863: #endif
864:
1.1.1.4 ! root 865: #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
! 866: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 867: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
! 868: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
! 869:
! 870: TFtype
! 871: __floatditf (u)
! 872: DItype u;
! 873: {
! 874: TFtype d;
! 875: SItype negate = 0;
! 876:
! 877: if (u < 0)
! 878: u = -u, negate = 1;
! 879:
! 880: d = (USItype) (u >> WORD_SIZE);
! 881: d *= HIGH_HALFWORD_COEFF;
! 882: d *= HIGH_HALFWORD_COEFF;
! 883: d += (USItype) (u & (HIGH_WORD_COEFF - 1));
! 884:
! 885: return (negate ? -d : d);
! 886: }
! 887: #endif
! 888:
1.1 root 889: #ifdef L_floatdidf
1.1.1.4 ! root 890: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 891: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
! 892: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1.1 root 893:
1.1.1.4 ! root 894: DFtype
1.1 root 895: __floatdidf (u)
1.1.1.4 ! root 896: DItype u;
1.1 root 897: {
1.1.1.4 ! root 898: DFtype d;
! 899: SItype negate = 0;
1.1 root 900:
901: if (u < 0)
902: u = -u, negate = 1;
903:
1.1.1.4 ! root 904: d = (USItype) (u >> WORD_SIZE);
1.1 root 905: d *= HIGH_HALFWORD_COEFF;
906: d *= HIGH_HALFWORD_COEFF;
1.1.1.4 ! root 907: d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1.1 root 908:
909: return (negate ? -d : d);
910: }
911: #endif
912:
913: #ifdef L_floatdisf
1.1.1.4 ! root 914: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
! 915: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
! 916: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1.1 root 917:
1.1.1.4 ! root 918: SFtype
1.1 root 919: __floatdisf (u)
1.1.1.4 ! root 920: DItype u;
1.1 root 921: {
1.1.1.4 ! root 922: SFtype f;
! 923: SItype negate = 0;
1.1 root 924:
925: if (u < 0)
926: u = -u, negate = 1;
927:
1.1.1.4 ! root 928: f = (USItype) (u >> WORD_SIZE);
1.1 root 929: f *= HIGH_HALFWORD_COEFF;
930: f *= HIGH_HALFWORD_COEFF;
1.1.1.4 ! root 931: f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1.1 root 932:
933: return (negate ? -f : f);
934: }
935: #endif
936:
937: #ifdef L_fixunsdfsi
1.1.1.4 ! root 938: #include "glimits.h"
1.1 root 939:
1.1.1.4 ! root 940: USItype
1.1 root 941: __fixunsdfsi (a)
1.1.1.4 ! root 942: DFtype a;
1.1 root 943: {
1.1.1.4 ! root 944: if (a >= - (DFtype) LONG_MIN)
1.1 root 945: return (SItype) (a + LONG_MIN) - LONG_MIN;
946: return (SItype) a;
947: }
948: #endif
949:
950: #ifdef L_fixunssfsi
1.1.1.4 ! root 951: #include "glimits.h"
1.1 root 952:
1.1.1.4 ! root 953: USItype
! 954: __fixunssfsi (SFtype a)
1.1 root 955: {
1.1.1.4 ! root 956: if (a >= - (SFtype) LONG_MIN)
1.1 root 957: return (SItype) (a + LONG_MIN) - LONG_MIN;
958: return (SItype) a;
959: }
960: #endif
961:
1.1.1.4 ! root 962: /* From here on down, the routines use normal data types. */
! 963:
! 964: #define SItype bogus_type
! 965: #define USItype bogus_type
! 966: #define DItype bogus_type
! 967: #define UDItype bogus_type
! 968: #define SFtype bogus_type
! 969: #define DFtype bogus_type
! 970:
! 971: #undef char
! 972: #undef short
! 973: #undef int
! 974: #undef long
! 975: #undef unsigned
! 976: #undef float
! 977: #undef double
! 978:
! 979: #ifdef L__gcc_bcmp
! 980:
! 981: /* Like bcmp except the sign is meaningful.
! 982: Reult is negative if S1 is less than S2,
! 983: positive if S1 is greater, 0 if S1 and S2 are equal. */
! 984:
! 985: int
! 986: __gcc_bcmp (s1, s2, size)
! 987: unsigned char *s1, *s2;
! 988: size_t size;
! 989: {
! 990: while (size > 0)
! 991: {
! 992: unsigned char c1 = *s1++, c2 = *s2++;
! 993: if (c1 != c2)
! 994: return c1 - c2;
! 995: size--;
! 996: }
! 997: return 0;
! 998: }
! 999:
! 1000: #endif
! 1001:
1.1 root 1002: #ifdef L_varargs
1003: #ifdef __i860__
1.1.1.4 ! root 1004: #if defined(__svr4__) || defined(__alliant__)
1.1 root 1005: asm (" .text");
1006: asm (" .align 4");
1007:
1.1.1.4 ! root 1008: /* The Alliant needs the added underscore. */
1.1 root 1009: asm (".globl __builtin_saveregs");
1010: asm ("__builtin_saveregs:");
1.1.1.4 ! root 1011: asm (".globl ___builtin_saveregs");
! 1012: asm ("___builtin_saveregs:");
! 1013:
! 1014: asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1.1 root 1015: asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1016: area and also for a new va_list
1017: structure */
1018: /* Save all argument registers in the arg reg save area. The
1019: arg reg save area must have the following layout (according
1020: to the svr4 ABI):
1021:
1022: struct {
1023: union {
1024: float freg[8];
1025: double dreg[4];
1026: } float_regs;
1027: long ireg[12];
1028: };
1029: */
1030:
1031: asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1032: asm (" fst.q %f12,16(%sp)");
1033:
1034: asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1035: asm (" st.l %r17,36(%sp)");
1036: asm (" st.l %r18,40(%sp)");
1037: asm (" st.l %r19,44(%sp)");
1038: asm (" st.l %r20,48(%sp)");
1039: asm (" st.l %r21,52(%sp)");
1040: asm (" st.l %r22,56(%sp)");
1041: asm (" st.l %r23,60(%sp)");
1042: asm (" st.l %r24,64(%sp)");
1043: asm (" st.l %r25,68(%sp)");
1044: asm (" st.l %r26,72(%sp)");
1045: asm (" st.l %r27,76(%sp)");
1046:
1047: asm (" adds 80,%sp,%r16"); /* compute the address of the new
1048: va_list structure. Put in into
1049: r16 so that it will be returned
1050: to the caller. */
1051:
1052: /* Initialize all fields of the new va_list structure. This
1053: structure looks like:
1054:
1055: typedef struct {
1056: unsigned long ireg_used;
1057: unsigned long freg_used;
1058: long *reg_base;
1059: long *mem_ptr;
1060: } va_list;
1061: */
1062:
1063: asm (" st.l %r0, 0(%r16)"); /* nfixed */
1064: asm (" st.l %r0, 4(%r16)"); /* nfloating */
1065: asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1066: asm (" bri %r1"); /* delayed return */
1067: asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1068:
1.1.1.4 ! root 1069: #else /* not __SVR4__ */
1.1 root 1070: asm (" .text");
1071: asm (" .align 4");
1072:
1073: asm (".globl ___builtin_saveregs");
1074: asm ("___builtin_saveregs:");
1075: asm (" mov sp,r30");
1076: asm (" andnot 0x0f,sp,sp");
1077: asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1078:
1079: /* Fill in the __va_struct. */
1080: asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1081: asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1082: asm (" st.l r18, 8(sp)");
1083: asm (" st.l r19,12(sp)");
1084: asm (" st.l r20,16(sp)");
1085: asm (" st.l r21,20(sp)");
1086: asm (" st.l r22,24(sp)");
1087: asm (" st.l r23,28(sp)");
1088: asm (" st.l r24,32(sp)");
1089: asm (" st.l r25,36(sp)");
1090: asm (" st.l r26,40(sp)");
1091: asm (" st.l r27,44(sp)");
1092:
1093: asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1094: asm (" fst.q f12,64(sp)"); /* int floating[8] */
1095:
1096: /* Fill in the __va_ctl. */
1097: asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1098: asm (" st.l r28,84(sp)"); /* pointer to more args */
1099: asm (" st.l r0, 88(sp)"); /* nfixed */
1100: asm (" st.l r0, 92(sp)"); /* nfloating */
1101:
1102: asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1103: asm (" bri r1");
1104: asm (" mov r30,sp");
1105: /* recover stack and pass address to start
1106: of data. */
1.1.1.4 ! root 1107: #endif /* not __SVR4__ */
1.1 root 1108: #else /* not __i860__ */
1109: #ifdef __sparc__
1.1.1.2 root 1110: asm (".global __builtin_saveregs");
1111: asm ("__builtin_saveregs:");
1.1 root 1112: asm (".global ___builtin_saveregs");
1113: asm ("___builtin_saveregs:");
1.1.1.3 root 1114: #ifdef NEED_PROC_COMMAND
1115: asm (".proc 020");
1.1.1.2 root 1116: #endif
1.1 root 1117: asm ("st %i0,[%fp+68]");
1118: asm ("st %i1,[%fp+72]");
1119: asm ("st %i2,[%fp+76]");
1120: asm ("st %i3,[%fp+80]");
1121: asm ("st %i4,[%fp+84]");
1122: asm ("retl");
1123: asm ("st %i5,[%fp+88]");
1.1.1.3 root 1124: #ifdef NEED_TYPE_COMMAND
1125: asm (".type __builtin_saveregs,#function");
1126: asm (".size __builtin_saveregs,.-__builtin_saveregs");
1127: #endif
1.1 root 1128: #else /* not __sparc__ */
1129: #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1130:
1131: asm (" .text");
1132: asm (" .ent __builtin_saveregs");
1133: asm (" .globl __builtin_saveregs");
1134: asm ("__builtin_saveregs:");
1135: asm (" sw $4,0($30)");
1136: asm (" sw $5,4($30)");
1137: asm (" sw $6,8($30)");
1138: asm (" sw $7,12($30)");
1139: asm (" j $31");
1140: asm (" .end __builtin_saveregs");
1141: #else /* not __mips__, etc. */
1142: __builtin_saveregs ()
1143: {
1144: abort ();
1145: }
1146: #endif /* not __mips__ */
1147: #endif /* not __sparc__ */
1148: #endif /* not __i860__ */
1149: #endif
1150:
1151: #ifdef L_eprintf
1.1.1.4 ! root 1152: #ifndef inhibit_eprintf
! 1153:
1.1 root 1154: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1155: #include <stdio.h>
1156: /* This is used by the `assert' macro. */
1157: void
1158: __eprintf (string, expression, line, filename)
1.1.1.3 root 1159: const char *string;
1160: const char *expression;
1.1 root 1161: int line;
1.1.1.3 root 1162: const char *filename;
1.1 root 1163: {
1164: fprintf (stderr, string, expression, line, filename);
1165: fflush (stderr);
1166: abort ();
1167: }
1.1.1.4 ! root 1168:
! 1169: #endif
1.1 root 1170: #endif
1171:
1172: #ifdef L_bb
1173: /* Avoid warning from ranlib about empty object file. */
1174: void
1175: __bb_avoid_warning ()
1176: {}
1177:
1178: #if defined (__sun__) && defined (__mc68000__)
1179: struct bb
1180: {
1181: int initialized;
1182: char *filename;
1183: int *counts;
1184: int ncounts;
1185: int zero_word;
1186: int *addresses;
1187: };
1188:
1189: extern int ___tcov_init;
1190:
1191: __bb_init_func (blocks)
1192: struct bb *blocks;
1193: {
1194: if (! ___tcov_init)
1195: ___tcov_init_func ();
1196:
1197: ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1198: }
1199:
1200: #endif
1201: #endif
1202:
1203: /* frills for C++ */
1204:
1205: #ifdef L_builtin_new
1206: typedef void (*vfp)(void);
1207:
1208: extern vfp __new_handler;
1209:
1210: void *
1211: __builtin_new (sz)
1.1.1.3 root 1212: size_t sz;
1.1 root 1213: {
1214: void *p;
1215:
1.1.1.4 ! root 1216: /* malloc (0) is unpredictable; avoid it. */
! 1217: if (sz == 0)
! 1218: sz = 1;
! 1219: p = (void *) malloc (sz);
1.1 root 1220: if (p == 0)
1221: (*__new_handler) ();
1222: return p;
1223: }
1224: #endif
1225:
1.1.1.4 ! root 1226: #ifdef L_caps_New
! 1227:
! 1228: /* This gets us __GNU_LIBRARY__. */
! 1229: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
! 1230: #include <stdio.h>
! 1231:
! 1232: #ifdef __GNU_LIBRARY__
! 1233: /* Avoid forcing the library's meaning of `write' on the user program
! 1234: by using the "internal" name (for use within the library) */
! 1235: #define write(fd, buf, n) __write((fd), (buf), (n))
! 1236: #endif
! 1237:
1.1 root 1238: typedef void (*vfp)(void);
1239:
1.1.1.3 root 1240: extern void *__builtin_new (size_t);
1241: static void default_new_handler (void);
1.1 root 1242:
1243: vfp __new_handler = default_new_handler;
1244:
1245: void *
1246: __builtin_vec_new (p, maxindex, size, ctor)
1247: void *p;
1.1.1.3 root 1248: size_t maxindex;
1249: size_t size;
1.1 root 1250: void (*ctor)(void *);
1251: {
1.1.1.3 root 1252: size_t i;
1253: size_t nelts = maxindex + 1;
1.1 root 1254: void *rval;
1255:
1256: if (p == 0)
1.1.1.3 root 1257: p = __builtin_new (nelts * size);
1.1 root 1258:
1259: rval = p;
1260:
1261: for (i = 0; i < nelts; i++)
1262: {
1263: (*ctor) (p);
1264: p += size;
1265: }
1266:
1267: return rval;
1268: }
1269:
1270: vfp
1271: __set_new_handler (handler)
1272: vfp handler;
1273: {
1274: vfp prev_handler;
1275:
1276: prev_handler = __new_handler;
1277: if (handler == 0) handler = default_new_handler;
1278: __new_handler = handler;
1279: return prev_handler;
1280: }
1281:
1282: vfp
1283: set_new_handler (handler)
1284: vfp handler;
1285: {
1286: return __set_new_handler (handler);
1287: }
1288:
1.1.1.3 root 1289: #define MESSAGE "Virtual memory exceeded in `new'\n"
1290:
1.1 root 1291: static void
1292: default_new_handler ()
1293: {
1294: /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1295: /* This should really print the name of the program, but that is hard to
1296: do. We need a standard, clean way to get at the name. */
1.1.1.3 root 1297: write (2, MESSAGE, sizeof (MESSAGE));
1.1 root 1298: /* don't call exit () because that may call global destructors which
1299: may cause a loop. */
1300: _exit (-1);
1301: }
1302: #endif
1303:
1304: #ifdef L_builtin_del
1305: typedef void (*vfp)(void);
1306:
1307: void
1308: __builtin_delete (ptr)
1309: void *ptr;
1310: {
1311: if (ptr)
1312: free (ptr);
1313: }
1314:
1315: void
1316: __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1317: void *ptr;
1.1.1.3 root 1318: size_t maxindex;
1319: size_t size;
1320: void (*dtor)(void *, int);
1.1 root 1321: int auto_delete;
1322: {
1.1.1.3 root 1323: size_t i;
1324: size_t nelts = maxindex + 1;
1.1 root 1325: void *p = ptr;
1326:
1327: ptr += nelts * size;
1328:
1329: for (i = 0; i < nelts; i++)
1330: {
1331: ptr -= size;
1332: (*dtor) (ptr, auto_delete);
1333: }
1334:
1335: if (auto_delete_vec)
1336: __builtin_delete (p);
1337: }
1338:
1339: #endif
1340:
1341: #ifdef L_shtab
1342: unsigned int __shtab[] = {
1343: 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1344: 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1345: 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1346: 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1347: 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1348: 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1349: 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1350: 0x10000000, 0x20000000, 0x40000000, 0x80000000
1351: };
1352: #endif
1353:
1354: #ifdef L_clear_cache
1355: /* Clear part of an instruction cache. */
1356:
1357: #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1358:
1359: void
1360: __clear_cache (beg, end)
1361: char *beg, *end;
1362: {
1363: #ifdef INSN_CACHE_SIZE
1364: static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1365: static int initialized = 0;
1366: int offset;
1.1.1.3 root 1367: void *start_addr
1368: void *end_addr;
1.1 root 1369: typedef (*function_ptr) ();
1370:
1371: #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1372: /* It's cheaper to clear the whole cache.
1373: Put in a series of jump instructions so that calling the beginning
1374: of the cache will clear the whole thing. */
1375:
1376: if (! initialized)
1377: {
1378: int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1379: & -INSN_CACHE_LINE_WIDTH);
1380: int end_ptr = ptr + INSN_CACHE_SIZE;
1381:
1382: while (ptr < end_ptr)
1383: {
1384: *(INSTRUCTION_TYPE *)ptr
1385: = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1386: ptr += INSN_CACHE_LINE_WIDTH;
1387: }
1388: *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1389:
1390: initialized = 1;
1391: }
1392:
1393: /* Call the beginning of the sequence. */
1394: (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1395: & -INSN_CACHE_LINE_WIDTH))
1396: ());
1397:
1398: #else /* Cache is large. */
1399:
1400: if (! initialized)
1401: {
1402: int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1403: & -INSN_CACHE_LINE_WIDTH);
1404:
1405: while (ptr < (int) array + sizeof array)
1406: {
1407: *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1408: ptr += INSN_CACHE_LINE_WIDTH;
1409: }
1410:
1411: initialized = 1;
1412: }
1413:
1414: /* Find the location in array that occupies the same cache line as BEG. */
1415:
1416: offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1417: start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1418: & -INSN_CACHE_PLANE_SIZE)
1419: + offset);
1420:
1421: /* Compute the cache alignment of the place to stop clearing. */
1422: #if 0 /* This is not needed for gcc's purposes. */
1423: /* If the block to clear is bigger than a cache plane,
1424: we clear the entire cache, and OFFSET is already correct. */
1425: if (end < beg + INSN_CACHE_PLANE_SIZE)
1426: #endif
1427: offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1428: & -INSN_CACHE_LINE_WIDTH)
1429: & (INSN_CACHE_PLANE_SIZE - 1));
1430:
1431: #if INSN_CACHE_DEPTH > 1
1432: end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1433: if (end_addr <= start_addr)
1434: end_addr += INSN_CACHE_PLANE_SIZE;
1435:
1436: for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1437: {
1438: int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1439: int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1440:
1441: while (addr != stop)
1442: {
1443: /* Call the return instruction at ADDR. */
1444: ((function_ptr) addr) ();
1445:
1446: addr += INSN_CACHE_LINE_WIDTH;
1447: }
1448: }
1449: #else /* just one plane */
1450: do
1451: {
1452: /* Call the return instruction at START_ADDR. */
1453: ((function_ptr) start_addr) ();
1454:
1455: start_addr += INSN_CACHE_LINE_WIDTH;
1456: }
1457: while ((start_addr % INSN_CACHE_SIZE) != offset);
1458: #endif /* just one plane */
1459: #endif /* Cache is large */
1460: #endif /* Cache exists */
1461: }
1462:
1463: #endif /* L_clear_cache */
1464:
1465: #ifdef L_trampoline
1466:
1467: /* Jump to a trampoline, loading the static chain address. */
1468:
1469: #ifdef TRANSFER_FROM_TRAMPOLINE
1470: TRANSFER_FROM_TRAMPOLINE
1471: #endif
1472:
1473: #ifdef __convex__
1474:
1475: /* Make stack executable so we can call trampolines on stack.
1476: This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1477:
1478: #include <sys/mman.h>
1479: #include <sys/vmparam.h>
1480: #include <machine/machparam.h>
1481:
1482: void
1483: __enable_execute_stack ()
1484: {
1485: int fp;
1486: static unsigned lowest = USRSTACK;
1487: unsigned current = (unsigned) &fp & -NBPG;
1488:
1489: if (lowest > current)
1490: {
1491: unsigned len = lowest - current;
1492: mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1493: lowest = current;
1494: }
1495:
1496: /* Clear instruction cache in case an old trampoline is in it. */
1497: asm ("pich");
1498: }
1499: #endif /* __convex__ */
1.1.1.2 root 1500:
1501: #ifdef __pyr__
1502:
1.1.1.4 ! root 1503: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1.1.1.2 root 1504: #include <stdio.h>
1505: #include <sys/mman.h>
1506: #include <sys/types.h>
1507: #include <sys/param.h>
1508: #include <sys/vmmac.h>
1509:
1510: /* Modified from the convex -code above.
1511: mremap promises to clear the i-cache. */
1512:
1513: void
1514: __enable_execute_stack ()
1515: {
1516: int fp;
1517: if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1518: PROT_READ|PROT_WRITE|PROT_EXEC))
1519: {
1520: perror ("mprotect in __enable_execute_stack");
1521: fflush (stderr);
1522: abort ();
1523: }
1524: }
1525: #endif /* __pyr__ */
1.1 root 1526: #endif /* L_trampoline */
1527:
1528: #ifdef L__main
1529:
1530: #include "gbl-ctors.h"
1531:
1532: /* Run all the global destructors on exit from the program. */
1533:
1534: void
1535: __do_global_dtors ()
1536: {
1537: #ifdef DO_GLOBAL_DTORS_BODY
1538: DO_GLOBAL_DTORS_BODY;
1539: #else
1.1.1.4 ! root 1540: unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1.1.1.3 root 1541: unsigned i;
1.1 root 1542:
1543: /* Some systems place the number of pointers
1544: in the first word of the table.
1545: On other systems, that word is -1.
1546: In all cases, the table is null-terminated. */
1547:
1548: /* If the length is not recorded, count up to the null. */
1549: if (nptrs == -1)
1550: for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1551:
1552: /* GNU LD format. */
1553: for (i = nptrs; i >= 1; i--)
1554: __DTOR_LIST__[i] ();
1555: #endif
1556: }
1557:
1558: #ifndef INIT_SECTION_ASM_OP
1559: /* Run all the global constructors on entry to the program. */
1560:
1.1.1.2 root 1561: #ifndef ON_EXIT
1.1 root 1562: #define ON_EXIT(a, b)
1563: #else
1564: /* Make sure the exit routine is pulled in to define the globals as
1565: bss symbols, just in case the linker does not automatically pull
1566: bss definitions from the library. */
1567:
1568: extern int _exit_dummy_decl;
1569: int *_exit_dummy_ref = &_exit_dummy_decl;
1570: #endif /* ON_EXIT */
1571:
1572: void
1573: __do_global_ctors ()
1574: {
1575: DO_GLOBAL_CTORS_BODY;
1.1.1.2 root 1576: ON_EXIT (__do_global_dtors, 0);
1.1 root 1577: }
1.1.1.2 root 1578: #endif /* no INIT_SECTION_ASM_OP */
1.1 root 1579:
1.1.1.2 root 1580: #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1.1 root 1581: /* Subroutine called automatically by `main'.
1582: Compiling a global function named `main'
1583: produces an automatic call to this function at the beginning.
1584:
1585: For many systems, this routine calls __do_global_ctors.
1586: For systems which support a .init section we use the .init section
1587: to run __do_global_ctors, so we need not do anything here. */
1588:
1589: void
1590: __main ()
1591: {
1592: /* Support recursive calls to `main': run initializers just once. */
1.1.1.3 root 1593: static int initialized = 0;
1.1 root 1594: if (! initialized)
1595: {
1596: initialized = 1;
1597: __do_global_ctors ();
1598: }
1599: }
1.1.1.2 root 1600: #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1.1 root 1601:
1602: #endif /* L__main */
1603:
1.1.1.4 ! root 1604: #ifdef L_ctors
1.1 root 1605:
1606: #include "gbl-ctors.h"
1607:
1608: /* Provide default definitions for the lists of constructors and
1609: destructors, so that we don't get linker errors. These symbols are
1610: intentionally bss symbols, so that gld and/or collect will provide
1611: the right values. */
1612:
1613: /* We declare the lists here with two elements each,
1614: so that they are valid empty lists if no other definition is loaded. */
1.1.1.2 root 1615: #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1.1.1.4 ! root 1616: #ifdef __NeXT__
! 1617: /* After 2.3, try this definition on all systems. */
! 1618: func_ptr __CTOR_LIST__[2] = {0, 0};
! 1619: func_ptr __DTOR_LIST__[2] = {0, 0};
! 1620: #else
1.1 root 1621: func_ptr __CTOR_LIST__[2];
1622: func_ptr __DTOR_LIST__[2];
1.1.1.4 ! root 1623: #endif
1.1.1.2 root 1624: #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1.1.1.4 ! root 1625: #endif /* L_ctors */
! 1626:
! 1627: #ifdef L_exit
! 1628:
! 1629: #include "gbl-ctors.h"
1.1 root 1630:
1631: #ifndef ON_EXIT
1632:
1633: /* If we have no known way of registering our own __do_global_dtors
1634: routine so that it will be invoked at program exit time, then we
1635: have to define our own exit routine which will get this to happen. */
1636:
1637: extern void __do_global_dtors ();
1638: extern void _cleanup ();
1.1.1.4 ! root 1639: extern volatile void _exit ();
1.1 root 1640:
1641: void
1642: exit (status)
1643: int status;
1644: {
1645: __do_global_dtors ();
1646: #ifdef EXIT_BODY
1647: EXIT_BODY;
1648: #else
1649: _cleanup ();
1650: #endif
1651: _exit (status);
1652: }
1653:
1654: #else
1655: int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1656: #endif
1657:
1658: #endif /* L_exit */
1659:
1660: /* In a.out systems, we need to have these dummy constructor and destructor
1661: lists in the library.
1662:
1663: When using `collect', the first link will resolve __CTOR_LIST__
1664: and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1665: result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1666: Since we don't do the second link if no constructors existed, these
1667: dummies must be fully functional empty lists.
1668:
1669: When using `gnu ld', these symbols will be used if there are no
1670: constructors. If there are constructors, the N_SETV symbol defined
1671: by the linker from the N_SETT's in input files will define __CTOR_LIST__
1672: and __DTOR_LIST__ rather than its being allocated as common storage
1673: by the definitions below.
1674:
1675: When using a linker that supports constructor and destructor segments,
1676: these definitions will not be used, since crtbegin.o and crtend.o
1677: (from crtstuff.c) will have already defined __CTOR_LIST__ and
1678: __DTOR_LIST__. The crt*.o files are passed directly to the linker
1679: on its command line, by gcc. */
1680:
1681: /* The list needs two elements: one is ignored (the old count); the
1682: second is the terminating zero. Since both values are zero, this
1683: declaration is not initialized, and it becomes `common'. */
1684:
1685: #ifdef L_ctor_list
1686: #include "gbl-ctors.h"
1687: func_ptr __CTOR_LIST__[2];
1688: #endif
1689:
1690: #ifdef L_dtor_list
1691: #include "gbl-ctors.h"
1692: func_ptr __DTOR_LIST__[2];
1693: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.