OSDN Git Service

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