]> gcc.gnu.org Git - gcc.git/blame - gcc/libgcc2.c
(convert_to_integer): Don't add a NOP_EXPR in cases where we can
[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"
b335c2cc 32#ifndef L_trampoline
203b91b9 33#include "gstddef.h"
b335c2cc 34#endif
203b91b9
RS
35
36/* Don't use `fancy_abort' here even if config.h says to use it. */
37#ifdef abort
38#undef abort
39#endif
40
ab495388
RS
41/* In the first part of this file, we are interfacing to calls generated
42 by the compiler itself. These calls pass values into these routines
43 which have very specific modes (rather than very specific types), and
44 these compiler-generated calls also expect any return values to have
45 very specific modes (rather than very specific types). Thus, we need
46 to avoid using regular C language type names in this part of the file
47 because the sizes for those types can be configured to be anything.
48 Instead we use the following special type names. */
49
50typedef unsigned int UQItype __attribute__ ((mode (QI)));
51typedef int SItype __attribute__ ((mode (SI)));
52typedef unsigned int USItype __attribute__ ((mode (SI)));
53typedef int DItype __attribute__ ((mode (DI)));
54typedef unsigned int UDItype __attribute__ ((mode (DI)));
55typedef float SFtype __attribute__ ((mode (SF)));
56typedef float DFtype __attribute__ ((mode (DF)));
258d1356 57#if 0
ab495388 58typedef float XFtype __attribute__ ((mode (XF)));
258d1356
CH
59#endif
60#if LONG_DOUBLE_TYPE_SIZE == 128
ab495388 61typedef float TFtype __attribute__ ((mode (TF)));
258d1356 62#endif
ab495388
RS
63
64/* Make sure that we don't accidentaly use any normal C language built-in
65 type names in the first part of this file. Instead we want to use *only*
66 the type names defined above. The following macro definitions insure
67 that if we *do* accidently use soem normal C language built-in type name,
68 we will get a syntax error. */
69
70#define char bogus_type
71#define short bogus_type
72#define int bogus_type
73#define long bogus_type
74#define unsigned bogus_type
75#define float bogus_type
76#define double bogus_type
77
78#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
79
80/* DIstructs are pairs of SItype values in the order determined by
203b91b9
RS
81 WORDS_BIG_ENDIAN. */
82
83#if WORDS_BIG_ENDIAN
ab495388 84 struct DIstruct {SItype high, low;};
203b91b9 85#else
ab495388 86 struct DIstruct {SItype low, high;};
203b91b9
RS
87#endif
88
ab495388
RS
89/* We need this union to unpack/pack DImode values, since we don't have
90 any arithmetic yet. Incoming DImode parameters are stored into the
91 `ll' field, and the unpacked result is read from the struct `s'. */
203b91b9
RS
92
93typedef union
94{
ab495388
RS
95 struct DIstruct s;
96 DItype ll;
97} DIunion;
203b91b9 98
3904131a 99#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
203b91b9
RS
100
101#include "longlong.h"
102
103#endif /* udiv or mul */
104
ab495388
RS
105extern DItype __fixunssfdi (SFtype a);
106extern DItype __fixunsdfdi (DFtype a);
203b91b9
RS
107\f
108#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
109#if defined (L_divdi3) || defined (L_moddi3)
110static inline
111#endif
ab495388 112DItype
203b91b9 113__negdi2 (u)
ab495388 114 DItype u;
203b91b9 115{
ab495388
RS
116 DIunion w;
117 DIunion uu;
203b91b9
RS
118
119 uu.ll = u;
120
121 w.s.low = -uu.s.low;
ab495388 122 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
203b91b9
RS
123
124 return w.ll;
125}
126#endif
127\f
128#ifdef L_lshldi3
ab495388 129DItype
203b91b9 130__lshldi3 (u, b)
ab495388
RS
131 DItype u;
132 SItype b;
203b91b9 133{
ab495388
RS
134 DIunion w;
135 SItype bm;
136 DIunion uu;
203b91b9
RS
137
138 if (b == 0)
139 return u;
140
141 uu.ll = u;
142
ab495388 143 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
144 if (bm <= 0)
145 {
146 w.s.low = 0;
ab495388 147 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
148 }
149 else
150 {
ab495388
RS
151 USItype carries = (USItype)uu.s.low >> bm;
152 w.s.low = (USItype)uu.s.low << b;
153 w.s.high = ((USItype)uu.s.high << b) | carries;
203b91b9
RS
154 }
155
156 return w.ll;
157}
158#endif
159
160#ifdef L_lshrdi3
ab495388 161DItype
203b91b9 162__lshrdi3 (u, b)
ab495388
RS
163 DItype u;
164 SItype b;
203b91b9 165{
ab495388
RS
166 DIunion w;
167 SItype bm;
168 DIunion uu;
203b91b9
RS
169
170 if (b == 0)
171 return u;
172
173 uu.ll = u;
174
ab495388 175 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
176 if (bm <= 0)
177 {
178 w.s.high = 0;
ab495388 179 w.s.low = (USItype)uu.s.high >> -bm;
203b91b9
RS
180 }
181 else
182 {
ab495388
RS
183 USItype carries = (USItype)uu.s.high << bm;
184 w.s.high = (USItype)uu.s.high >> b;
185 w.s.low = ((USItype)uu.s.low >> b) | carries;
203b91b9
RS
186 }
187
188 return w.ll;
189}
190#endif
191
192#ifdef L_ashldi3
ab495388 193DItype
203b91b9 194__ashldi3 (u, b)
ab495388
RS
195 DItype u;
196 SItype b;
203b91b9 197{
ab495388
RS
198 DIunion w;
199 SItype bm;
200 DIunion uu;
203b91b9
RS
201
202 if (b == 0)
203 return u;
204
205 uu.ll = u;
206
ab495388 207 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
208 if (bm <= 0)
209 {
210 w.s.low = 0;
ab495388 211 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
212 }
213 else
214 {
ab495388
RS
215 USItype carries = (USItype)uu.s.low >> bm;
216 w.s.low = (USItype)uu.s.low << b;
217 w.s.high = ((USItype)uu.s.high << b) | carries;
203b91b9
RS
218 }
219
220 return w.ll;
221}
222#endif
223
224#ifdef L_ashrdi3
ab495388 225DItype
203b91b9 226__ashrdi3 (u, b)
ab495388
RS
227 DItype u;
228 SItype b;
203b91b9 229{
ab495388
RS
230 DIunion w;
231 SItype bm;
232 DIunion uu;
203b91b9
RS
233
234 if (b == 0)
235 return u;
236
237 uu.ll = u;
238
ab495388 239 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
240 if (bm <= 0)
241 {
242 /* w.s.high = 1..1 or 0..0 */
ab495388 243 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
203b91b9
RS
244 w.s.low = uu.s.high >> -bm;
245 }
246 else
247 {
ab495388 248 USItype carries = (USItype)uu.s.high << bm;
203b91b9 249 w.s.high = uu.s.high >> b;
ab495388 250 w.s.low = ((USItype)uu.s.low >> b) | carries;
203b91b9
RS
251 }
252
253 return w.ll;
254}
255#endif
256\f
257#ifdef L_muldi3
ab495388 258DItype
203b91b9 259__muldi3 (u, v)
ab495388 260 DItype u, v;
203b91b9 261{
ab495388
RS
262 DIunion w;
263 DIunion uu, vv;
203b91b9
RS
264
265 uu.ll = u,
266 vv.ll = v;
267
268 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
ab495388
RS
269 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
270 + (USItype) uu.s.high * (USItype) vv.s.low);
203b91b9
RS
271
272 return w.ll;
273}
274#endif
275\f
3904131a 276#ifdef L_udiv_w_sdiv
431b1ee0 277USItype
3904131a 278__udiv_w_sdiv (rp, a1, a0, d)
431b1ee0
TG
279 USItype *rp, a1, a0, d;
280{
281 USItype q, r;
282 USItype c0, c1, b1;
283
284 if ((SItype) d >= 0)
285 {
286 if (a1 < d - a1 - (a0 >> 31))
287 {
288 /* dividend, divisor, and quotient are nonnegative */
289 sdiv_qrnnd (q, r, a1, a0, d);
290 }
291 else
292 {
293 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
294 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << 31);
295 /* Divide (c1*2^32 + c0) by d */
296 sdiv_qrnnd (q, r, c1, c0, d);
297 /* Add 2^31 to quotient */
298 q += 1 << 31;
299 }
300 }
301 else
302 {
303 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
304 c1 = a1 >> 1; /* A/2 */
305 c0 = (a1 << 31) + (a0 >> 1);
306
307 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
308 {
309 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
310
311 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
312 if ((d & 1) != 0)
313 {
314 if (r >= q)
315 r = r - q;
316 else if (q - r <= d)
317 {
318 r = r - q + d;
319 q--;
320 }
321 else
322 {
323 r = r - q + 2*d;
324 q -= 2;
325 }
326 }
327 }
328 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
329 {
330 c1 = (b1 - 1) - c1;
331 c0 = ~c0; /* logical NOT */
332
333 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
334
335 q = ~q; /* (A/2)/b1 */
336 r = (b1 - 1) - r;
337
338 r = 2*r + (a0 & 1); /* A/(2*b1) */
339
340 if ((d & 1) != 0)
341 {
342 if (r >= q)
343 r = r - q;
344 else if (q - r <= d)
345 {
346 r = r - q + d;
347 q--;
348 }
349 else
350 {
351 r = r - q + 2*d;
352 q -= 2;
353 }
354 }
355 }
356 else /* Implies c1 = b1 */
357 { /* Hence a1 = d - 1 = 2*b1 - 1 */
358 if (a0 >= -d)
359 {
360 q = -1;
361 r = a0 + d;
362 }
363 else
364 {
365 q = -2;
366 r = a0 + 2*d;
367 }
368 }
369 }
370
371 *rp = r;
372 return q;
373}
374#endif
375\f
203b91b9 376#ifdef L_udivmoddi4
ab495388 377static const UQItype __clz_tab[] =
203b91b9
RS
378{
379 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,
380 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,
381 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,
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 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,
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};
388
ab495388 389UDItype
203b91b9 390__udivmoddi4 (n, d, rp)
ab495388
RS
391 UDItype n, d;
392 UDItype *rp;
203b91b9 393{
ab495388
RS
394 DIunion ww;
395 DIunion nn, dd;
396 DIunion rr;
397 USItype d0, d1, n0, n1, n2;
398 USItype q0, q1;
399 USItype b, bm;
203b91b9
RS
400
401 nn.ll = n;
402 dd.ll = d;
403
404 d0 = dd.s.low;
405 d1 = dd.s.high;
406 n0 = nn.s.low;
407 n1 = nn.s.high;
408
409#if !UDIV_NEEDS_NORMALIZATION
410 if (d1 == 0)
411 {
412 if (d0 > n1)
413 {
414 /* 0q = nn / 0D */
415
416 udiv_qrnnd (q0, n0, n1, n0, d0);
417 q1 = 0;
418
419 /* Remainder in n0. */
420 }
421 else
422 {
423 /* qq = NN / 0d */
424
425 if (d0 == 0)
426 d0 = 1 / d0; /* Divide intentionally by zero. */
427
428 udiv_qrnnd (q1, n1, 0, n1, d0);
429 udiv_qrnnd (q0, n0, n1, n0, d0);
430
431 /* Remainder in n0. */
432 }
433
434 if (rp != 0)
435 {
436 rr.s.low = n0;
437 rr.s.high = 0;
438 *rp = rr.ll;
439 }
440 }
441
442#else /* UDIV_NEEDS_NORMALIZATION */
443
444 if (d1 == 0)
445 {
446 if (d0 > n1)
447 {
448 /* 0q = nn / 0D */
449
450 count_leading_zeros (bm, d0);
451
452 if (bm != 0)
453 {
454 /* Normalize, i.e. make the most significant bit of the
455 denominator set. */
456
457 d0 = d0 << bm;
ab495388 458 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
203b91b9
RS
459 n0 = n0 << bm;
460 }
461
462 udiv_qrnnd (q0, n0, n1, n0, d0);
463 q1 = 0;
464
465 /* Remainder in n0 >> bm. */
466 }
467 else
468 {
469 /* qq = NN / 0d */
470
471 if (d0 == 0)
472 d0 = 1 / d0; /* Divide intentionally by zero. */
473
474 count_leading_zeros (bm, d0);
475
476 if (bm == 0)
477 {
478 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
479 conclude (the most significant bit of n1 is set) /\ (the
480 leading quotient digit q1 = 1).
481
482 This special case is necessary, not an optimization.
ab495388 483 (Shifts counts of SI_TYPE_SIZE are undefined.) */
203b91b9
RS
484
485 n1 -= d0;
486 q1 = 1;
487 }
488 else
489 {
490 /* Normalize. */
491
ab495388 492 b = SI_TYPE_SIZE - bm;
203b91b9
RS
493
494 d0 = d0 << bm;
495 n2 = n1 >> b;
496 n1 = (n1 << bm) | (n0 >> b);
497 n0 = n0 << bm;
498
499 udiv_qrnnd (q1, n1, n2, n1, d0);
500 }
501
502 /* n1 != d0... */
503
504 udiv_qrnnd (q0, n0, n1, n0, d0);
505
506 /* Remainder in n0 >> bm. */
507 }
508
509 if (rp != 0)
510 {
511 rr.s.low = n0 >> bm;
512 rr.s.high = 0;
513 *rp = rr.ll;
514 }
515 }
516#endif /* UDIV_NEEDS_NORMALIZATION */
517
518 else
519 {
520 if (d1 > n1)
521 {
522 /* 00 = nn / DD */
523
524 q0 = 0;
525 q1 = 0;
526
527 /* Remainder in n1n0. */
528 if (rp != 0)
529 {
530 rr.s.low = n0;
531 rr.s.high = n1;
532 *rp = rr.ll;
533 }
534 }
535 else
536 {
537 /* 0q = NN / dd */
538
539 count_leading_zeros (bm, d1);
540 if (bm == 0)
541 {
542 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
543 conclude (the most significant bit of n1 is set) /\ (the
544 quotient digit q0 = 0 or 1).
545
546 This special case is necessary, not an optimization. */
547
548 /* The condition on the next line takes advantage of that
549 n1 >= d1 (true due to program flow). */
550 if (n1 > d1 || n0 >= d0)
551 {
552 q0 = 1;
553 sub_ddmmss (n1, n0, n1, n0, d1, d0);
554 }
555 else
556 q0 = 0;
557
558 q1 = 0;
559
560 if (rp != 0)
561 {
562 rr.s.low = n0;
563 rr.s.high = n1;
564 *rp = rr.ll;
565 }
566 }
567 else
568 {
ab495388 569 USItype m1, m0;
203b91b9
RS
570 /* Normalize. */
571
ab495388 572 b = SI_TYPE_SIZE - bm;
203b91b9
RS
573
574 d1 = (d1 << bm) | (d0 >> b);
575 d0 = d0 << bm;
576 n2 = n1 >> b;
577 n1 = (n1 << bm) | (n0 >> b);
578 n0 = n0 << bm;
579
580 udiv_qrnnd (q0, n1, n2, n1, d1);
581 umul_ppmm (m1, m0, q0, d0);
582
583 if (m1 > n1 || (m1 == n1 && m0 > n0))
584 {
585 q0--;
586 sub_ddmmss (m1, m0, m1, m0, d1, d0);
587 }
588
589 q1 = 0;
590
591 /* Remainder in (n1n0 - m1m0) >> bm. */
592 if (rp != 0)
593 {
594 sub_ddmmss (n1, n0, n1, n0, m1, m0);
595 rr.s.low = (n1 << b) | (n0 >> bm);
596 rr.s.high = n1 >> bm;
597 *rp = rr.ll;
598 }
599 }
600 }
601 }
602
603 ww.s.low = q0;
604 ww.s.high = q1;
605 return ww.ll;
606}
607#endif
608
609#ifdef L_divdi3
ab495388
RS
610UDItype __udivmoddi4 ();
611DItype
203b91b9 612__divdi3 (u, v)
ab495388 613 DItype u, v;
203b91b9 614{
ab495388
RS
615 SItype c = 0;
616 DIunion uu, vv;
617 DItype w;
203b91b9
RS
618
619 uu.ll = u;
620 vv.ll = v;
621
622 if (uu.s.high < 0)
623 c = ~c,
624 uu.ll = __negdi2 (uu.ll);
625 if (vv.s.high < 0)
626 c = ~c,
627 vv.ll = __negdi2 (vv.ll);
628
ab495388 629 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
203b91b9
RS
630 if (c)
631 w = __negdi2 (w);
632
633 return w;
634}
635#endif
636
637#ifdef L_moddi3
ab495388
RS
638UDItype __udivmoddi4 ();
639DItype
203b91b9 640__moddi3 (u, v)
ab495388 641 DItype u, v;
203b91b9 642{
ab495388
RS
643 SItype c = 0;
644 DIunion uu, vv;
645 DItype w;
203b91b9
RS
646
647 uu.ll = u;
648 vv.ll = v;
649
650 if (uu.s.high < 0)
651 c = ~c,
652 uu.ll = __negdi2 (uu.ll);
653 if (vv.s.high < 0)
654 vv.ll = __negdi2 (vv.ll);
655
656 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
657 if (c)
658 w = __negdi2 (w);
659
660 return w;
661}
662#endif
663
664#ifdef L_umoddi3
ab495388
RS
665UDItype __udivmoddi4 ();
666UDItype
203b91b9 667__umoddi3 (u, v)
ab495388 668 UDItype u, v;
203b91b9 669{
ab495388 670 DItype w;
203b91b9
RS
671
672 (void) __udivmoddi4 (u, v, &w);
673
674 return w;
675}
676#endif
677
678#ifdef L_udivdi3
ab495388
RS
679UDItype __udivmoddi4 ();
680UDItype
203b91b9 681__udivdi3 (n, d)
ab495388 682 UDItype n, d;
203b91b9 683{
ab495388 684 return __udivmoddi4 (n, d, (UDItype *) 0);
203b91b9
RS
685}
686#endif
687\f
688#ifdef L_cmpdi2
689SItype
690__cmpdi2 (a, b)
ab495388 691 DItype a, b;
203b91b9 692{
ab495388 693 DIunion au, bu;
203b91b9
RS
694
695 au.ll = a, bu.ll = b;
696
697 if (au.s.high < bu.s.high)
698 return 0;
699 else if (au.s.high > bu.s.high)
700 return 2;
ab495388 701 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 702 return 0;
ab495388 703 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
704 return 2;
705 return 1;
706}
707#endif
708
709#ifdef L_ucmpdi2
710SItype
711__ucmpdi2 (a, b)
ab495388 712 DItype a, b;
203b91b9 713{
ab495388 714 DIunion au, bu;
203b91b9
RS
715
716 au.ll = a, bu.ll = b;
717
ab495388 718 if ((USItype) au.s.high < (USItype) bu.s.high)
203b91b9 719 return 0;
ab495388 720 else if ((USItype) au.s.high > (USItype) bu.s.high)
203b91b9 721 return 2;
ab495388 722 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 723 return 0;
ab495388 724 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
725 return 2;
726 return 1;
727}
728#endif
729\f
ab495388
RS
730#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
731#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
732#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
733
734DItype
735__fixunstfdi (a)
736 TFtype a;
737{
738 TFtype b;
739 UDItype v;
740
741 if (a < 0)
742 return 0;
743
744 /* Compute high word of result, as a flonum. */
745 b = (a / HIGH_WORD_COEFF);
746 /* Convert that to fixed (but not to DItype!),
747 and shift it into the high word. */
748 v = (USItype) b;
749 v <<= WORD_SIZE;
750 /* Remove high part from the TFtype, leaving the low part as flonum. */
751 a -= (TFtype)v;
752 /* Convert that to fixed (but not to DItype!) and add it in.
753 Sometimes A comes out negative. This is significant, since
754 A has more bits than a long int does. */
755 if (a < 0)
756 v -= (USItype) (- a);
757 else
758 v += (USItype) a;
759 return v;
760}
761#endif
762
763#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
764DItype
765__fixtfdi (a)
766 TFtype a;
767{
768 if (a < 0)
769 return - __fixunstfdi (-a);
770 return __fixunstfdi (a);
771}
772#endif
773
203b91b9 774#ifdef L_fixunsdfdi
ab495388
RS
775#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
776#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 777
ab495388 778DItype
203b91b9 779__fixunsdfdi (a)
ab495388 780 DFtype a;
203b91b9 781{
ab495388
RS
782 DFtype b;
783 UDItype v;
203b91b9
RS
784
785 if (a < 0)
786 return 0;
787
788 /* Compute high word of result, as a flonum. */
789 b = (a / HIGH_WORD_COEFF);
ab495388 790 /* Convert that to fixed (but not to DItype!),
203b91b9 791 and shift it into the high word. */
ab495388 792 v = (USItype) b;
203b91b9 793 v <<= WORD_SIZE;
ab495388
RS
794 /* Remove high part from the DFtype, leaving the low part as flonum. */
795 a -= (DFtype)v;
796 /* Convert that to fixed (but not to DItype!) and add it in.
203b91b9
RS
797 Sometimes A comes out negative. This is significant, since
798 A has more bits than a long int does. */
799 if (a < 0)
ab495388 800 v -= (USItype) (- a);
203b91b9 801 else
ab495388 802 v += (USItype) a;
203b91b9
RS
803 return v;
804}
805#endif
806
807#ifdef L_fixdfdi
ab495388 808DItype
203b91b9 809__fixdfdi (a)
ab495388 810 DFtype a;
203b91b9
RS
811{
812 if (a < 0)
813 return - __fixunsdfdi (-a);
814 return __fixunsdfdi (a);
815}
816#endif
817
818#ifdef L_fixunssfdi
ab495388
RS
819#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
820#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 821
ab495388
RS
822DItype
823__fixunssfdi (SFtype original_a)
203b91b9 824{
ab495388 825 /* Convert the SFtype to a DFtype, because that is surely not going
203b91b9 826 to lose any bits. Some day someone else can write a faster version
ab495388
RS
827 that avoids converting to DFtype, and verify it really works right. */
828 DFtype a = original_a;
829 DFtype b;
830 UDItype v;
203b91b9
RS
831
832 if (a < 0)
833 return 0;
834
835 /* Compute high word of result, as a flonum. */
836 b = (a / HIGH_WORD_COEFF);
ab495388 837 /* Convert that to fixed (but not to DItype!),
203b91b9 838 and shift it into the high word. */
ab495388 839 v = (USItype) b;
203b91b9 840 v <<= WORD_SIZE;
ab495388
RS
841 /* Remove high part from the DFtype, leaving the low part as flonum. */
842 a -= (DFtype)v;
843 /* Convert that to fixed (but not to DItype!) and add it in.
203b91b9
RS
844 Sometimes A comes out negative. This is significant, since
845 A has more bits than a long int does. */
846 if (a < 0)
ab495388 847 v -= (USItype) (- a);
203b91b9 848 else
ab495388 849 v += (USItype) a;
203b91b9
RS
850 return v;
851}
852#endif
853
854#ifdef L_fixsfdi
ab495388
RS
855DItype
856__fixsfdi (SFtype a)
203b91b9
RS
857{
858 if (a < 0)
859 return - __fixunssfdi (-a);
860 return __fixunssfdi (a);
861}
862#endif
863
ab495388
RS
864#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
865#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
866#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
867#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
868
869TFtype
870__floatditf (u)
871 DItype u;
872{
873 TFtype d;
874 SItype negate = 0;
875
876 if (u < 0)
877 u = -u, negate = 1;
878
879 d = (USItype) (u >> WORD_SIZE);
880 d *= HIGH_HALFWORD_COEFF;
881 d *= HIGH_HALFWORD_COEFF;
882 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
883
884 return (negate ? -d : d);
885}
886#endif
887
203b91b9 888#ifdef L_floatdidf
ab495388
RS
889#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
890#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
891#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 892
ab495388 893DFtype
203b91b9 894__floatdidf (u)
ab495388 895 DItype u;
203b91b9 896{
ab495388
RS
897 DFtype d;
898 SItype negate = 0;
203b91b9
RS
899
900 if (u < 0)
901 u = -u, negate = 1;
902
ab495388 903 d = (USItype) (u >> WORD_SIZE);
203b91b9
RS
904 d *= HIGH_HALFWORD_COEFF;
905 d *= HIGH_HALFWORD_COEFF;
ab495388 906 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9
RS
907
908 return (negate ? -d : d);
909}
910#endif
911
912#ifdef L_floatdisf
ab495388
RS
913#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
914#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
915#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 916
ab495388 917SFtype
203b91b9 918__floatdisf (u)
ab495388 919 DItype u;
203b91b9 920{
ab495388
RS
921 SFtype f;
922 SItype negate = 0;
203b91b9
RS
923
924 if (u < 0)
925 u = -u, negate = 1;
926
ab495388 927 f = (USItype) (u >> WORD_SIZE);
203b91b9
RS
928 f *= HIGH_HALFWORD_COEFF;
929 f *= HIGH_HALFWORD_COEFF;
ab495388 930 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9
RS
931
932 return (negate ? -f : f);
933}
934#endif
935
936#ifdef L_fixunsdfsi
937#include "limits.h"
938
ab495388 939USItype
203b91b9 940__fixunsdfsi (a)
ab495388 941 DFtype a;
203b91b9 942{
ab495388 943 if (a >= - (DFtype) LONG_MIN)
203b91b9
RS
944 return (SItype) (a + LONG_MIN) - LONG_MIN;
945 return (SItype) a;
946}
947#endif
948
949#ifdef L_fixunssfsi
950#include "limits.h"
951
ab495388
RS
952USItype
953__fixunssfsi (SFtype a)
203b91b9 954{
ab495388 955 if (a >= - (SFtype) LONG_MIN)
203b91b9
RS
956 return (SItype) (a + LONG_MIN) - LONG_MIN;
957 return (SItype) a;
958}
959#endif
960\f
ab495388
RS
961/* From here on down, the routines use normal data types. */
962
963#define SItype bogus_type
964#define USItype bogus_type
965#define DItype bogus_type
966#define UDItype bogus_type
967#define SFtype bogus_type
968#define DFtype bogus_type
969
970#undef char
971#undef short
972#undef int
973#undef long
974#undef unsigned
975#undef float
976#undef double
977
203b91b9
RS
978#ifdef L_varargs
979#ifdef __i860__
600032fc 980#if defined(__svr4__) || defined(__alliant__)
203b91b9
RS
981 asm (" .text");
982 asm (" .align 4");
983
27d21d32 984/* The Alliant needs the added underscore. */
203b91b9
RS
985 asm (".globl __builtin_saveregs");
986asm ("__builtin_saveregs:");
27d21d32
RS
987 asm (".globl ___builtin_saveregs");
988asm ("___builtin_saveregs:");
989
990 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
203b91b9
RS
991 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
992 area and also for a new va_list
993 structure */
994 /* Save all argument registers in the arg reg save area. The
995 arg reg save area must have the following layout (according
996 to the svr4 ABI):
997
998 struct {
999 union {
1000 float freg[8];
1001 double dreg[4];
1002 } float_regs;
1003 long ireg[12];
1004 };
1005 */
1006
1007 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1008 asm (" fst.q %f12,16(%sp)");
1009
1010 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1011 asm (" st.l %r17,36(%sp)");
1012 asm (" st.l %r18,40(%sp)");
1013 asm (" st.l %r19,44(%sp)");
1014 asm (" st.l %r20,48(%sp)");
1015 asm (" st.l %r21,52(%sp)");
1016 asm (" st.l %r22,56(%sp)");
1017 asm (" st.l %r23,60(%sp)");
1018 asm (" st.l %r24,64(%sp)");
1019 asm (" st.l %r25,68(%sp)");
1020 asm (" st.l %r26,72(%sp)");
1021 asm (" st.l %r27,76(%sp)");
1022
1023 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1024 va_list structure. Put in into
1025 r16 so that it will be returned
1026 to the caller. */
1027
1028 /* Initialize all fields of the new va_list structure. This
1029 structure looks like:
1030
1031 typedef struct {
1032 unsigned long ireg_used;
1033 unsigned long freg_used;
1034 long *reg_base;
1035 long *mem_ptr;
1036 } va_list;
1037 */
1038
1039 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1040 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1041 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1042 asm (" bri %r1"); /* delayed return */
1043 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1044
600032fc 1045#else /* not __SVR4__ */
203b91b9
RS
1046 asm (" .text");
1047 asm (" .align 4");
1048
1049 asm (".globl ___builtin_saveregs");
1050 asm ("___builtin_saveregs:");
1051 asm (" mov sp,r30");
1052 asm (" andnot 0x0f,sp,sp");
1053 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1054
1055/* Fill in the __va_struct. */
1056 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1057 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1058 asm (" st.l r18, 8(sp)");
1059 asm (" st.l r19,12(sp)");
1060 asm (" st.l r20,16(sp)");
1061 asm (" st.l r21,20(sp)");
1062 asm (" st.l r22,24(sp)");
1063 asm (" st.l r23,28(sp)");
1064 asm (" st.l r24,32(sp)");
1065 asm (" st.l r25,36(sp)");
1066 asm (" st.l r26,40(sp)");
1067 asm (" st.l r27,44(sp)");
1068
1069 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1070 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1071
1072/* Fill in the __va_ctl. */
1073 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1074 asm (" st.l r28,84(sp)"); /* pointer to more args */
1075 asm (" st.l r0, 88(sp)"); /* nfixed */
1076 asm (" st.l r0, 92(sp)"); /* nfloating */
1077
1078 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1079 asm (" bri r1");
1080 asm (" mov r30,sp");
1081 /* recover stack and pass address to start
1082 of data. */
600032fc 1083#endif /* not __SVR4__ */
203b91b9
RS
1084#else /* not __i860__ */
1085#ifdef __sparc__
b335c2cc
TW
1086 asm (".global __builtin_saveregs");
1087 asm ("__builtin_saveregs:");
203b91b9
RS
1088 asm (".global ___builtin_saveregs");
1089 asm ("___builtin_saveregs:");
b1166fae
RS
1090#ifdef NEED_PROC_COMMAND
1091 asm (".proc 020");
b335c2cc 1092#endif
203b91b9
RS
1093 asm ("st %i0,[%fp+68]");
1094 asm ("st %i1,[%fp+72]");
1095 asm ("st %i2,[%fp+76]");
1096 asm ("st %i3,[%fp+80]");
1097 asm ("st %i4,[%fp+84]");
1098 asm ("retl");
1099 asm ("st %i5,[%fp+88]");
b1166fae
RS
1100#ifdef NEED_TYPE_COMMAND
1101 asm (".type __builtin_saveregs,#function");
1102 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1103#endif
203b91b9
RS
1104#else /* not __sparc__ */
1105#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1106
1107 asm (" .text");
1108 asm (" .ent __builtin_saveregs");
1109 asm (" .globl __builtin_saveregs");
1110 asm ("__builtin_saveregs:");
1111 asm (" sw $4,0($30)");
1112 asm (" sw $5,4($30)");
1113 asm (" sw $6,8($30)");
1114 asm (" sw $7,12($30)");
1115 asm (" j $31");
1116 asm (" .end __builtin_saveregs");
1117#else /* not __mips__, etc. */
1118__builtin_saveregs ()
1119{
1120 abort ();
1121}
1122#endif /* not __mips__ */
1123#endif /* not __sparc__ */
1124#endif /* not __i860__ */
1125#endif
1126\f
1127#ifdef L_eprintf
1128#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1129#include <stdio.h>
1130/* This is used by the `assert' macro. */
1131void
1132__eprintf (string, expression, line, filename)
b1166fae
RS
1133 const char *string;
1134 const char *expression;
203b91b9 1135 int line;
b1166fae 1136 const char *filename;
203b91b9
RS
1137{
1138 fprintf (stderr, string, expression, line, filename);
1139 fflush (stderr);
1140 abort ();
1141}
1142#endif
1143
1144#ifdef L_bb
1145/* Avoid warning from ranlib about empty object file. */
1146void
1147__bb_avoid_warning ()
1148{}
1149
1150#if defined (__sun__) && defined (__mc68000__)
1151struct bb
1152{
1153 int initialized;
1154 char *filename;
1155 int *counts;
1156 int ncounts;
1157 int zero_word;
1158 int *addresses;
1159};
1160
1161extern int ___tcov_init;
1162
1163__bb_init_func (blocks)
1164 struct bb *blocks;
1165{
1166 if (! ___tcov_init)
1167 ___tcov_init_func ();
1168
1169 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1170}
1171
1172#endif
1173#endif
1174\f
1175/* frills for C++ */
1176
1177#ifdef L_builtin_new
1178typedef void (*vfp)(void);
1179
1180extern vfp __new_handler;
b6422cca 1181extern void *malloc ();
203b91b9
RS
1182
1183void *
1184__builtin_new (sz)
b6422cca 1185 size_t sz;
203b91b9
RS
1186{
1187 void *p;
1188
b1166fae 1189 p = 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.215682 seconds and 5 git commands to generate.