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