]> gcc.gnu.org Git - gcc.git/blob - gcc/libgcc2.c
Make gcc use its own obstack.o.
[gcc.git] / gcc / libgcc2.c
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
31 #include "tconfig.h"
32 #include "machmode.h"
33 #ifndef L_trampoline
34 #include "gstddef.h"
35 #endif
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
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 LONG_DOUBLE_TYPE_SIZE == 96
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 #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
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
78 that if we *do* accidentally use some normal C language built-in type name,
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
88
89 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
90
91 /* DIstructs are pairs of SItype values in the order determined by
92 WORDS_BIG_ENDIAN. */
93
94 #if WORDS_BIG_ENDIAN
95 struct DIstruct {SItype high, low;};
96 #else
97 struct DIstruct {SItype low, high;};
98 #endif
99
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'. */
103
104 typedef union
105 {
106 struct DIstruct s;
107 DItype ll;
108 } DIunion;
109
110 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
111
112 #include "longlong.h"
113
114 #endif /* udiv or mul */
115
116 extern DItype __fixunssfdi (SFtype a);
117 extern DItype __fixunsdfdi (DFtype a);
118 \f
119 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
120 #if defined (L_divdi3) || defined (L_moddi3)
121 static inline
122 #endif
123 DItype
124 __negdi2 (u)
125 DItype u;
126 {
127 DIunion w;
128 DIunion uu;
129
130 uu.ll = u;
131
132 w.s.low = -uu.s.low;
133 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
134
135 return w.ll;
136 }
137 #endif
138 \f
139 #ifdef L_lshldi3
140 DItype
141 __lshldi3 (u, b)
142 DItype u;
143 SItype b;
144 {
145 DIunion w;
146 SItype bm;
147 DIunion uu;
148
149 if (b == 0)
150 return u;
151
152 uu.ll = u;
153
154 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
155 if (bm <= 0)
156 {
157 w.s.low = 0;
158 w.s.high = (USItype)uu.s.low << -bm;
159 }
160 else
161 {
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;
165 }
166
167 return w.ll;
168 }
169 #endif
170
171 #ifdef L_lshrdi3
172 DItype
173 __lshrdi3 (u, b)
174 DItype u;
175 SItype b;
176 {
177 DIunion w;
178 SItype bm;
179 DIunion uu;
180
181 if (b == 0)
182 return u;
183
184 uu.ll = u;
185
186 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
187 if (bm <= 0)
188 {
189 w.s.high = 0;
190 w.s.low = (USItype)uu.s.high >> -bm;
191 }
192 else
193 {
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;
197 }
198
199 return w.ll;
200 }
201 #endif
202
203 #ifdef L_ashldi3
204 DItype
205 __ashldi3 (u, b)
206 DItype u;
207 SItype b;
208 {
209 DIunion w;
210 SItype bm;
211 DIunion uu;
212
213 if (b == 0)
214 return u;
215
216 uu.ll = u;
217
218 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
219 if (bm <= 0)
220 {
221 w.s.low = 0;
222 w.s.high = (USItype)uu.s.low << -bm;
223 }
224 else
225 {
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;
229 }
230
231 return w.ll;
232 }
233 #endif
234
235 #ifdef L_ashrdi3
236 DItype
237 __ashrdi3 (u, b)
238 DItype u;
239 SItype b;
240 {
241 DIunion w;
242 SItype bm;
243 DIunion uu;
244
245 if (b == 0)
246 return u;
247
248 uu.ll = u;
249
250 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
251 if (bm <= 0)
252 {
253 /* w.s.high = 1..1 or 0..0 */
254 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
255 w.s.low = uu.s.high >> -bm;
256 }
257 else
258 {
259 USItype carries = (USItype)uu.s.high << bm;
260 w.s.high = uu.s.high >> b;
261 w.s.low = ((USItype)uu.s.low >> b) | carries;
262 }
263
264 return w.ll;
265 }
266 #endif
267 \f
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 \f
289 #ifdef L_muldi3
290 DItype
291 __muldi3 (u, v)
292 DItype u, v;
293 {
294 DIunion w;
295 DIunion uu, vv;
296
297 uu.ll = u,
298 vv.ll = v;
299
300 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
301 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
302 + (USItype) uu.s.high * (USItype) vv.s.low);
303
304 return w.ll;
305 }
306 #endif
307 \f
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 {
318 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
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 */
326 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
327 /* Divide (c1*2^32 + c0) by d */
328 sdiv_qrnnd (q, r, c1, c0, d);
329 /* Add 2^31 to quotient */
330 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
331 }
332 }
333 else
334 {
335 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
336 c1 = a1 >> 1; /* A/2 */
337 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
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 \f
408 #ifdef L_udivmoddi4
409 static const UQItype __clz_tab[] =
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
421 UDItype
422 __udivmoddi4 (n, d, rp)
423 UDItype n, d;
424 UDItype *rp;
425 {
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;
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;
490 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
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.
515 (Shifts counts of SI_TYPE_SIZE are undefined.) */
516
517 n1 -= d0;
518 q1 = 1;
519 }
520 else
521 {
522 /* Normalize. */
523
524 b = SI_TYPE_SIZE - bm;
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 {
601 USItype m1, m0;
602 /* Normalize. */
603
604 b = SI_TYPE_SIZE - bm;
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
642 UDItype __udivmoddi4 ();
643 DItype
644 __divdi3 (u, v)
645 DItype u, v;
646 {
647 SItype c = 0;
648 DIunion uu, vv;
649 DItype w;
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
661 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
662 if (c)
663 w = __negdi2 (w);
664
665 return w;
666 }
667 #endif
668
669 #ifdef L_moddi3
670 UDItype __udivmoddi4 ();
671 DItype
672 __moddi3 (u, v)
673 DItype u, v;
674 {
675 SItype c = 0;
676 DIunion uu, vv;
677 DItype w;
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
697 UDItype __udivmoddi4 ();
698 UDItype
699 __umoddi3 (u, v)
700 UDItype u, v;
701 {
702 DItype w;
703
704 (void) __udivmoddi4 (u, v, &w);
705
706 return w;
707 }
708 #endif
709
710 #ifdef L_udivdi3
711 UDItype __udivmoddi4 ();
712 UDItype
713 __udivdi3 (n, d)
714 UDItype n, d;
715 {
716 return __udivmoddi4 (n, d, (UDItype *) 0);
717 }
718 #endif
719 \f
720 #ifdef L_cmpdi2
721 word_type
722 __cmpdi2 (a, b)
723 DItype a, b;
724 {
725 DIunion au, bu;
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;
733 if ((USItype) au.s.low < (USItype) bu.s.low)
734 return 0;
735 else if ((USItype) au.s.low > (USItype) bu.s.low)
736 return 2;
737 return 1;
738 }
739 #endif
740
741 #ifdef L_ucmpdi2
742 word_type
743 __ucmpdi2 (a, b)
744 DItype a, b;
745 {
746 DIunion au, bu;
747
748 au.ll = a, bu.ll = b;
749
750 if ((USItype) au.s.high < (USItype) bu.s.high)
751 return 0;
752 else if ((USItype) au.s.high > (USItype) bu.s.high)
753 return 2;
754 if ((USItype) au.s.low < (USItype) bu.s.low)
755 return 0;
756 else if ((USItype) au.s.low > (USItype) bu.s.low)
757 return 2;
758 return 1;
759 }
760 #endif
761 \f
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
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
850 #ifdef L_fixunsdfdi
851 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
852 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
853
854 DItype
855 __fixunsdfdi (a)
856 DFtype a;
857 {
858 DFtype b;
859 UDItype v;
860
861 if (a < 0)
862 return 0;
863
864 /* Compute high word of result, as a flonum. */
865 b = (a / HIGH_WORD_COEFF);
866 /* Convert that to fixed (but not to DItype!),
867 and shift it into the high word. */
868 v = (USItype) b;
869 v <<= WORD_SIZE;
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.
873 Sometimes A comes out negative. This is significant, since
874 A has more bits than a long int does. */
875 if (a < 0)
876 v -= (USItype) (- a);
877 else
878 v += (USItype) a;
879 return v;
880 }
881 #endif
882
883 #ifdef L_fixdfdi
884 DItype
885 __fixdfdi (a)
886 DFtype a;
887 {
888 if (a < 0)
889 return - __fixunsdfdi (-a);
890 return __fixunsdfdi (a);
891 }
892 #endif
893
894 #ifdef L_fixunssfdi
895 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
896 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
897
898 DItype
899 __fixunssfdi (SFtype original_a)
900 {
901 /* Convert the SFtype to a DFtype, because that is surely not going
902 to lose any bits. Some day someone else can write a faster version
903 that avoids converting to DFtype, and verify it really works right. */
904 DFtype a = original_a;
905 DFtype b;
906 UDItype v;
907
908 if (a < 0)
909 return 0;
910
911 /* Compute high word of result, as a flonum. */
912 b = (a / HIGH_WORD_COEFF);
913 /* Convert that to fixed (but not to DItype!),
914 and shift it into the high word. */
915 v = (USItype) b;
916 v <<= WORD_SIZE;
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.
920 Sometimes A comes out negative. This is significant, since
921 A has more bits than a long int does. */
922 if (a < 0)
923 v -= (USItype) (- a);
924 else
925 v += (USItype) a;
926 return v;
927 }
928 #endif
929
930 #ifdef L_fixsfdi
931 DItype
932 __fixsfdi (SFtype a)
933 {
934 if (a < 0)
935 return - __fixunssfdi (-a);
936 return __fixunssfdi (a);
937 }
938 #endif
939
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
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
988 #ifdef L_floatdidf
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)
992
993 DFtype
994 __floatdidf (u)
995 DItype u;
996 {
997 DFtype d;
998 SItype negate = 0;
999
1000 if (u < 0)
1001 u = -u, negate = 1;
1002
1003 d = (USItype) (u >> WORD_SIZE);
1004 d *= HIGH_HALFWORD_COEFF;
1005 d *= HIGH_HALFWORD_COEFF;
1006 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1007
1008 return (negate ? -d : d);
1009 }
1010 #endif
1011
1012 #ifdef L_floatdisf
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)
1016
1017 SFtype
1018 __floatdisf (u)
1019 DItype u;
1020 {
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;
1025 SItype negate = 0;
1026
1027 if (u < 0)
1028 u = -u, negate = 1;
1029
1030 f = (USItype) (u >> WORD_SIZE);
1031 f *= HIGH_HALFWORD_COEFF;
1032 f *= HIGH_HALFWORD_COEFF;
1033 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1034
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;
1049 }
1050 #endif
1051
1052 #ifdef L_fixunsdfsi
1053 #include "glimits.h"
1054
1055 USItype
1056 __fixunsdfsi (a)
1057 DFtype a;
1058 {
1059 if (a >= - (DFtype) LONG_MIN)
1060 return (SItype) (a + LONG_MIN) - LONG_MIN;
1061 return (SItype) a;
1062 }
1063 #endif
1064
1065 #ifdef L_fixunssfsi
1066 #include "glimits.h"
1067
1068 USItype
1069 __fixunssfsi (SFtype a)
1070 {
1071 if (a >= - (SFtype) LONG_MIN)
1072 return (SItype) (a + LONG_MIN) - LONG_MIN;
1073 return (SItype) a;
1074 }
1075 #endif
1076 \f
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 \f
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 \f\f
1117 #ifdef L_varargs
1118 #ifdef __i860__
1119 #if defined(__svr4__) || defined(__alliant__)
1120 asm (" .text");
1121 asm (" .align 4");
1122
1123 /* The Alliant needs the added underscore. */
1124 asm (".globl __builtin_saveregs");
1125 asm ("__builtin_saveregs:");
1126 asm (".globl ___builtin_saveregs");
1127 asm ("___builtin_saveregs:");
1128
1129 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
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
1184 #else /* not __svr4__ */
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. */
1222 #endif /* not __svr4__ */
1223 #else /* not __i860__ */
1224 #ifdef __sparc__
1225 asm (".global __builtin_saveregs");
1226 asm ("__builtin_saveregs:");
1227 asm (".global ___builtin_saveregs");
1228 asm ("___builtin_saveregs:");
1229 #ifdef NEED_PROC_COMMAND
1230 asm (".proc 020");
1231 #endif
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]");
1239 #ifdef NEED_TYPE_COMMAND
1240 asm (".type __builtin_saveregs,#function");
1241 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1242 #endif
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 \f
1266 #ifdef L_eprintf
1267 #ifndef inhibit_libc
1268
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)
1274 const char *string;
1275 const char *expression;
1276 int line;
1277 const char *filename;
1278 {
1279 fprintf (stderr, string, expression, line, filename);
1280 fflush (stderr);
1281 abort ();
1282 }
1283
1284 #endif
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 \f
1318 /* frills for C++ */
1319
1320 #ifdef L_op_new
1321 typedef void (*vfp)(void);
1322
1323 extern vfp __new_handler;
1324
1325 /* void * operator new (size_t sz) */
1326 void *
1327 __builtin_new (size_t sz)
1328 {
1329 void *p;
1330
1331 /* malloc (0) is unpredictable; avoid it. */
1332 if (sz == 0)
1333 sz = 1;
1334 p = (void *) malloc (sz);
1335 if (p == 0)
1336 (*__new_handler) ();
1337 return p;
1338 }
1339 #endif /* L_op_new */
1340
1341 #ifdef L_new_handler
1342
1343 #ifndef inhibit_libc
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
1353 #endif /* inhibit_libc */
1354
1355 typedef void (*vfp)(void);
1356
1357 extern void *__builtin_new (size_t);
1358 static void default_new_handler (void);
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
1381 #define MESSAGE "Virtual memory exceeded in `new'\n"
1382
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. */
1389 write (2, MESSAGE, sizeof (MESSAGE));
1390 /* don't call exit () because that may call global destructors which
1391 may cause a loop. */
1392 _exit (-1);
1393 }
1394 #endif
1395
1396 #ifdef L_op_delete
1397 /* void operator delete (void *ptr) */
1398 void
1399 __builtin_delete (void *ptr)
1400 {
1401 if (ptr)
1402 free (ptr);
1403 }
1404 #endif
1405 \f
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 \f
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;
1432 void *start_addr
1433 void *end_addr;
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 \f
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__ */
1565
1566 #ifdef __pyr__
1567
1568 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
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__ */
1591 #endif /* L_trampoline */
1592 \f
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
1605 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1606 unsigned i;
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
1626 #ifndef ON_EXIT
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;
1641 ON_EXIT (__do_global_dtors, 0);
1642 }
1643 #endif /* no INIT_SECTION_ASM_OP */
1644
1645 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
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. */
1658 static int initialized = 0;
1659 if (! initialized)
1660 {
1661 initialized = 1;
1662 __do_global_ctors ();
1663 }
1664 }
1665 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1666
1667 #endif /* L__main */
1668 \f
1669 #ifdef L_ctors
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. */
1680 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
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
1686 func_ptr __CTOR_LIST__[2];
1687 func_ptr __DTOR_LIST__[2];
1688 #endif
1689 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1690 #endif /* L_ctors */
1691 \f
1692 #ifdef L_exit
1693
1694 #include "gbl-ctors.h"
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 ();
1704 extern volatile void _exit ();
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 \f
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 page took 0.11718 seconds and 5 git commands to generate.