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