]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/libgcc2.c
(variable_size): Change back to NULL_PTR.
[thirdparty/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 64
a1c37766 65/* Make sure that we don't accidentally use any normal C language built-in
ab495388
RS
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
a1c37766 68 that if we *do* accidentally use soem normal C language built-in type name,
ab495388
RS
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 {
7bc7d45a 287 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
431b1ee0
TG
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 */
7bc7d45a 295 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
431b1ee0
TG
296 /* Divide (c1*2^32 + c0) by d */
297 sdiv_qrnnd (q, r, c1, c0, d);
298 /* Add 2^31 to quotient */
7bc7d45a 299 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
431b1ee0
TG
300 }
301 }
302 else
303 {
304 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
305 c1 = a1 >> 1; /* A/2 */
7bc7d45a 306 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
431b1ee0
TG
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
9bd23d2c
RS
978\f
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
985int
986__gcc_bcmp (s1, s2, size)
78e33213 987 unsigned char *s1, *s2;
9bd23d2c
RS
988 size_t size;
989{
990 while (size > 0)
991 {
78e33213 992 unsigned char c1 = *s1++, c2 = *s2++;
9bd23d2c
RS
993 if (c1 != c2)
994 return c1 - c2;
995 size--;
996 }
997 return 0;
998}
ab495388 999
9bd23d2c
RS
1000#endif
1001\f\f
203b91b9
RS
1002#ifdef L_varargs
1003#ifdef __i860__
600032fc 1004#if defined(__svr4__) || defined(__alliant__)
203b91b9
RS
1005 asm (" .text");
1006 asm (" .align 4");
1007
27d21d32 1008/* The Alliant needs the added underscore. */
203b91b9
RS
1009 asm (".globl __builtin_saveregs");
1010asm ("__builtin_saveregs:");
27d21d32
RS
1011 asm (".globl ___builtin_saveregs");
1012asm ("___builtin_saveregs:");
1013
1014 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
203b91b9
RS
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
600032fc 1069#else /* not __SVR4__ */
203b91b9
RS
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. */
600032fc 1107#endif /* not __SVR4__ */
203b91b9
RS
1108#else /* not __i860__ */
1109#ifdef __sparc__
b335c2cc
TW
1110 asm (".global __builtin_saveregs");
1111 asm ("__builtin_saveregs:");
203b91b9
RS
1112 asm (".global ___builtin_saveregs");
1113 asm ("___builtin_saveregs:");
b1166fae
RS
1114#ifdef NEED_PROC_COMMAND
1115 asm (".proc 020");
b335c2cc 1116#endif
203b91b9
RS
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]");
b1166fae
RS
1124#ifdef NEED_TYPE_COMMAND
1125 asm (".type __builtin_saveregs,#function");
1126 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1127#endif
203b91b9
RS
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\f
1151#ifdef L_eprintf
bba2431c
RS
1152#ifndef inhibit_eprintf
1153
203b91b9
RS
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. */
1157void
1158__eprintf (string, expression, line, filename)
b1166fae
RS
1159 const char *string;
1160 const char *expression;
203b91b9 1161 int line;
b1166fae 1162 const char *filename;
203b91b9
RS
1163{
1164 fprintf (stderr, string, expression, line, filename);
1165 fflush (stderr);
1166 abort ();
1167}
bba2431c
RS
1168
1169#endif
203b91b9
RS
1170#endif
1171
1172#ifdef L_bb
1173/* Avoid warning from ranlib about empty object file. */
1174void
1175__bb_avoid_warning ()
1176{}
1177
1178#if defined (__sun__) && defined (__mc68000__)
1179struct bb
1180{
1181 int initialized;
1182 char *filename;
1183 int *counts;
1184 int ncounts;
1185 int zero_word;
1186 int *addresses;
1187};
1188
1189extern 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\f
1203/* frills for C++ */
1204
ec06f00a 1205#ifdef L_op_new
203b91b9
RS
1206typedef void (*vfp)(void);
1207
1208extern vfp __new_handler;
1209
ec06f00a 1210/* void * operator new (size_t sz) */
203b91b9 1211void *
ec06f00a 1212__builtin_new (size_t sz)
203b91b9
RS
1213{
1214 void *p;
1215
bcea2185
RS
1216 /* malloc (0) is unpredictable; avoid it. */
1217 if (sz == 0)
1218 sz = 1;
ecbe06a1 1219 p = (void *) malloc (sz);
203b91b9
RS
1220 if (p == 0)
1221 (*__new_handler) ();
1222 return p;
1223}
ec06f00a 1224#endif /* L_op_new */
203b91b9 1225
ec06f00a 1226#ifdef L_new_handler
fffa6914
RS
1227
1228/* This gets us __GNU_LIBRARY__. */
98126ed6 1229#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
fffa6914
RS
1230#include <stdio.h>
1231
1232#ifdef __GNU_LIBRARY__
1233 /* Avoid forcing the library's meaning of `write' on the user program
e45d9b98 1234 by using the "internal" name (for use within the library) */
fffa6914
RS
1235#define write(fd, buf, n) __write((fd), (buf), (n))
1236#endif
1237
203b91b9
RS
1238typedef void (*vfp)(void);
1239
b6422cca
RS
1240extern void *__builtin_new (size_t);
1241static void default_new_handler (void);
203b91b9
RS
1242
1243vfp __new_handler = default_new_handler;
1244
203b91b9
RS
1245vfp
1246__set_new_handler (handler)
1247 vfp handler;
1248{
1249 vfp prev_handler;
1250
1251 prev_handler = __new_handler;
1252 if (handler == 0) handler = default_new_handler;
1253 __new_handler = handler;
1254 return prev_handler;
1255}
1256
1257vfp
1258set_new_handler (handler)
1259 vfp handler;
1260{
1261 return __set_new_handler (handler);
1262}
1263
b1166fae
RS
1264#define MESSAGE "Virtual memory exceeded in `new'\n"
1265
203b91b9
RS
1266static void
1267default_new_handler ()
1268{
1269 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1270 /* This should really print the name of the program, but that is hard to
1271 do. We need a standard, clean way to get at the name. */
b1166fae 1272 write (2, MESSAGE, sizeof (MESSAGE));
203b91b9
RS
1273 /* don't call exit () because that may call global destructors which
1274 may cause a loop. */
1275 _exit (-1);
1276}
1277#endif
203b91b9 1278
ec06f00a
JW
1279#ifdef L_op_delete
1280/* void operator delete (void *ptr) */
203b91b9 1281void
ec06f00a 1282__builtin_delete (void *ptr)
203b91b9
RS
1283{
1284 if (ptr)
1285 free (ptr);
1286}
203b91b9 1287#endif
ec06f00a 1288\f
203b91b9
RS
1289#ifdef L_shtab
1290unsigned int __shtab[] = {
1291 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1292 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1293 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1294 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1295 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1296 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1297 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1298 0x10000000, 0x20000000, 0x40000000, 0x80000000
1299 };
1300#endif
1301\f
1302#ifdef L_clear_cache
1303/* Clear part of an instruction cache. */
1304
1305#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1306
1307void
1308__clear_cache (beg, end)
1309 char *beg, *end;
1310{
1311#ifdef INSN_CACHE_SIZE
1312 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1313 static int initialized = 0;
1314 int offset;
b6422cca
RS
1315 void *start_addr
1316 void *end_addr;
203b91b9
RS
1317 typedef (*function_ptr) ();
1318
1319#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1320 /* It's cheaper to clear the whole cache.
1321 Put in a series of jump instructions so that calling the beginning
1322 of the cache will clear the whole thing. */
1323
1324 if (! initialized)
1325 {
1326 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1327 & -INSN_CACHE_LINE_WIDTH);
1328 int end_ptr = ptr + INSN_CACHE_SIZE;
1329
1330 while (ptr < end_ptr)
1331 {
1332 *(INSTRUCTION_TYPE *)ptr
1333 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1334 ptr += INSN_CACHE_LINE_WIDTH;
1335 }
1336 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1337
1338 initialized = 1;
1339 }
1340
1341 /* Call the beginning of the sequence. */
1342 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1343 & -INSN_CACHE_LINE_WIDTH))
1344 ());
1345
1346#else /* Cache is large. */
1347
1348 if (! initialized)
1349 {
1350 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1351 & -INSN_CACHE_LINE_WIDTH);
1352
1353 while (ptr < (int) array + sizeof array)
1354 {
1355 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1356 ptr += INSN_CACHE_LINE_WIDTH;
1357 }
1358
1359 initialized = 1;
1360 }
1361
1362 /* Find the location in array that occupies the same cache line as BEG. */
1363
1364 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1365 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1366 & -INSN_CACHE_PLANE_SIZE)
1367 + offset);
1368
1369 /* Compute the cache alignment of the place to stop clearing. */
1370#if 0 /* This is not needed for gcc's purposes. */
1371 /* If the block to clear is bigger than a cache plane,
1372 we clear the entire cache, and OFFSET is already correct. */
1373 if (end < beg + INSN_CACHE_PLANE_SIZE)
1374#endif
1375 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1376 & -INSN_CACHE_LINE_WIDTH)
1377 & (INSN_CACHE_PLANE_SIZE - 1));
1378
1379#if INSN_CACHE_DEPTH > 1
1380 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1381 if (end_addr <= start_addr)
1382 end_addr += INSN_CACHE_PLANE_SIZE;
1383
1384 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1385 {
1386 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1387 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1388
1389 while (addr != stop)
1390 {
1391 /* Call the return instruction at ADDR. */
1392 ((function_ptr) addr) ();
1393
1394 addr += INSN_CACHE_LINE_WIDTH;
1395 }
1396 }
1397#else /* just one plane */
1398 do
1399 {
1400 /* Call the return instruction at START_ADDR. */
1401 ((function_ptr) start_addr) ();
1402
1403 start_addr += INSN_CACHE_LINE_WIDTH;
1404 }
1405 while ((start_addr % INSN_CACHE_SIZE) != offset);
1406#endif /* just one plane */
1407#endif /* Cache is large */
1408#endif /* Cache exists */
1409}
1410
1411#endif /* L_clear_cache */
1412\f
1413#ifdef L_trampoline
1414
1415/* Jump to a trampoline, loading the static chain address. */
1416
1417#ifdef TRANSFER_FROM_TRAMPOLINE
1418TRANSFER_FROM_TRAMPOLINE
1419#endif
1420
1421#ifdef __convex__
1422
1423/* Make stack executable so we can call trampolines on stack.
1424 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1425
1426#include <sys/mman.h>
1427#include <sys/vmparam.h>
1428#include <machine/machparam.h>
1429
1430void
1431__enable_execute_stack ()
1432{
1433 int fp;
1434 static unsigned lowest = USRSTACK;
1435 unsigned current = (unsigned) &fp & -NBPG;
1436
1437 if (lowest > current)
1438 {
1439 unsigned len = lowest - current;
1440 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1441 lowest = current;
1442 }
1443
1444 /* Clear instruction cache in case an old trampoline is in it. */
1445 asm ("pich");
1446}
1447#endif /* __convex__ */
b335c2cc
TW
1448
1449#ifdef __pyr__
1450
98126ed6 1451#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
b335c2cc
TW
1452#include <stdio.h>
1453#include <sys/mman.h>
1454#include <sys/types.h>
1455#include <sys/param.h>
1456#include <sys/vmmac.h>
1457
1458/* Modified from the convex -code above.
1459 mremap promises to clear the i-cache. */
1460
1461void
1462__enable_execute_stack ()
1463{
1464 int fp;
1465 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1466 PROT_READ|PROT_WRITE|PROT_EXEC))
1467 {
1468 perror ("mprotect in __enable_execute_stack");
1469 fflush (stderr);
1470 abort ();
1471 }
1472}
1473#endif /* __pyr__ */
203b91b9
RS
1474#endif /* L_trampoline */
1475\f
1476#ifdef L__main
1477
1478#include "gbl-ctors.h"
1479
1480/* Run all the global destructors on exit from the program. */
1481
1482void
1483__do_global_dtors ()
1484{
89cf554b
RS
1485#ifdef DO_GLOBAL_DTORS_BODY
1486 DO_GLOBAL_DTORS_BODY;
1487#else
0dadecf6 1488 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
b6422cca 1489 unsigned i;
203b91b9
RS
1490
1491 /* Some systems place the number of pointers
1492 in the first word of the table.
1493 On other systems, that word is -1.
1494 In all cases, the table is null-terminated. */
1495
1496 /* If the length is not recorded, count up to the null. */
1497 if (nptrs == -1)
1498 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1499
1500 /* GNU LD format. */
1501 for (i = nptrs; i >= 1; i--)
1502 __DTOR_LIST__[i] ();
89cf554b 1503#endif
203b91b9
RS
1504}
1505
1506#ifndef INIT_SECTION_ASM_OP
1507/* Run all the global constructors on entry to the program. */
1508
135461d9 1509#ifndef ON_EXIT
203b91b9
RS
1510#define ON_EXIT(a, b)
1511#else
1512/* Make sure the exit routine is pulled in to define the globals as
1513 bss symbols, just in case the linker does not automatically pull
1514 bss definitions from the library. */
1515
1516extern int _exit_dummy_decl;
1517int *_exit_dummy_ref = &_exit_dummy_decl;
1518#endif /* ON_EXIT */
1519
1520void
1521__do_global_ctors ()
1522{
1523 DO_GLOBAL_CTORS_BODY;
135461d9 1524 ON_EXIT (__do_global_dtors, 0);
203b91b9 1525}
b335c2cc 1526#endif /* no INIT_SECTION_ASM_OP */
203b91b9 1527
b335c2cc 1528#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
203b91b9
RS
1529/* Subroutine called automatically by `main'.
1530 Compiling a global function named `main'
1531 produces an automatic call to this function at the beginning.
1532
1533 For many systems, this routine calls __do_global_ctors.
1534 For systems which support a .init section we use the .init section
1535 to run __do_global_ctors, so we need not do anything here. */
1536
1537void
1538__main ()
1539{
1540 /* Support recursive calls to `main': run initializers just once. */
b6422cca 1541 static int initialized = 0;
203b91b9
RS
1542 if (! initialized)
1543 {
1544 initialized = 1;
1545 __do_global_ctors ();
1546 }
1547}
b335c2cc 1548#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
203b91b9
RS
1549
1550#endif /* L__main */
1551\f
ad38743d 1552#ifdef L_ctors
203b91b9
RS
1553
1554#include "gbl-ctors.h"
1555
1556/* Provide default definitions for the lists of constructors and
1557 destructors, so that we don't get linker errors. These symbols are
1558 intentionally bss symbols, so that gld and/or collect will provide
1559 the right values. */
1560
1561/* We declare the lists here with two elements each,
1562 so that they are valid empty lists if no other definition is loaded. */
b335c2cc 1563#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
d15d0264
RS
1564#ifdef __NeXT__
1565/* After 2.3, try this definition on all systems. */
1566func_ptr __CTOR_LIST__[2] = {0, 0};
1567func_ptr __DTOR_LIST__[2] = {0, 0};
1568#else
203b91b9
RS
1569func_ptr __CTOR_LIST__[2];
1570func_ptr __DTOR_LIST__[2];
d15d0264 1571#endif
b335c2cc 1572#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
ad38743d
RS
1573#endif /* L_ctors */
1574\f
1575#ifdef L_exit
1576
1577#include "gbl-ctors.h"
203b91b9
RS
1578
1579#ifndef ON_EXIT
1580
1581/* If we have no known way of registering our own __do_global_dtors
1582 routine so that it will be invoked at program exit time, then we
1583 have to define our own exit routine which will get this to happen. */
1584
1585extern void __do_global_dtors ();
1586extern void _cleanup ();
ad38743d 1587extern volatile void _exit ();
203b91b9
RS
1588
1589void
1590exit (status)
1591 int status;
1592{
1593 __do_global_dtors ();
1594#ifdef EXIT_BODY
1595 EXIT_BODY;
1596#else
1597 _cleanup ();
1598#endif
1599 _exit (status);
1600}
1601
1602#else
1603int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1604#endif
1605
1606#endif /* L_exit */
1607\f
1608/* In a.out systems, we need to have these dummy constructor and destructor
1609 lists in the library.
1610
1611 When using `collect', the first link will resolve __CTOR_LIST__
1612 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1613 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1614 Since we don't do the second link if no constructors existed, these
1615 dummies must be fully functional empty lists.
1616
1617 When using `gnu ld', these symbols will be used if there are no
1618 constructors. If there are constructors, the N_SETV symbol defined
1619 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1620 and __DTOR_LIST__ rather than its being allocated as common storage
1621 by the definitions below.
1622
1623 When using a linker that supports constructor and destructor segments,
1624 these definitions will not be used, since crtbegin.o and crtend.o
1625 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1626 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1627 on its command line, by gcc. */
1628
1629/* The list needs two elements: one is ignored (the old count); the
1630 second is the terminating zero. Since both values are zero, this
1631 declaration is not initialized, and it becomes `common'. */
1632
1633#ifdef L_ctor_list
1634#include "gbl-ctors.h"
1635func_ptr __CTOR_LIST__[2];
1636#endif
1637
1638#ifdef L_dtor_list
1639#include "gbl-ctors.h"
1640func_ptr __DTOR_LIST__[2];
1641#endif