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