xref: /original-bsd/contrib/gcc-2.3.3/libgcc2.c (revision 2bdcd748)
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 int
986 __gcc_bcmp (s1, s2, size)
987      unsigned char *s1, *s2;
988      size_t size;
989 {
990   while (size > 0)
991     {
992       unsigned char c1 = *s1++, c2 = *s2++;
993       if (c1 != c2)
994 	return c1 - c2;
995       size--;
996     }
997   return 0;
998 }
999 
1000 #endif
1001 
1002 #ifdef L_varargs
1003 #ifdef __i860__
1004 #if defined(__svr4__) || defined(__alliant__)
1005 	asm ("	.text");
1006 	asm ("	.align	4");
1007 
1008 /* The Alliant needs the added underscore.  */
1009 	asm (".globl	__builtin_saveregs");
1010 asm ("__builtin_saveregs:");
1011 	asm (".globl	___builtin_saveregs");
1012 asm ("___builtin_saveregs:");
1013 
1014         asm ("	andnot	0x0f,%sp,%sp");	/* round down to 16-byte boundary */
1015 	asm ("	adds	-96,%sp,%sp");  /* allocate stack space for reg save
1016 					   area and also for a new va_list
1017 					   structure */
1018 	/* Save all argument registers in the arg reg save area.  The
1019 	   arg reg save area must have the following layout (according
1020 	   to the svr4 ABI):
1021 
1022 		struct {
1023 		  union  {
1024 		    float freg[8];
1025 		    double dreg[4];
1026 		  } float_regs;
1027 		  long	ireg[12];
1028 		};
1029 	*/
1030 
1031 	asm ("	fst.q	%f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1032 	asm ("	fst.q	%f12,16(%sp)");
1033 
1034 	asm ("	st.l	%r16,32(%sp)"); /* save integer regs (r16-r27) */
1035 	asm ("	st.l	%r17,36(%sp)");
1036 	asm ("	st.l	%r18,40(%sp)");
1037 	asm ("	st.l	%r19,44(%sp)");
1038 	asm ("	st.l	%r20,48(%sp)");
1039 	asm ("	st.l	%r21,52(%sp)");
1040 	asm ("	st.l	%r22,56(%sp)");
1041 	asm ("	st.l	%r23,60(%sp)");
1042 	asm ("	st.l	%r24,64(%sp)");
1043 	asm ("	st.l	%r25,68(%sp)");
1044 	asm ("	st.l	%r26,72(%sp)");
1045 	asm ("	st.l	%r27,76(%sp)");
1046 
1047 	asm ("	adds	80,%sp,%r16");  /* compute the address of the new
1048 					   va_list structure.  Put in into
1049 					   r16 so that it will be returned
1050 					   to the caller.  */
1051 
1052 	/* Initialize all fields of the new va_list structure.  This
1053 	   structure looks like:
1054 
1055 		typedef struct {
1056 		    unsigned long	ireg_used;
1057 		    unsigned long	freg_used;
1058 		    long		*reg_base;
1059 		    long		*mem_ptr;
1060 		} va_list;
1061 	*/
1062 
1063 	asm ("	st.l	%r0, 0(%r16)"); /* nfixed */
1064 	asm ("	st.l	%r0, 4(%r16)"); /* nfloating */
1065 	asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1066 	asm ("	bri	%r1");		/* delayed return */
1067 	asm ("	st.l	%r28,12(%r16)"); /* pointer to overflow args */
1068 
1069 #else /* not __SVR4__ */
1070 	asm ("	.text");
1071 	asm ("	.align	4");
1072 
1073 	asm (".globl	___builtin_saveregs");
1074 	asm ("___builtin_saveregs:");
1075 	asm ("	mov	sp,r30");
1076 	asm ("	andnot	0x0f,sp,sp");
1077 	asm ("	adds	-96,sp,sp");  /* allocate sufficient space on the stack */
1078 
1079 /* Fill in the __va_struct.  */
1080 	asm ("	st.l	r16, 0(sp)"); /* save integer regs (r16-r27) */
1081 	asm ("	st.l	r17, 4(sp)"); /* int	fixed[12] */
1082 	asm ("	st.l	r18, 8(sp)");
1083 	asm ("	st.l	r19,12(sp)");
1084 	asm ("	st.l	r20,16(sp)");
1085 	asm ("	st.l	r21,20(sp)");
1086 	asm ("	st.l	r22,24(sp)");
1087 	asm ("	st.l	r23,28(sp)");
1088 	asm ("	st.l	r24,32(sp)");
1089 	asm ("	st.l	r25,36(sp)");
1090 	asm ("	st.l	r26,40(sp)");
1091 	asm ("	st.l	r27,44(sp)");
1092 
1093 	asm ("	fst.q	f8, 48(sp)"); /* save floating regs (f8-f15) */
1094 	asm ("	fst.q	f12,64(sp)"); /* int floating[8] */
1095 
1096 /* Fill in the __va_ctl.  */
1097 	asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1098 	asm ("	st.l	r28,84(sp)"); /* pointer to more args */
1099 	asm ("	st.l	r0, 88(sp)"); /* nfixed */
1100 	asm ("	st.l	r0, 92(sp)"); /* nfloating */
1101 
1102 	asm ("	adds	80,sp,r16");  /* return address of the __va_ctl.  */
1103 	asm ("	bri	r1");
1104 	asm ("	mov	r30,sp");
1105 				/* recover stack and pass address to start
1106 				   of data.  */
1107 #endif /* not __SVR4__ */
1108 #else /* not __i860__ */
1109 #ifdef __sparc__
1110 	asm (".global __builtin_saveregs");
1111 	asm ("__builtin_saveregs:");
1112 	asm (".global ___builtin_saveregs");
1113 	asm ("___builtin_saveregs:");
1114 #ifdef NEED_PROC_COMMAND
1115 	asm (".proc 020");
1116 #endif
1117 	asm ("st %i0,[%fp+68]");
1118 	asm ("st %i1,[%fp+72]");
1119 	asm ("st %i2,[%fp+76]");
1120 	asm ("st %i3,[%fp+80]");
1121 	asm ("st %i4,[%fp+84]");
1122 	asm ("retl");
1123 	asm ("st %i5,[%fp+88]");
1124 #ifdef NEED_TYPE_COMMAND
1125 	asm (".type __builtin_saveregs,#function");
1126 	asm (".size __builtin_saveregs,.-__builtin_saveregs");
1127 #endif
1128 #else /* not __sparc__ */
1129 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1130 
1131   asm ("	.text");
1132   asm ("	.ent __builtin_saveregs");
1133   asm ("	.globl __builtin_saveregs");
1134   asm ("__builtin_saveregs:");
1135   asm ("	sw	$4,0($30)");
1136   asm ("	sw	$5,4($30)");
1137   asm ("	sw	$6,8($30)");
1138   asm ("	sw	$7,12($30)");
1139   asm ("	j	$31");
1140   asm ("	.end __builtin_saveregs");
1141 #else /* not __mips__, etc. */
1142 __builtin_saveregs ()
1143 {
1144   abort ();
1145 }
1146 #endif /* not __mips__ */
1147 #endif /* not __sparc__ */
1148 #endif /* not __i860__ */
1149 #endif
1150 
1151 #ifdef L_eprintf
1152 #ifndef inhibit_eprintf
1153 
1154 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1155 #include <stdio.h>
1156 /* This is used by the `assert' macro.  */
1157 void
1158 __eprintf (string, expression, line, filename)
1159      const char *string;
1160      const char *expression;
1161      int line;
1162      const char *filename;
1163 {
1164   fprintf (stderr, string, expression, line, filename);
1165   fflush (stderr);
1166   abort ();
1167 }
1168 
1169 #endif
1170 #endif
1171 
1172 #ifdef L_bb
1173 /* Avoid warning from ranlib about empty object file.  */
1174 void
1175 __bb_avoid_warning ()
1176 {}
1177 
1178 #if defined (__sun__) && defined (__mc68000__)
1179 struct bb
1180 {
1181   int initialized;
1182   char *filename;
1183   int *counts;
1184   int ncounts;
1185   int zero_word;
1186   int *addresses;
1187 };
1188 
1189 extern int ___tcov_init;
1190 
1191 __bb_init_func (blocks)
1192 	struct bb *blocks;
1193 {
1194   if (! ___tcov_init)
1195     ___tcov_init_func ();
1196 
1197   ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1198 }
1199 
1200 #endif
1201 #endif
1202 
1203 /* frills for C++ */
1204 
1205 #ifdef L_builtin_new
1206 typedef void (*vfp)(void);
1207 
1208 extern vfp __new_handler;
1209 
1210 void *
1211 __builtin_new (sz)
1212      size_t sz;
1213 {
1214   void *p;
1215 
1216   /* malloc (0) is unpredictable; avoid it.  */
1217   if (sz == 0)
1218     sz = 1;
1219   p = (void *) malloc (sz);
1220   if (p == 0)
1221     (*__new_handler) ();
1222   return p;
1223 }
1224 #endif
1225 
1226 #ifdef L_caps_New
1227 
1228 /* This gets us __GNU_LIBRARY__.  */
1229 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1230 #include <stdio.h>
1231 
1232 #ifdef __GNU_LIBRARY__
1233   /* Avoid forcing the library's meaning of `write' on the user program
1234      by using the "internal" name (for use within the library)  */
1235 #define write(fd, buf, n)	__write((fd), (buf), (n))
1236 #endif
1237 
1238 typedef void (*vfp)(void);
1239 
1240 extern void *__builtin_new (size_t);
1241 static void default_new_handler (void);
1242 
1243 vfp __new_handler = default_new_handler;
1244 
1245 void *
1246 __builtin_vec_new (p, maxindex, size, ctor)
1247      void *p;
1248      size_t maxindex;
1249      size_t size;
1250      void (*ctor)(void *);
1251 {
1252   size_t i;
1253   size_t nelts = maxindex + 1;
1254   void *rval;
1255 
1256   if (p == 0)
1257     p = __builtin_new (nelts * size);
1258 
1259   rval = p;
1260 
1261   for (i = 0; i < nelts; i++)
1262     {
1263       (*ctor) (p);
1264       p += size;
1265     }
1266 
1267   return rval;
1268 }
1269 
1270 vfp
1271 __set_new_handler (handler)
1272      vfp handler;
1273 {
1274   vfp prev_handler;
1275 
1276   prev_handler = __new_handler;
1277   if (handler == 0) handler = default_new_handler;
1278   __new_handler = handler;
1279   return prev_handler;
1280 }
1281 
1282 vfp
1283 set_new_handler (handler)
1284      vfp handler;
1285 {
1286   return __set_new_handler (handler);
1287 }
1288 
1289 #define MESSAGE "Virtual memory exceeded in `new'\n"
1290 
1291 static void
1292 default_new_handler ()
1293 {
1294   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1295   /* This should really print the name of the program, but that is hard to
1296      do.  We need a standard, clean way to get at the name.  */
1297   write (2, MESSAGE, sizeof (MESSAGE));
1298   /* don't call exit () because that may call global destructors which
1299      may cause a loop.  */
1300   _exit (-1);
1301 }
1302 #endif
1303 
1304 #ifdef L_builtin_del
1305 typedef void (*vfp)(void);
1306 
1307 void
1308 __builtin_delete (ptr)
1309      void *ptr;
1310 {
1311   if (ptr)
1312     free (ptr);
1313 }
1314 
1315 void
1316 __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1317      void *ptr;
1318      size_t maxindex;
1319      size_t size;
1320      void (*dtor)(void *, int);
1321      int auto_delete;
1322 {
1323   size_t i;
1324   size_t nelts = maxindex + 1;
1325   void *p = ptr;
1326 
1327   ptr += nelts * size;
1328 
1329   for (i = 0; i < nelts; i++)
1330     {
1331       ptr -= size;
1332       (*dtor) (ptr, auto_delete);
1333     }
1334 
1335   if (auto_delete_vec)
1336     __builtin_delete (p);
1337 }
1338 
1339 #endif
1340 
1341 #ifdef L_shtab
1342 unsigned int __shtab[] = {
1343     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1344     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1345     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1346     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1347     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1348     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1349     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1350     0x10000000, 0x20000000, 0x40000000, 0x80000000
1351   };
1352 #endif
1353 
1354 #ifdef L_clear_cache
1355 /* Clear part of an instruction cache.  */
1356 
1357 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1358 
1359 void
1360 __clear_cache (beg, end)
1361      char *beg, *end;
1362 {
1363 #ifdef INSN_CACHE_SIZE
1364   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1365   static int initialized = 0;
1366   int offset;
1367   void *start_addr
1368   void *end_addr;
1369   typedef (*function_ptr) ();
1370 
1371 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1372   /* It's cheaper to clear the whole cache.
1373      Put in a series of jump instructions so that calling the beginning
1374      of the cache will clear the whole thing.  */
1375 
1376   if (! initialized)
1377     {
1378       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1379 		 & -INSN_CACHE_LINE_WIDTH);
1380       int end_ptr = ptr + INSN_CACHE_SIZE;
1381 
1382       while (ptr < end_ptr)
1383 	{
1384 	  *(INSTRUCTION_TYPE *)ptr
1385 	    = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1386 	  ptr += INSN_CACHE_LINE_WIDTH;
1387 	}
1388       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1389 
1390       initialized = 1;
1391     }
1392 
1393   /* Call the beginning of the sequence.  */
1394   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1395 		    & -INSN_CACHE_LINE_WIDTH))
1396    ());
1397 
1398 #else /* Cache is large.  */
1399 
1400   if (! initialized)
1401     {
1402       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1403 		 & -INSN_CACHE_LINE_WIDTH);
1404 
1405       while (ptr < (int) array + sizeof array)
1406 	{
1407 	  *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1408 	  ptr += INSN_CACHE_LINE_WIDTH;
1409 	}
1410 
1411       initialized = 1;
1412     }
1413 
1414   /* Find the location in array that occupies the same cache line as BEG.  */
1415 
1416   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1417   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1418 		 & -INSN_CACHE_PLANE_SIZE)
1419 		+ offset);
1420 
1421   /* Compute the cache alignment of the place to stop clearing.  */
1422 #if 0  /* This is not needed for gcc's purposes.  */
1423   /* If the block to clear is bigger than a cache plane,
1424      we clear the entire cache, and OFFSET is already correct.  */
1425   if (end < beg + INSN_CACHE_PLANE_SIZE)
1426 #endif
1427     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1428 	       & -INSN_CACHE_LINE_WIDTH)
1429 	      & (INSN_CACHE_PLANE_SIZE - 1));
1430 
1431 #if INSN_CACHE_DEPTH > 1
1432   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1433   if (end_addr <= start_addr)
1434     end_addr += INSN_CACHE_PLANE_SIZE;
1435 
1436   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1437     {
1438       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1439       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1440 
1441       while (addr != stop)
1442 	{
1443 	  /* Call the return instruction at ADDR.  */
1444 	  ((function_ptr) addr) ();
1445 
1446 	  addr += INSN_CACHE_LINE_WIDTH;
1447 	}
1448     }
1449 #else /* just one plane */
1450   do
1451     {
1452       /* Call the return instruction at START_ADDR.  */
1453       ((function_ptr) start_addr) ();
1454 
1455       start_addr += INSN_CACHE_LINE_WIDTH;
1456     }
1457   while ((start_addr % INSN_CACHE_SIZE) != offset);
1458 #endif /* just one plane */
1459 #endif /* Cache is large */
1460 #endif /* Cache exists */
1461 }
1462 
1463 #endif /* L_clear_cache */
1464 
1465 #ifdef L_trampoline
1466 
1467 /* Jump to a trampoline, loading the static chain address.  */
1468 
1469 #ifdef TRANSFER_FROM_TRAMPOLINE
1470 TRANSFER_FROM_TRAMPOLINE
1471 #endif
1472 
1473 #ifdef __convex__
1474 
1475 /* Make stack executable so we can call trampolines on stack.
1476    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1477 
1478 #include <sys/mman.h>
1479 #include <sys/vmparam.h>
1480 #include <machine/machparam.h>
1481 
1482 void
1483 __enable_execute_stack ()
1484 {
1485   int fp;
1486   static unsigned lowest = USRSTACK;
1487   unsigned current = (unsigned) &fp & -NBPG;
1488 
1489   if (lowest > current)
1490     {
1491       unsigned len = lowest - current;
1492       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1493       lowest = current;
1494     }
1495 
1496   /* Clear instruction cache in case an old trampoline is in it. */
1497   asm ("pich");
1498 }
1499 #endif /* __convex__ */
1500 
1501 #ifdef __pyr__
1502 
1503 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1504 #include <stdio.h>
1505 #include <sys/mman.h>
1506 #include <sys/types.h>
1507 #include <sys/param.h>
1508 #include <sys/vmmac.h>
1509 
1510 /* Modified from the convex -code above.
1511    mremap promises to clear the i-cache. */
1512 
1513 void
1514 __enable_execute_stack ()
1515 {
1516   int fp;
1517   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1518 		PROT_READ|PROT_WRITE|PROT_EXEC))
1519     {
1520       perror ("mprotect in __enable_execute_stack");
1521       fflush (stderr);
1522       abort ();
1523     }
1524 }
1525 #endif /* __pyr__ */
1526 #endif /* L_trampoline */
1527 
1528 #ifdef L__main
1529 
1530 #include "gbl-ctors.h"
1531 
1532 /* Run all the global destructors on exit from the program.  */
1533 
1534 void
1535 __do_global_dtors ()
1536 {
1537 #ifdef DO_GLOBAL_DTORS_BODY
1538   DO_GLOBAL_DTORS_BODY;
1539 #else
1540   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1541   unsigned i;
1542 
1543   /* Some systems place the number of pointers
1544      in the first word of the table.
1545      On other systems, that word is -1.
1546      In all cases, the table is null-terminated.  */
1547 
1548   /* If the length is not recorded, count up to the null.  */
1549   if (nptrs == -1)
1550     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1551 
1552   /* GNU LD format.  */
1553   for (i = nptrs; i >= 1; i--)
1554     __DTOR_LIST__[i] ();
1555 #endif
1556 }
1557 
1558 #ifndef INIT_SECTION_ASM_OP
1559 /* Run all the global constructors on entry to the program.  */
1560 
1561 #ifndef ON_EXIT
1562 #define ON_EXIT(a, b)
1563 #else
1564 /* Make sure the exit routine is pulled in to define the globals as
1565    bss symbols, just in case the linker does not automatically pull
1566    bss definitions from the library.  */
1567 
1568 extern int _exit_dummy_decl;
1569 int *_exit_dummy_ref = &_exit_dummy_decl;
1570 #endif /* ON_EXIT */
1571 
1572 void
1573 __do_global_ctors ()
1574 {
1575   DO_GLOBAL_CTORS_BODY;
1576   ON_EXIT (__do_global_dtors, 0);
1577 }
1578 #endif /* no INIT_SECTION_ASM_OP */
1579 
1580 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1581 /* Subroutine called automatically by `main'.
1582    Compiling a global function named `main'
1583    produces an automatic call to this function at the beginning.
1584 
1585    For many systems, this routine calls __do_global_ctors.
1586    For systems which support a .init section we use the .init section
1587    to run __do_global_ctors, so we need not do anything here.  */
1588 
1589 void
1590 __main ()
1591 {
1592   /* Support recursive calls to `main': run initializers just once.  */
1593   static int initialized = 0;
1594   if (! initialized)
1595     {
1596       initialized = 1;
1597       __do_global_ctors ();
1598     }
1599 }
1600 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1601 
1602 #endif /* L__main */
1603 
1604 #ifdef L_ctors
1605 
1606 #include "gbl-ctors.h"
1607 
1608 /* Provide default definitions for the lists of constructors and
1609    destructors, so that we don't get linker errors.  These symbols are
1610    intentionally bss symbols, so that gld and/or collect will provide
1611    the right values.  */
1612 
1613 /* We declare the lists here with two elements each,
1614    so that they are valid empty lists if no other definition is loaded.  */
1615 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1616 #ifdef __NeXT__
1617 /* After 2.3, try this definition on all systems.  */
1618 func_ptr __CTOR_LIST__[2] = {0, 0};
1619 func_ptr __DTOR_LIST__[2] = {0, 0};
1620 #else
1621 func_ptr __CTOR_LIST__[2];
1622 func_ptr __DTOR_LIST__[2];
1623 #endif
1624 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1625 #endif /* L_ctors */
1626 
1627 #ifdef L_exit
1628 
1629 #include "gbl-ctors.h"
1630 
1631 #ifndef ON_EXIT
1632 
1633 /* If we have no known way of registering our own __do_global_dtors
1634    routine so that it will be invoked at program exit time, then we
1635    have to define our own exit routine which will get this to happen.  */
1636 
1637 extern void __do_global_dtors ();
1638 extern void _cleanup ();
1639 extern volatile void _exit ();
1640 
1641 void
1642 exit (status)
1643      int status;
1644 {
1645   __do_global_dtors ();
1646 #ifdef EXIT_BODY
1647   EXIT_BODY;
1648 #else
1649   _cleanup ();
1650 #endif
1651   _exit (status);
1652 }
1653 
1654 #else
1655 int _exit_dummy_decl = 0;	/* prevent compiler & linker warnings */
1656 #endif
1657 
1658 #endif /* L_exit */
1659 
1660 /* In a.out systems, we need to have these dummy constructor and destructor
1661    lists in the library.
1662 
1663    When using `collect', the first link will resolve __CTOR_LIST__
1664    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
1665    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1666    Since we don't do the second link if no constructors existed, these
1667    dummies must be fully functional empty lists.
1668 
1669    When using `gnu ld', these symbols will be used if there are no
1670    constructors.  If there are constructors, the N_SETV symbol defined
1671    by the linker from the N_SETT's in input files will define __CTOR_LIST__
1672    and __DTOR_LIST__ rather than its being allocated as common storage
1673    by the definitions below.
1674 
1675    When using a linker that supports constructor and destructor segments,
1676    these definitions will not be used, since crtbegin.o and crtend.o
1677    (from crtstuff.c) will have already defined __CTOR_LIST__ and
1678     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
1679    on its command line, by gcc.  */
1680 
1681 /* The list needs two elements:  one is ignored (the old count); the
1682    second is the terminating zero.  Since both values are zero, this
1683    declaration is not initialized, and it becomes `common'.  */
1684 
1685 #ifdef L_ctor_list
1686 #include "gbl-ctors.h"
1687 func_ptr __CTOR_LIST__[2];
1688 #endif
1689 
1690 #ifdef L_dtor_list
1691 #include "gbl-ctors.h"
1692 func_ptr __DTOR_LIST__[2];
1693 #endif
1694