]> gcc.gnu.org Git - gcc.git/blame - gcc/libgcc2.c
(poplevel): Store into BLOCK iff it is non-null.
[gcc.git] / gcc / libgcc2.c
CommitLineData
203b91b9
RS
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* As a special exception, if you link this library with files
22 compiled with GCC to produce an executable, this does not cause
23 the resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why
25 the executable file might be covered by the GNU General Public License. */
26
27/* It is incorrect to include config.h here, because this file is being
28 compiled for the target, and hence definitions concerning only the host
29 do not apply. */
30
0dadecf6 31#include "tconfig.h"
bfe655f9 32#include "machmode.h"
b335c2cc 33#ifndef L_trampoline
203b91b9 34#include "gstddef.h"
b335c2cc 35#endif
203b91b9
RS
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
ab495388
RS
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
51typedef unsigned int UQItype __attribute__ ((mode (QI)));
52typedef int SItype __attribute__ ((mode (SI)));
53typedef unsigned int USItype __attribute__ ((mode (SI)));
54typedef int DItype __attribute__ ((mode (DI)));
55typedef unsigned int UDItype __attribute__ ((mode (DI)));
56typedef float SFtype __attribute__ ((mode (SF)));
57typedef float DFtype __attribute__ ((mode (DF)));
258d1356 58#if 0
ab495388 59typedef float XFtype __attribute__ ((mode (XF)));
258d1356
CH
60#endif
61#if LONG_DOUBLE_TYPE_SIZE == 128
ab495388 62typedef float TFtype __attribute__ ((mode (TF)));
258d1356 63#endif
ab495388
RS
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
203b91b9
RS
82 WORDS_BIG_ENDIAN. */
83
84#if WORDS_BIG_ENDIAN
ab495388 85 struct DIstruct {SItype high, low;};
203b91b9 86#else
ab495388 87 struct DIstruct {SItype low, high;};
203b91b9
RS
88#endif
89
ab495388
RS
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'. */
203b91b9
RS
93
94typedef union
95{
ab495388
RS
96 struct DIstruct s;
97 DItype ll;
98} DIunion;
203b91b9 99
3904131a 100#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
203b91b9
RS
101
102#include "longlong.h"
103
104#endif /* udiv or mul */
105
ab495388
RS
106extern DItype __fixunssfdi (SFtype a);
107extern DItype __fixunsdfdi (DFtype a);
203b91b9
RS
108\f
109#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
110#if defined (L_divdi3) || defined (L_moddi3)
111static inline
112#endif
ab495388 113DItype
203b91b9 114__negdi2 (u)
ab495388 115 DItype u;
203b91b9 116{
ab495388
RS
117 DIunion w;
118 DIunion uu;
203b91b9
RS
119
120 uu.ll = u;
121
122 w.s.low = -uu.s.low;
ab495388 123 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
203b91b9
RS
124
125 return w.ll;
126}
127#endif
128\f
129#ifdef L_lshldi3
ab495388 130DItype
203b91b9 131__lshldi3 (u, b)
ab495388
RS
132 DItype u;
133 SItype b;
203b91b9 134{
ab495388
RS
135 DIunion w;
136 SItype bm;
137 DIunion uu;
203b91b9
RS
138
139 if (b == 0)
140 return u;
141
142 uu.ll = u;
143
ab495388 144 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
145 if (bm <= 0)
146 {
147 w.s.low = 0;
ab495388 148 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
149 }
150 else
151 {
ab495388
RS
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;
203b91b9
RS
155 }
156
157 return w.ll;
158}
159#endif
160
161#ifdef L_lshrdi3
ab495388 162DItype
203b91b9 163__lshrdi3 (u, b)
ab495388
RS
164 DItype u;
165 SItype b;
203b91b9 166{
ab495388
RS
167 DIunion w;
168 SItype bm;
169 DIunion uu;
203b91b9
RS
170
171 if (b == 0)
172 return u;
173
174 uu.ll = u;
175
ab495388 176 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
177 if (bm <= 0)
178 {
179 w.s.high = 0;
ab495388 180 w.s.low = (USItype)uu.s.high >> -bm;
203b91b9
RS
181 }
182 else
183 {
ab495388
RS
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;
203b91b9
RS
187 }
188
189 return w.ll;
190}
191#endif
192
193#ifdef L_ashldi3
ab495388 194DItype
203b91b9 195__ashldi3 (u, b)
ab495388
RS
196 DItype u;
197 SItype b;
203b91b9 198{
ab495388
RS
199 DIunion w;
200 SItype bm;
201 DIunion uu;
203b91b9
RS
202
203 if (b == 0)
204 return u;
205
206 uu.ll = u;
207
ab495388 208 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
209 if (bm <= 0)
210 {
211 w.s.low = 0;
ab495388 212 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
213 }
214 else
215 {
ab495388
RS
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;
203b91b9
RS
219 }
220
221 return w.ll;
222}
223#endif
224
225#ifdef L_ashrdi3
ab495388 226DItype
203b91b9 227__ashrdi3 (u, b)
ab495388
RS
228 DItype u;
229 SItype b;
203b91b9 230{
ab495388
RS
231 DIunion w;
232 SItype bm;
233 DIunion uu;
203b91b9
RS
234
235 if (b == 0)
236 return u;
237
238 uu.ll = u;
239
ab495388 240 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
241 if (bm <= 0)
242 {
243 /* w.s.high = 1..1 or 0..0 */
ab495388 244 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
203b91b9
RS
245 w.s.low = uu.s.high >> -bm;
246 }
247 else
248 {
ab495388 249 USItype carries = (USItype)uu.s.high << bm;
203b91b9 250 w.s.high = uu.s.high >> b;
ab495388 251 w.s.low = ((USItype)uu.s.low >> b) | carries;
203b91b9
RS
252 }
253
254 return w.ll;
255}
256#endif
257\f
258#ifdef L_muldi3
ab495388 259DItype
203b91b9 260__muldi3 (u, v)
ab495388 261 DItype u, v;
203b91b9 262{
ab495388
RS
263 DIunion w;
264 DIunion uu, vv;
203b91b9
RS
265
266 uu.ll = u,
267 vv.ll = v;
268
269 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
ab495388
RS
270 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
271 + (USItype) uu.s.high * (USItype) vv.s.low);
203b91b9
RS
272
273 return w.ll;
274}
275#endif
276\f
3904131a 277#ifdef L_udiv_w_sdiv
431b1ee0 278USItype
3904131a 279__udiv_w_sdiv (rp, a1, a0, d)
431b1ee0
TG
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 += 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\f
203b91b9 377#ifdef L_udivmoddi4
ab495388 378static const UQItype __clz_tab[] =
203b91b9
RS
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
ab495388 390UDItype
203b91b9 391__udivmoddi4 (n, d, rp)
ab495388
RS
392 UDItype n, d;
393 UDItype *rp;
203b91b9 394{
ab495388
RS
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;
203b91b9
RS
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;
ab495388 459 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
203b91b9
RS
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.
ab495388 484 (Shifts counts of SI_TYPE_SIZE are undefined.) */
203b91b9
RS
485
486 n1 -= d0;
487 q1 = 1;
488 }
489 else
490 {
491 /* Normalize. */
492
ab495388 493 b = SI_TYPE_SIZE - bm;
203b91b9
RS
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 {
ab495388 570 USItype m1, m0;
203b91b9
RS
571 /* Normalize. */
572
ab495388 573 b = SI_TYPE_SIZE - bm;
203b91b9
RS
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
ab495388
RS
611UDItype __udivmoddi4 ();
612DItype
203b91b9 613__divdi3 (u, v)
ab495388 614 DItype u, v;
203b91b9 615{
ab495388
RS
616 SItype c = 0;
617 DIunion uu, vv;
618 DItype w;
203b91b9
RS
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
ab495388 630 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
203b91b9
RS
631 if (c)
632 w = __negdi2 (w);
633
634 return w;
635}
636#endif
637
638#ifdef L_moddi3
ab495388
RS
639UDItype __udivmoddi4 ();
640DItype
203b91b9 641__moddi3 (u, v)
ab495388 642 DItype u, v;
203b91b9 643{
ab495388
RS
644 SItype c = 0;
645 DIunion uu, vv;
646 DItype w;
203b91b9
RS
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
ab495388
RS
666UDItype __udivmoddi4 ();
667UDItype
203b91b9 668__umoddi3 (u, v)
ab495388 669 UDItype u, v;
203b91b9 670{
ab495388 671 DItype w;
203b91b9
RS
672
673 (void) __udivmoddi4 (u, v, &w);
674
675 return w;
676}
677#endif
678
679#ifdef L_udivdi3
ab495388
RS
680UDItype __udivmoddi4 ();
681UDItype
203b91b9 682__udivdi3 (n, d)
ab495388 683 UDItype n, d;
203b91b9 684{
ab495388 685 return __udivmoddi4 (n, d, (UDItype *) 0);
203b91b9
RS
686}
687#endif
688\f
689#ifdef L_cmpdi2
690SItype
691__cmpdi2 (a, b)
ab495388 692 DItype a, b;
203b91b9 693{
ab495388 694 DIunion au, bu;
203b91b9
RS
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;
ab495388 702 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 703 return 0;
ab495388 704 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
705 return 2;
706 return 1;
707}
708#endif
709
710#ifdef L_ucmpdi2
711SItype
712__ucmpdi2 (a, b)
ab495388 713 DItype a, b;
203b91b9 714{
ab495388 715 DIunion au, bu;
203b91b9
RS
716
717 au.ll = a, bu.ll = b;
718
ab495388 719 if ((USItype) au.s.high < (USItype) bu.s.high)
203b91b9 720 return 0;
ab495388 721 else if ((USItype) au.s.high > (USItype) bu.s.high)
203b91b9 722 return 2;
ab495388 723 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 724 return 0;
ab495388 725 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
726 return 2;
727 return 1;
728}
729#endif
730\f
ab495388
RS
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
735DItype
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)
765DItype
766__fixtfdi (a)
767 TFtype a;
768{
769 if (a < 0)
770 return - __fixunstfdi (-a);
771 return __fixunstfdi (a);
772}
773#endif
774
203b91b9 775#ifdef L_fixunsdfdi
ab495388
RS
776#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
777#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 778
ab495388 779DItype
203b91b9 780__fixunsdfdi (a)
ab495388 781 DFtype a;
203b91b9 782{
ab495388
RS
783 DFtype b;
784 UDItype v;
203b91b9
RS
785
786 if (a < 0)
787 return 0;
788
789 /* Compute high word of result, as a flonum. */
790 b = (a / HIGH_WORD_COEFF);
ab495388 791 /* Convert that to fixed (but not to DItype!),
203b91b9 792 and shift it into the high word. */
ab495388 793 v = (USItype) b;
203b91b9 794 v <<= WORD_SIZE;
ab495388
RS
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.
203b91b9
RS
798 Sometimes A comes out negative. This is significant, since
799 A has more bits than a long int does. */
800 if (a < 0)
ab495388 801 v -= (USItype) (- a);
203b91b9 802 else
ab495388 803 v += (USItype) a;
203b91b9
RS
804 return v;
805}
806#endif
807
808#ifdef L_fixdfdi
ab495388 809DItype
203b91b9 810__fixdfdi (a)
ab495388 811 DFtype a;
203b91b9
RS
812{
813 if (a < 0)
814 return - __fixunsdfdi (-a);
815 return __fixunsdfdi (a);
816}
817#endif
818
819#ifdef L_fixunssfdi
ab495388
RS
820#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
821#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 822
ab495388
RS
823DItype
824__fixunssfdi (SFtype original_a)
203b91b9 825{
ab495388 826 /* Convert the SFtype to a DFtype, because that is surely not going
203b91b9 827 to lose any bits. Some day someone else can write a faster version
ab495388
RS
828 that avoids converting to DFtype, and verify it really works right. */
829 DFtype a = original_a;
830 DFtype b;
831 UDItype v;
203b91b9
RS
832
833 if (a < 0)
834 return 0;
835
836 /* Compute high word of result, as a flonum. */
837 b = (a / HIGH_WORD_COEFF);
ab495388 838 /* Convert that to fixed (but not to DItype!),
203b91b9 839 and shift it into the high word. */
ab495388 840 v = (USItype) b;
203b91b9 841 v <<= WORD_SIZE;
ab495388
RS
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.
203b91b9
RS
845 Sometimes A comes out negative. This is significant, since
846 A has more bits than a long int does. */
847 if (a < 0)
ab495388 848 v -= (USItype) (- a);
203b91b9 849 else
ab495388 850 v += (USItype) a;
203b91b9
RS
851 return v;
852}
853#endif
854
855#ifdef L_fixsfdi
ab495388
RS
856DItype
857__fixsfdi (SFtype a)
203b91b9
RS
858{
859 if (a < 0)
860 return - __fixunssfdi (-a);
861 return __fixunssfdi (a);
862}
863#endif
864
ab495388
RS
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
870TFtype
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
203b91b9 889#ifdef L_floatdidf
ab495388
RS
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)
203b91b9 893
ab495388 894DFtype
203b91b9 895__floatdidf (u)
ab495388 896 DItype u;
203b91b9 897{
ab495388
RS
898 DFtype d;
899 SItype negate = 0;
203b91b9
RS
900
901 if (u < 0)
902 u = -u, negate = 1;
903
ab495388 904 d = (USItype) (u >> WORD_SIZE);
203b91b9
RS
905 d *= HIGH_HALFWORD_COEFF;
906 d *= HIGH_HALFWORD_COEFF;
ab495388 907 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9
RS
908
909 return (negate ? -d : d);
910}
911#endif
912
913#ifdef L_floatdisf
ab495388
RS
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)
203b91b9 917
ab495388 918SFtype
203b91b9 919__floatdisf (u)
ab495388 920 DItype u;
203b91b9 921{
ab495388
RS
922 SFtype f;
923 SItype negate = 0;
203b91b9
RS
924
925 if (u < 0)
926 u = -u, negate = 1;
927
ab495388 928 f = (USItype) (u >> WORD_SIZE);
203b91b9
RS
929 f *= HIGH_HALFWORD_COEFF;
930 f *= HIGH_HALFWORD_COEFF;
ab495388 931 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9
RS
932
933 return (negate ? -f : f);
934}
935#endif
936
937#ifdef L_fixunsdfsi
0c7b7f30 938#include "glimits.h"
203b91b9 939
ab495388 940USItype
203b91b9 941__fixunsdfsi (a)
ab495388 942 DFtype a;
203b91b9 943{
ab495388 944 if (a >= - (DFtype) LONG_MIN)
203b91b9
RS
945 return (SItype) (a + LONG_MIN) - LONG_MIN;
946 return (SItype) a;
947}
948#endif
949
950#ifdef L_fixunssfsi
0c7b7f30 951#include "glimits.h"
203b91b9 952
ab495388
RS
953USItype
954__fixunssfsi (SFtype a)
203b91b9 955{
ab495388 956 if (a >= - (SFtype) LONG_MIN)
203b91b9
RS
957 return (SItype) (a + LONG_MIN) - LONG_MIN;
958 return (SItype) a;
959}
960#endif
961\f
ab495388
RS
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
203b91b9
RS
979#ifdef L_varargs
980#ifdef __i860__
600032fc 981#if defined(__svr4__) || defined(__alliant__)
203b91b9
RS
982 asm (" .text");
983 asm (" .align 4");
984
27d21d32 985/* The Alliant needs the added underscore. */
203b91b9
RS
986 asm (".globl __builtin_saveregs");
987asm ("__builtin_saveregs:");
27d21d32
RS
988 asm (".globl ___builtin_saveregs");
989asm ("___builtin_saveregs:");
990
991 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
203b91b9
RS
992 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
993 area and also for a new va_list
994 structure */
995 /* Save all argument registers in the arg reg save area. The
996 arg reg save area must have the following layout (according
997 to the svr4 ABI):
998
999 struct {
1000 union {
1001 float freg[8];
1002 double dreg[4];
1003 } float_regs;
1004 long ireg[12];
1005 };
1006 */
1007
1008 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1009 asm (" fst.q %f12,16(%sp)");
1010
1011 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1012 asm (" st.l %r17,36(%sp)");
1013 asm (" st.l %r18,40(%sp)");
1014 asm (" st.l %r19,44(%sp)");
1015 asm (" st.l %r20,48(%sp)");
1016 asm (" st.l %r21,52(%sp)");
1017 asm (" st.l %r22,56(%sp)");
1018 asm (" st.l %r23,60(%sp)");
1019 asm (" st.l %r24,64(%sp)");
1020 asm (" st.l %r25,68(%sp)");
1021 asm (" st.l %r26,72(%sp)");
1022 asm (" st.l %r27,76(%sp)");
1023
1024 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1025 va_list structure. Put in into
1026 r16 so that it will be returned
1027 to the caller. */
1028
1029 /* Initialize all fields of the new va_list structure. This
1030 structure looks like:
1031
1032 typedef struct {
1033 unsigned long ireg_used;
1034 unsigned long freg_used;
1035 long *reg_base;
1036 long *mem_ptr;
1037 } va_list;
1038 */
1039
1040 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1041 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1042 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1043 asm (" bri %r1"); /* delayed return */
1044 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1045
600032fc 1046#else /* not __SVR4__ */
203b91b9
RS
1047 asm (" .text");
1048 asm (" .align 4");
1049
1050 asm (".globl ___builtin_saveregs");
1051 asm ("___builtin_saveregs:");
1052 asm (" mov sp,r30");
1053 asm (" andnot 0x0f,sp,sp");
1054 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1055
1056/* Fill in the __va_struct. */
1057 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1058 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1059 asm (" st.l r18, 8(sp)");
1060 asm (" st.l r19,12(sp)");
1061 asm (" st.l r20,16(sp)");
1062 asm (" st.l r21,20(sp)");
1063 asm (" st.l r22,24(sp)");
1064 asm (" st.l r23,28(sp)");
1065 asm (" st.l r24,32(sp)");
1066 asm (" st.l r25,36(sp)");
1067 asm (" st.l r26,40(sp)");
1068 asm (" st.l r27,44(sp)");
1069
1070 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1071 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1072
1073/* Fill in the __va_ctl. */
1074 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1075 asm (" st.l r28,84(sp)"); /* pointer to more args */
1076 asm (" st.l r0, 88(sp)"); /* nfixed */
1077 asm (" st.l r0, 92(sp)"); /* nfloating */
1078
1079 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1080 asm (" bri r1");
1081 asm (" mov r30,sp");
1082 /* recover stack and pass address to start
1083 of data. */
600032fc 1084#endif /* not __SVR4__ */
203b91b9
RS
1085#else /* not __i860__ */
1086#ifdef __sparc__
b335c2cc
TW
1087 asm (".global __builtin_saveregs");
1088 asm ("__builtin_saveregs:");
203b91b9
RS
1089 asm (".global ___builtin_saveregs");
1090 asm ("___builtin_saveregs:");
b1166fae
RS
1091#ifdef NEED_PROC_COMMAND
1092 asm (".proc 020");
b335c2cc 1093#endif
203b91b9
RS
1094 asm ("st %i0,[%fp+68]");
1095 asm ("st %i1,[%fp+72]");
1096 asm ("st %i2,[%fp+76]");
1097 asm ("st %i3,[%fp+80]");
1098 asm ("st %i4,[%fp+84]");
1099 asm ("retl");
1100 asm ("st %i5,[%fp+88]");
b1166fae
RS
1101#ifdef NEED_TYPE_COMMAND
1102 asm (".type __builtin_saveregs,#function");
1103 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1104#endif
203b91b9
RS
1105#else /* not __sparc__ */
1106#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1107
1108 asm (" .text");
1109 asm (" .ent __builtin_saveregs");
1110 asm (" .globl __builtin_saveregs");
1111 asm ("__builtin_saveregs:");
1112 asm (" sw $4,0($30)");
1113 asm (" sw $5,4($30)");
1114 asm (" sw $6,8($30)");
1115 asm (" sw $7,12($30)");
1116 asm (" j $31");
1117 asm (" .end __builtin_saveregs");
1118#else /* not __mips__, etc. */
1119__builtin_saveregs ()
1120{
1121 abort ();
1122}
1123#endif /* not __mips__ */
1124#endif /* not __sparc__ */
1125#endif /* not __i860__ */
1126#endif
1127\f
1128#ifdef L_eprintf
1129#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1130#include <stdio.h>
1131/* This is used by the `assert' macro. */
1132void
1133__eprintf (string, expression, line, filename)
b1166fae
RS
1134 const char *string;
1135 const char *expression;
203b91b9 1136 int line;
b1166fae 1137 const char *filename;
203b91b9
RS
1138{
1139 fprintf (stderr, string, expression, line, filename);
1140 fflush (stderr);
1141 abort ();
1142}
1143#endif
1144
1145#ifdef L_bb
1146/* Avoid warning from ranlib about empty object file. */
1147void
1148__bb_avoid_warning ()
1149{}
1150
1151#if defined (__sun__) && defined (__mc68000__)
1152struct bb
1153{
1154 int initialized;
1155 char *filename;
1156 int *counts;
1157 int ncounts;
1158 int zero_word;
1159 int *addresses;
1160};
1161
1162extern int ___tcov_init;
1163
1164__bb_init_func (blocks)
1165 struct bb *blocks;
1166{
1167 if (! ___tcov_init)
1168 ___tcov_init_func ();
1169
1170 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1171}
1172
1173#endif
1174#endif
1175\f
1176/* frills for C++ */
1177
1178#ifdef L_builtin_new
1179typedef void (*vfp)(void);
1180
1181extern vfp __new_handler;
1182
1183void *
1184__builtin_new (sz)
b6422cca 1185 size_t sz;
203b91b9
RS
1186{
1187 void *p;
1188
ecbe06a1 1189 p = (void *) malloc (sz);
203b91b9
RS
1190 if (p == 0)
1191 (*__new_handler) ();
1192 return p;
1193}
1194#endif
1195
c7c0a635 1196#ifdef L_caps_New
203b91b9
RS
1197typedef void (*vfp)(void);
1198
b6422cca
RS
1199extern void *__builtin_new (size_t);
1200static void default_new_handler (void);
203b91b9
RS
1201
1202vfp __new_handler = default_new_handler;
1203
1204void *
1205__builtin_vec_new (p, maxindex, size, ctor)
1206 void *p;
b6422cca
RS
1207 size_t maxindex;
1208 size_t size;
203b91b9
RS
1209 void (*ctor)(void *);
1210{
b6422cca
RS
1211 size_t i;
1212 size_t nelts = maxindex + 1;
203b91b9
RS
1213 void *rval;
1214
1215 if (p == 0)
b1166fae 1216 p = __builtin_new (nelts * size);
203b91b9
RS
1217
1218 rval = p;
1219
1220 for (i = 0; i < nelts; i++)
1221 {
1222 (*ctor) (p);
1223 p += size;
1224 }
1225
1226 return rval;
1227}
1228
1229vfp
1230__set_new_handler (handler)
1231 vfp handler;
1232{
1233 vfp prev_handler;
1234
1235 prev_handler = __new_handler;
1236 if (handler == 0) handler = default_new_handler;
1237 __new_handler = handler;
1238 return prev_handler;
1239}
1240
1241vfp
1242set_new_handler (handler)
1243 vfp handler;
1244{
1245 return __set_new_handler (handler);
1246}
1247
b1166fae
RS
1248#define MESSAGE "Virtual memory exceeded in `new'\n"
1249
203b91b9
RS
1250static void
1251default_new_handler ()
1252{
1253 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1254 /* This should really print the name of the program, but that is hard to
1255 do. We need a standard, clean way to get at the name. */
b1166fae 1256 write (2, MESSAGE, sizeof (MESSAGE));
203b91b9
RS
1257 /* don't call exit () because that may call global destructors which
1258 may cause a loop. */
1259 _exit (-1);
1260}
1261#endif
1262\f
1263#ifdef L_builtin_del
1264typedef void (*vfp)(void);
1265
1266void
1267__builtin_delete (ptr)
1268 void *ptr;
1269{
1270 if (ptr)
1271 free (ptr);
1272}
1273
1274void
1275__builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1276 void *ptr;
b6422cca
RS
1277 size_t maxindex;
1278 size_t size;
1279 void (*dtor)(void *, int);
203b91b9
RS
1280 int auto_delete;
1281{
b6422cca
RS
1282 size_t i;
1283 size_t nelts = maxindex + 1;
203b91b9
RS
1284 void *p = ptr;
1285
1286 ptr += nelts * size;
1287
1288 for (i = 0; i < nelts; i++)
1289 {
1290 ptr -= size;
1291 (*dtor) (ptr, auto_delete);
1292 }
1293
1294 if (auto_delete_vec)
1295 __builtin_delete (p);
1296}
1297
1298#endif
1299
1300#ifdef L_shtab
1301unsigned int __shtab[] = {
1302 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1303 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1304 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1305 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1306 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1307 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1308 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1309 0x10000000, 0x20000000, 0x40000000, 0x80000000
1310 };
1311#endif
1312\f
1313#ifdef L_clear_cache
1314/* Clear part of an instruction cache. */
1315
1316#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1317
1318void
1319__clear_cache (beg, end)
1320 char *beg, *end;
1321{
1322#ifdef INSN_CACHE_SIZE
1323 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1324 static int initialized = 0;
1325 int offset;
b6422cca
RS
1326 void *start_addr
1327 void *end_addr;
203b91b9
RS
1328 typedef (*function_ptr) ();
1329
1330#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1331 /* It's cheaper to clear the whole cache.
1332 Put in a series of jump instructions so that calling the beginning
1333 of the cache will clear the whole thing. */
1334
1335 if (! initialized)
1336 {
1337 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1338 & -INSN_CACHE_LINE_WIDTH);
1339 int end_ptr = ptr + INSN_CACHE_SIZE;
1340
1341 while (ptr < end_ptr)
1342 {
1343 *(INSTRUCTION_TYPE *)ptr
1344 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1345 ptr += INSN_CACHE_LINE_WIDTH;
1346 }
1347 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1348
1349 initialized = 1;
1350 }
1351
1352 /* Call the beginning of the sequence. */
1353 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1354 & -INSN_CACHE_LINE_WIDTH))
1355 ());
1356
1357#else /* Cache is large. */
1358
1359 if (! initialized)
1360 {
1361 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1362 & -INSN_CACHE_LINE_WIDTH);
1363
1364 while (ptr < (int) array + sizeof array)
1365 {
1366 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1367 ptr += INSN_CACHE_LINE_WIDTH;
1368 }
1369
1370 initialized = 1;
1371 }
1372
1373 /* Find the location in array that occupies the same cache line as BEG. */
1374
1375 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1376 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1377 & -INSN_CACHE_PLANE_SIZE)
1378 + offset);
1379
1380 /* Compute the cache alignment of the place to stop clearing. */
1381#if 0 /* This is not needed for gcc's purposes. */
1382 /* If the block to clear is bigger than a cache plane,
1383 we clear the entire cache, and OFFSET is already correct. */
1384 if (end < beg + INSN_CACHE_PLANE_SIZE)
1385#endif
1386 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1387 & -INSN_CACHE_LINE_WIDTH)
1388 & (INSN_CACHE_PLANE_SIZE - 1));
1389
1390#if INSN_CACHE_DEPTH > 1
1391 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1392 if (end_addr <= start_addr)
1393 end_addr += INSN_CACHE_PLANE_SIZE;
1394
1395 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1396 {
1397 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1398 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1399
1400 while (addr != stop)
1401 {
1402 /* Call the return instruction at ADDR. */
1403 ((function_ptr) addr) ();
1404
1405 addr += INSN_CACHE_LINE_WIDTH;
1406 }
1407 }
1408#else /* just one plane */
1409 do
1410 {
1411 /* Call the return instruction at START_ADDR. */
1412 ((function_ptr) start_addr) ();
1413
1414 start_addr += INSN_CACHE_LINE_WIDTH;
1415 }
1416 while ((start_addr % INSN_CACHE_SIZE) != offset);
1417#endif /* just one plane */
1418#endif /* Cache is large */
1419#endif /* Cache exists */
1420}
1421
1422#endif /* L_clear_cache */
1423\f
1424#ifdef L_trampoline
1425
1426/* Jump to a trampoline, loading the static chain address. */
1427
1428#ifdef TRANSFER_FROM_TRAMPOLINE
1429TRANSFER_FROM_TRAMPOLINE
1430#endif
1431
1432#ifdef __convex__
1433
1434/* Make stack executable so we can call trampolines on stack.
1435 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1436
1437#include <sys/mman.h>
1438#include <sys/vmparam.h>
1439#include <machine/machparam.h>
1440
1441void
1442__enable_execute_stack ()
1443{
1444 int fp;
1445 static unsigned lowest = USRSTACK;
1446 unsigned current = (unsigned) &fp & -NBPG;
1447
1448 if (lowest > current)
1449 {
1450 unsigned len = lowest - current;
1451 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1452 lowest = current;
1453 }
1454
1455 /* Clear instruction cache in case an old trampoline is in it. */
1456 asm ("pich");
1457}
1458#endif /* __convex__ */
b335c2cc
TW
1459
1460#ifdef __pyr__
1461
1462#include <stdio.h>
1463#include <sys/mman.h>
1464#include <sys/types.h>
1465#include <sys/param.h>
1466#include <sys/vmmac.h>
1467
1468/* Modified from the convex -code above.
1469 mremap promises to clear the i-cache. */
1470
1471void
1472__enable_execute_stack ()
1473{
1474 int fp;
1475 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1476 PROT_READ|PROT_WRITE|PROT_EXEC))
1477 {
1478 perror ("mprotect in __enable_execute_stack");
1479 fflush (stderr);
1480 abort ();
1481 }
1482}
1483#endif /* __pyr__ */
203b91b9
RS
1484#endif /* L_trampoline */
1485\f
1486#ifdef L__main
1487
1488#include "gbl-ctors.h"
1489
1490/* Run all the global destructors on exit from the program. */
1491
1492void
1493__do_global_dtors ()
1494{
89cf554b
RS
1495#ifdef DO_GLOBAL_DTORS_BODY
1496 DO_GLOBAL_DTORS_BODY;
1497#else
0dadecf6 1498 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
b6422cca 1499 unsigned i;
203b91b9
RS
1500
1501 /* Some systems place the number of pointers
1502 in the first word of the table.
1503 On other systems, that word is -1.
1504 In all cases, the table is null-terminated. */
1505
1506 /* If the length is not recorded, count up to the null. */
1507 if (nptrs == -1)
1508 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1509
1510 /* GNU LD format. */
1511 for (i = nptrs; i >= 1; i--)
1512 __DTOR_LIST__[i] ();
89cf554b 1513#endif
203b91b9
RS
1514}
1515
1516#ifndef INIT_SECTION_ASM_OP
1517/* Run all the global constructors on entry to the program. */
1518
135461d9 1519#ifndef ON_EXIT
203b91b9
RS
1520#define ON_EXIT(a, b)
1521#else
1522/* Make sure the exit routine is pulled in to define the globals as
1523 bss symbols, just in case the linker does not automatically pull
1524 bss definitions from the library. */
1525
1526extern int _exit_dummy_decl;
1527int *_exit_dummy_ref = &_exit_dummy_decl;
1528#endif /* ON_EXIT */
1529
1530void
1531__do_global_ctors ()
1532{
1533 DO_GLOBAL_CTORS_BODY;
135461d9 1534 ON_EXIT (__do_global_dtors, 0);
203b91b9 1535}
b335c2cc 1536#endif /* no INIT_SECTION_ASM_OP */
203b91b9 1537
b335c2cc 1538#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
203b91b9
RS
1539/* Subroutine called automatically by `main'.
1540 Compiling a global function named `main'
1541 produces an automatic call to this function at the beginning.
1542
1543 For many systems, this routine calls __do_global_ctors.
1544 For systems which support a .init section we use the .init section
1545 to run __do_global_ctors, so we need not do anything here. */
1546
1547void
1548__main ()
1549{
1550 /* Support recursive calls to `main': run initializers just once. */
b6422cca 1551 static int initialized = 0;
203b91b9
RS
1552 if (! initialized)
1553 {
1554 initialized = 1;
1555 __do_global_ctors ();
1556 }
1557}
b335c2cc 1558#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
203b91b9
RS
1559
1560#endif /* L__main */
1561\f
1562#ifdef L_exit
1563
1564#include "gbl-ctors.h"
1565
1566/* Provide default definitions for the lists of constructors and
1567 destructors, so that we don't get linker errors. These symbols are
1568 intentionally bss symbols, so that gld and/or collect will provide
1569 the right values. */
1570
1571/* We declare the lists here with two elements each,
1572 so that they are valid empty lists if no other definition is loaded. */
b335c2cc 1573#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
203b91b9
RS
1574func_ptr __CTOR_LIST__[2];
1575func_ptr __DTOR_LIST__[2];
b335c2cc 1576#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
203b91b9
RS
1577
1578#ifndef ON_EXIT
1579
1580/* If we have no known way of registering our own __do_global_dtors
1581 routine so that it will be invoked at program exit time, then we
1582 have to define our own exit routine which will get this to happen. */
1583
1584extern void __do_global_dtors ();
1585extern void _cleanup ();
1586extern void _exit ();
1587
1588void
1589exit (status)
1590 int status;
1591{
1592 __do_global_dtors ();
1593#ifdef EXIT_BODY
1594 EXIT_BODY;
1595#else
1596 _cleanup ();
1597#endif
1598 _exit (status);
1599}
1600
1601#else
1602int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1603#endif
1604
1605#endif /* L_exit */
1606\f
1607/* In a.out systems, we need to have these dummy constructor and destructor
1608 lists in the library.
1609
1610 When using `collect', the first link will resolve __CTOR_LIST__
1611 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1612 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1613 Since we don't do the second link if no constructors existed, these
1614 dummies must be fully functional empty lists.
1615
1616 When using `gnu ld', these symbols will be used if there are no
1617 constructors. If there are constructors, the N_SETV symbol defined
1618 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1619 and __DTOR_LIST__ rather than its being allocated as common storage
1620 by the definitions below.
1621
1622 When using a linker that supports constructor and destructor segments,
1623 these definitions will not be used, since crtbegin.o and crtend.o
1624 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1625 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1626 on its command line, by gcc. */
1627
1628/* The list needs two elements: one is ignored (the old count); the
1629 second is the terminating zero. Since both values are zero, this
1630 declaration is not initialized, and it becomes `common'. */
1631
1632#ifdef L_ctor_list
1633#include "gbl-ctors.h"
1634func_ptr __CTOR_LIST__[2];
1635#endif
1636
1637#ifdef L_dtor_list
1638#include "gbl-ctors.h"
1639func_ptr __DTOR_LIST__[2];
1640#endif
This page took 0.246019 seconds and 5 git commands to generate.