]> gcc.gnu.org Git - gcc.git/blame - gcc/libgcc2.c
(simplify_set): Move call to make_field_assignment to end; if SRC or DEST is a (clobb...
[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. */
442e881d 3/* Copyright (C) 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
203b91b9
RS
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
d5c88b0a
RK
21/* As a special exception, if you link this library with other files,
22 some of which are compiled with GCC, to produce an executable,
23 this library does not by itself cause the resulting executable
24 to be covered by the GNU General Public License.
203b91b9
RS
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
27
28/* It is incorrect to include config.h here, because this file is being
29 compiled for the target, and hence definitions concerning only the host
30 do not apply. */
31
0dadecf6 32#include "tconfig.h"
bfe655f9 33#include "machmode.h"
b335c2cc 34#ifndef L_trampoline
8717efce 35#include <stddef.h>
b335c2cc 36#endif
203b91b9
RS
37
38/* Don't use `fancy_abort' here even if config.h says to use it. */
39#ifdef abort
40#undef abort
41#endif
42
ab495388
RS
43/* In the first part of this file, we are interfacing to calls generated
44 by the compiler itself. These calls pass values into these routines
45 which have very specific modes (rather than very specific types), and
46 these compiler-generated calls also expect any return values to have
47 very specific modes (rather than very specific types). Thus, we need
48 to avoid using regular C language type names in this part of the file
49 because the sizes for those types can be configured to be anything.
50 Instead we use the following special type names. */
51
b2bf5aef
RK
52typedef unsigned int UQItype __attribute__ ((mode (QI)));
53typedef int SItype __attribute__ ((mode (SI)));
54typedef unsigned int USItype __attribute__ ((mode (SI)));
55typedef int DItype __attribute__ ((mode (DI)));
56typedef unsigned int UDItype __attribute__ ((mode (DI)));
57typedef float SFtype __attribute__ ((mode (SF)));
58typedef float DFtype __attribute__ ((mode (DF)));
e0799b34 59#if LONG_DOUBLE_TYPE_SIZE == 96
b2bf5aef 60typedef float XFtype __attribute__ ((mode (XF)));
258d1356
CH
61#endif
62#if LONG_DOUBLE_TYPE_SIZE == 128
b2bf5aef 63typedef float TFtype __attribute__ ((mode (TF)));
258d1356 64#endif
ab495388 65
4be7c28f 66#if BITS_PER_WORD==16
b2bf5aef 67typedef int word_type __attribute__ ((mode (HI)));
4be7c28f
JW
68#endif
69#if BITS_PER_WORD==32
b2bf5aef 70typedef int word_type __attribute__ ((mode (SI)));
4be7c28f
JW
71#endif
72#if BITS_PER_WORD==64
b2bf5aef 73typedef int word_type __attribute__ ((mode (DI)));
4be7c28f
JW
74#endif
75
a1c37766 76/* Make sure that we don't accidentally use any normal C language built-in
ab495388
RS
77 type names in the first part of this file. Instead we want to use *only*
78 the type names defined above. The following macro definitions insure
19197caa 79 that if we *do* accidentally use some normal C language built-in type name,
ab495388
RS
80 we will get a syntax error. */
81
82#define char bogus_type
83#define short bogus_type
84#define int bogus_type
85#define long bogus_type
86#define unsigned bogus_type
87#define float bogus_type
88#define double bogus_type
89
90#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
91
92/* DIstructs are pairs of SItype values in the order determined by
203b91b9
RS
93 WORDS_BIG_ENDIAN. */
94
95#if WORDS_BIG_ENDIAN
ab495388 96 struct DIstruct {SItype high, low;};
203b91b9 97#else
ab495388 98 struct DIstruct {SItype low, high;};
203b91b9
RS
99#endif
100
ab495388
RS
101/* We need this union to unpack/pack DImode values, since we don't have
102 any arithmetic yet. Incoming DImode parameters are stored into the
103 `ll' field, and the unpacked result is read from the struct `s'. */
203b91b9
RS
104
105typedef union
106{
ab495388
RS
107 struct DIstruct s;
108 DItype ll;
109} DIunion;
203b91b9 110
3904131a 111#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
203b91b9
RS
112
113#include "longlong.h"
114
115#endif /* udiv or mul */
116
ab495388
RS
117extern DItype __fixunssfdi (SFtype a);
118extern DItype __fixunsdfdi (DFtype a);
96fc2623 119#if LONG_DOUBLE_TYPE_SIZE == 96
f70ad14c 120extern DItype __fixunsxfdi (XFtype a);
96fc2623
RS
121#endif
122#if LONG_DOUBLE_TYPE_SIZE == 128
cc3cdac3 123extern DItype __fixunstfdi (TFtype a);
96fc2623 124#endif
203b91b9
RS
125\f
126#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
127#if defined (L_divdi3) || defined (L_moddi3)
128static inline
129#endif
ab495388 130DItype
203b91b9 131__negdi2 (u)
ab495388 132 DItype u;
203b91b9 133{
ab495388
RS
134 DIunion w;
135 DIunion uu;
203b91b9
RS
136
137 uu.ll = u;
138
139 w.s.low = -uu.s.low;
ab495388 140 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
203b91b9
RS
141
142 return w.ll;
143}
144#endif
145\f
146#ifdef L_lshldi3
ab495388 147DItype
203b91b9 148__lshldi3 (u, b)
ab495388
RS
149 DItype u;
150 SItype b;
203b91b9 151{
ab495388
RS
152 DIunion w;
153 SItype bm;
154 DIunion uu;
203b91b9
RS
155
156 if (b == 0)
157 return u;
158
159 uu.ll = u;
160
ab495388 161 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
162 if (bm <= 0)
163 {
164 w.s.low = 0;
ab495388 165 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
166 }
167 else
168 {
ab495388
RS
169 USItype carries = (USItype)uu.s.low >> bm;
170 w.s.low = (USItype)uu.s.low << b;
171 w.s.high = ((USItype)uu.s.high << b) | carries;
203b91b9
RS
172 }
173
174 return w.ll;
175}
176#endif
177
178#ifdef L_lshrdi3
ab495388 179DItype
203b91b9 180__lshrdi3 (u, b)
ab495388
RS
181 DItype u;
182 SItype b;
203b91b9 183{
ab495388
RS
184 DIunion w;
185 SItype bm;
186 DIunion uu;
203b91b9
RS
187
188 if (b == 0)
189 return u;
190
191 uu.ll = u;
192
ab495388 193 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
194 if (bm <= 0)
195 {
196 w.s.high = 0;
ab495388 197 w.s.low = (USItype)uu.s.high >> -bm;
203b91b9
RS
198 }
199 else
200 {
ab495388
RS
201 USItype carries = (USItype)uu.s.high << bm;
202 w.s.high = (USItype)uu.s.high >> b;
203 w.s.low = ((USItype)uu.s.low >> b) | carries;
203b91b9
RS
204 }
205
206 return w.ll;
207}
208#endif
209
210#ifdef L_ashldi3
ab495388 211DItype
203b91b9 212__ashldi3 (u, b)
ab495388
RS
213 DItype u;
214 SItype b;
203b91b9 215{
ab495388
RS
216 DIunion w;
217 SItype bm;
218 DIunion uu;
203b91b9
RS
219
220 if (b == 0)
221 return u;
222
223 uu.ll = u;
224
ab495388 225 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
226 if (bm <= 0)
227 {
228 w.s.low = 0;
ab495388 229 w.s.high = (USItype)uu.s.low << -bm;
203b91b9
RS
230 }
231 else
232 {
ab495388
RS
233 USItype carries = (USItype)uu.s.low >> bm;
234 w.s.low = (USItype)uu.s.low << b;
235 w.s.high = ((USItype)uu.s.high << b) | carries;
203b91b9
RS
236 }
237
238 return w.ll;
239}
240#endif
241
242#ifdef L_ashrdi3
ab495388 243DItype
203b91b9 244__ashrdi3 (u, b)
ab495388
RS
245 DItype u;
246 SItype b;
203b91b9 247{
ab495388
RS
248 DIunion w;
249 SItype bm;
250 DIunion uu;
203b91b9
RS
251
252 if (b == 0)
253 return u;
254
255 uu.ll = u;
256
ab495388 257 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
203b91b9
RS
258 if (bm <= 0)
259 {
260 /* w.s.high = 1..1 or 0..0 */
ab495388 261 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
203b91b9
RS
262 w.s.low = uu.s.high >> -bm;
263 }
264 else
265 {
ab495388 266 USItype carries = (USItype)uu.s.high << bm;
203b91b9 267 w.s.high = uu.s.high >> b;
ab495388 268 w.s.low = ((USItype)uu.s.low >> b) | carries;
203b91b9
RS
269 }
270
271 return w.ll;
272}
273#endif
274\f
aa66bd06
RS
275#ifdef L_ffsdi2
276DItype
277__ffsdi2 (u)
278 DItype u;
279{
280 DIunion uu, w;
281 uu.ll = u;
282 w.s.high = 0;
283 w.s.low = ffs (uu.s.low);
284 if (w.s.low != 0)
de6cbba6 285 return w.ll;
aa66bd06
RS
286 w.s.low = ffs (uu.s.high);
287 if (w.s.low != 0)
288 {
289 w.s.low += BITS_PER_UNIT * sizeof (SItype);
de6cbba6 290 return w.ll;
aa66bd06 291 }
de6cbba6 292 return w.ll;
aa66bd06
RS
293}
294#endif
295\f
203b91b9 296#ifdef L_muldi3
ab495388 297DItype
203b91b9 298__muldi3 (u, v)
ab495388 299 DItype u, v;
203b91b9 300{
ab495388
RS
301 DIunion w;
302 DIunion uu, vv;
203b91b9
RS
303
304 uu.ll = u,
305 vv.ll = v;
306
307 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
ab495388
RS
308 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
309 + (USItype) uu.s.high * (USItype) vv.s.low);
203b91b9
RS
310
311 return w.ll;
312}
313#endif
314\f
3904131a 315#ifdef L_udiv_w_sdiv
431b1ee0 316USItype
3904131a 317__udiv_w_sdiv (rp, a1, a0, d)
431b1ee0
TG
318 USItype *rp, a1, a0, d;
319{
320 USItype q, r;
321 USItype c0, c1, b1;
322
323 if ((SItype) d >= 0)
324 {
7bc7d45a 325 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
431b1ee0
TG
326 {
327 /* dividend, divisor, and quotient are nonnegative */
328 sdiv_qrnnd (q, r, a1, a0, d);
329 }
330 else
331 {
332 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
7bc7d45a 333 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
431b1ee0
TG
334 /* Divide (c1*2^32 + c0) by d */
335 sdiv_qrnnd (q, r, c1, c0, d);
336 /* Add 2^31 to quotient */
7bc7d45a 337 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
431b1ee0
TG
338 }
339 }
340 else
341 {
342 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
343 c1 = a1 >> 1; /* A/2 */
7bc7d45a 344 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
431b1ee0
TG
345
346 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
347 {
348 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
349
350 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
351 if ((d & 1) != 0)
352 {
353 if (r >= q)
354 r = r - q;
355 else if (q - r <= d)
356 {
357 r = r - q + d;
358 q--;
359 }
360 else
361 {
362 r = r - q + 2*d;
363 q -= 2;
364 }
365 }
366 }
367 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
368 {
369 c1 = (b1 - 1) - c1;
370 c0 = ~c0; /* logical NOT */
371
372 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
373
374 q = ~q; /* (A/2)/b1 */
375 r = (b1 - 1) - r;
376
377 r = 2*r + (a0 & 1); /* A/(2*b1) */
378
379 if ((d & 1) != 0)
380 {
381 if (r >= q)
382 r = r - q;
383 else if (q - r <= d)
384 {
385 r = r - q + d;
386 q--;
387 }
388 else
389 {
390 r = r - q + 2*d;
391 q -= 2;
392 }
393 }
394 }
395 else /* Implies c1 = b1 */
396 { /* Hence a1 = d - 1 = 2*b1 - 1 */
397 if (a0 >= -d)
398 {
399 q = -1;
400 r = a0 + d;
401 }
402 else
403 {
404 q = -2;
405 r = a0 + 2*d;
406 }
407 }
408 }
409
410 *rp = r;
411 return q;
412}
413#endif
414\f
203b91b9 415#ifdef L_udivmoddi4
ab495388 416static const UQItype __clz_tab[] =
203b91b9
RS
417{
418 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,
419 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,
420 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,
421 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,
422 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,
423 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,
424 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,
425 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,
426};
427
ab495388 428UDItype
203b91b9 429__udivmoddi4 (n, d, rp)
ab495388
RS
430 UDItype n, d;
431 UDItype *rp;
203b91b9 432{
ab495388
RS
433 DIunion ww;
434 DIunion nn, dd;
435 DIunion rr;
436 USItype d0, d1, n0, n1, n2;
437 USItype q0, q1;
438 USItype b, bm;
203b91b9
RS
439
440 nn.ll = n;
441 dd.ll = d;
442
443 d0 = dd.s.low;
444 d1 = dd.s.high;
445 n0 = nn.s.low;
446 n1 = nn.s.high;
447
448#if !UDIV_NEEDS_NORMALIZATION
449 if (d1 == 0)
450 {
451 if (d0 > n1)
452 {
453 /* 0q = nn / 0D */
454
455 udiv_qrnnd (q0, n0, n1, n0, d0);
456 q1 = 0;
457
458 /* Remainder in n0. */
459 }
460 else
461 {
462 /* qq = NN / 0d */
463
464 if (d0 == 0)
465 d0 = 1 / d0; /* Divide intentionally by zero. */
466
467 udiv_qrnnd (q1, n1, 0, n1, d0);
468 udiv_qrnnd (q0, n0, n1, n0, d0);
469
470 /* Remainder in n0. */
471 }
472
473 if (rp != 0)
474 {
475 rr.s.low = n0;
476 rr.s.high = 0;
477 *rp = rr.ll;
478 }
479 }
480
481#else /* UDIV_NEEDS_NORMALIZATION */
482
483 if (d1 == 0)
484 {
485 if (d0 > n1)
486 {
487 /* 0q = nn / 0D */
488
489 count_leading_zeros (bm, d0);
490
491 if (bm != 0)
492 {
493 /* Normalize, i.e. make the most significant bit of the
494 denominator set. */
495
496 d0 = d0 << bm;
ab495388 497 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
203b91b9
RS
498 n0 = n0 << bm;
499 }
500
501 udiv_qrnnd (q0, n0, n1, n0, d0);
502 q1 = 0;
503
504 /* Remainder in n0 >> bm. */
505 }
506 else
507 {
508 /* qq = NN / 0d */
509
510 if (d0 == 0)
511 d0 = 1 / d0; /* Divide intentionally by zero. */
512
513 count_leading_zeros (bm, d0);
514
515 if (bm == 0)
516 {
517 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
518 conclude (the most significant bit of n1 is set) /\ (the
519 leading quotient digit q1 = 1).
520
521 This special case is necessary, not an optimization.
ab495388 522 (Shifts counts of SI_TYPE_SIZE are undefined.) */
203b91b9
RS
523
524 n1 -= d0;
525 q1 = 1;
526 }
527 else
528 {
529 /* Normalize. */
530
ab495388 531 b = SI_TYPE_SIZE - bm;
203b91b9
RS
532
533 d0 = d0 << bm;
534 n2 = n1 >> b;
535 n1 = (n1 << bm) | (n0 >> b);
536 n0 = n0 << bm;
537
538 udiv_qrnnd (q1, n1, n2, n1, d0);
539 }
540
541 /* n1 != d0... */
542
543 udiv_qrnnd (q0, n0, n1, n0, d0);
544
545 /* Remainder in n0 >> bm. */
546 }
547
548 if (rp != 0)
549 {
550 rr.s.low = n0 >> bm;
551 rr.s.high = 0;
552 *rp = rr.ll;
553 }
554 }
555#endif /* UDIV_NEEDS_NORMALIZATION */
556
557 else
558 {
559 if (d1 > n1)
560 {
561 /* 00 = nn / DD */
562
563 q0 = 0;
564 q1 = 0;
565
566 /* Remainder in n1n0. */
567 if (rp != 0)
568 {
569 rr.s.low = n0;
570 rr.s.high = n1;
571 *rp = rr.ll;
572 }
573 }
574 else
575 {
576 /* 0q = NN / dd */
577
578 count_leading_zeros (bm, d1);
579 if (bm == 0)
580 {
581 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
582 conclude (the most significant bit of n1 is set) /\ (the
583 quotient digit q0 = 0 or 1).
584
585 This special case is necessary, not an optimization. */
586
587 /* The condition on the next line takes advantage of that
588 n1 >= d1 (true due to program flow). */
589 if (n1 > d1 || n0 >= d0)
590 {
591 q0 = 1;
592 sub_ddmmss (n1, n0, n1, n0, d1, d0);
593 }
594 else
595 q0 = 0;
596
597 q1 = 0;
598
599 if (rp != 0)
600 {
601 rr.s.low = n0;
602 rr.s.high = n1;
603 *rp = rr.ll;
604 }
605 }
606 else
607 {
ab495388 608 USItype m1, m0;
203b91b9
RS
609 /* Normalize. */
610
ab495388 611 b = SI_TYPE_SIZE - bm;
203b91b9
RS
612
613 d1 = (d1 << bm) | (d0 >> b);
614 d0 = d0 << bm;
615 n2 = n1 >> b;
616 n1 = (n1 << bm) | (n0 >> b);
617 n0 = n0 << bm;
618
619 udiv_qrnnd (q0, n1, n2, n1, d1);
620 umul_ppmm (m1, m0, q0, d0);
621
622 if (m1 > n1 || (m1 == n1 && m0 > n0))
623 {
624 q0--;
625 sub_ddmmss (m1, m0, m1, m0, d1, d0);
626 }
627
628 q1 = 0;
629
630 /* Remainder in (n1n0 - m1m0) >> bm. */
631 if (rp != 0)
632 {
633 sub_ddmmss (n1, n0, n1, n0, m1, m0);
634 rr.s.low = (n1 << b) | (n0 >> bm);
635 rr.s.high = n1 >> bm;
636 *rp = rr.ll;
637 }
638 }
639 }
640 }
641
642 ww.s.low = q0;
643 ww.s.high = q1;
644 return ww.ll;
645}
646#endif
647
648#ifdef L_divdi3
ab495388 649UDItype __udivmoddi4 ();
f70ad14c 650
ab495388 651DItype
203b91b9 652__divdi3 (u, v)
ab495388 653 DItype u, v;
203b91b9 654{
ab495388
RS
655 SItype c = 0;
656 DIunion uu, vv;
657 DItype w;
203b91b9
RS
658
659 uu.ll = u;
660 vv.ll = v;
661
662 if (uu.s.high < 0)
663 c = ~c,
664 uu.ll = __negdi2 (uu.ll);
665 if (vv.s.high < 0)
666 c = ~c,
667 vv.ll = __negdi2 (vv.ll);
668
ab495388 669 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
203b91b9
RS
670 if (c)
671 w = __negdi2 (w);
672
673 return w;
674}
675#endif
676
677#ifdef L_moddi3
ab495388
RS
678UDItype __udivmoddi4 ();
679DItype
203b91b9 680__moddi3 (u, v)
ab495388 681 DItype u, v;
203b91b9 682{
ab495388
RS
683 SItype c = 0;
684 DIunion uu, vv;
685 DItype w;
203b91b9
RS
686
687 uu.ll = u;
688 vv.ll = v;
689
690 if (uu.s.high < 0)
691 c = ~c,
692 uu.ll = __negdi2 (uu.ll);
693 if (vv.s.high < 0)
694 vv.ll = __negdi2 (vv.ll);
695
696 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
697 if (c)
698 w = __negdi2 (w);
699
700 return w;
701}
702#endif
703
704#ifdef L_umoddi3
ab495388
RS
705UDItype __udivmoddi4 ();
706UDItype
203b91b9 707__umoddi3 (u, v)
ab495388 708 UDItype u, v;
203b91b9 709{
ab495388 710 DItype w;
203b91b9
RS
711
712 (void) __udivmoddi4 (u, v, &w);
713
714 return w;
715}
716#endif
717
718#ifdef L_udivdi3
ab495388
RS
719UDItype __udivmoddi4 ();
720UDItype
203b91b9 721__udivdi3 (n, d)
ab495388 722 UDItype n, d;
203b91b9 723{
ab495388 724 return __udivmoddi4 (n, d, (UDItype *) 0);
203b91b9
RS
725}
726#endif
727\f
728#ifdef L_cmpdi2
4be7c28f 729word_type
203b91b9 730__cmpdi2 (a, b)
ab495388 731 DItype a, b;
203b91b9 732{
ab495388 733 DIunion au, bu;
203b91b9
RS
734
735 au.ll = a, bu.ll = b;
736
737 if (au.s.high < bu.s.high)
738 return 0;
739 else if (au.s.high > bu.s.high)
740 return 2;
ab495388 741 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 742 return 0;
ab495388 743 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
744 return 2;
745 return 1;
746}
747#endif
748
749#ifdef L_ucmpdi2
4be7c28f 750word_type
203b91b9 751__ucmpdi2 (a, b)
ab495388 752 DItype a, b;
203b91b9 753{
ab495388 754 DIunion au, bu;
203b91b9
RS
755
756 au.ll = a, bu.ll = b;
757
ab495388 758 if ((USItype) au.s.high < (USItype) bu.s.high)
203b91b9 759 return 0;
ab495388 760 else if ((USItype) au.s.high > (USItype) bu.s.high)
203b91b9 761 return 2;
ab495388 762 if ((USItype) au.s.low < (USItype) bu.s.low)
203b91b9 763 return 0;
ab495388 764 else if ((USItype) au.s.low > (USItype) bu.s.low)
203b91b9
RS
765 return 2;
766 return 1;
767}
768#endif
769\f
ab495388
RS
770#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
771#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
772#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
773
774DItype
775__fixunstfdi (a)
776 TFtype a;
777{
778 TFtype b;
779 UDItype v;
780
781 if (a < 0)
782 return 0;
783
784 /* Compute high word of result, as a flonum. */
785 b = (a / HIGH_WORD_COEFF);
786 /* Convert that to fixed (but not to DItype!),
787 and shift it into the high word. */
788 v = (USItype) b;
789 v <<= WORD_SIZE;
790 /* Remove high part from the TFtype, leaving the low part as flonum. */
791 a -= (TFtype)v;
792 /* Convert that to fixed (but not to DItype!) and add it in.
793 Sometimes A comes out negative. This is significant, since
794 A has more bits than a long int does. */
795 if (a < 0)
796 v -= (USItype) (- a);
797 else
798 v += (USItype) a;
799 return v;
800}
801#endif
802
803#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
804DItype
805__fixtfdi (a)
806 TFtype a;
807{
808 if (a < 0)
809 return - __fixunstfdi (-a);
810 return __fixunstfdi (a);
811}
812#endif
813
e0799b34
RS
814#if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
815#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
816#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
817
818DItype
819__fixunsxfdi (a)
820 XFtype a;
821{
822 XFtype b;
823 UDItype v;
824
825 if (a < 0)
826 return 0;
827
828 /* Compute high word of result, as a flonum. */
829 b = (a / HIGH_WORD_COEFF);
830 /* Convert that to fixed (but not to DItype!),
831 and shift it into the high word. */
832 v = (USItype) b;
833 v <<= WORD_SIZE;
834 /* Remove high part from the XFtype, leaving the low part as flonum. */
835 a -= (XFtype)v;
836 /* Convert that to fixed (but not to DItype!) and add it in.
837 Sometimes A comes out negative. This is significant, since
838 A has more bits than a long int does. */
839 if (a < 0)
840 v -= (USItype) (- a);
841 else
842 v += (USItype) a;
843 return v;
844}
845#endif
846
847#if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
848DItype
849__fixxfdi (a)
850 XFtype a;
851{
852 if (a < 0)
853 return - __fixunsxfdi (-a);
854 return __fixunsxfdi (a);
855}
856#endif
857
203b91b9 858#ifdef L_fixunsdfdi
ab495388
RS
859#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
860#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 861
ab495388 862DItype
203b91b9 863__fixunsdfdi (a)
ab495388 864 DFtype a;
203b91b9 865{
ab495388
RS
866 DFtype b;
867 UDItype v;
203b91b9
RS
868
869 if (a < 0)
870 return 0;
871
872 /* Compute high word of result, as a flonum. */
873 b = (a / HIGH_WORD_COEFF);
ab495388 874 /* Convert that to fixed (but not to DItype!),
203b91b9 875 and shift it into the high word. */
ab495388 876 v = (USItype) b;
203b91b9 877 v <<= WORD_SIZE;
ab495388
RS
878 /* Remove high part from the DFtype, leaving the low part as flonum. */
879 a -= (DFtype)v;
880 /* Convert that to fixed (but not to DItype!) and add it in.
203b91b9
RS
881 Sometimes A comes out negative. This is significant, since
882 A has more bits than a long int does. */
883 if (a < 0)
ab495388 884 v -= (USItype) (- a);
203b91b9 885 else
ab495388 886 v += (USItype) a;
203b91b9
RS
887 return v;
888}
889#endif
890
891#ifdef L_fixdfdi
ab495388 892DItype
203b91b9 893__fixdfdi (a)
ab495388 894 DFtype a;
203b91b9
RS
895{
896 if (a < 0)
897 return - __fixunsdfdi (-a);
898 return __fixunsdfdi (a);
899}
900#endif
901
902#ifdef L_fixunssfdi
ab495388
RS
903#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
904#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 905
ab495388
RS
906DItype
907__fixunssfdi (SFtype original_a)
203b91b9 908{
ab495388 909 /* Convert the SFtype to a DFtype, because that is surely not going
203b91b9 910 to lose any bits. Some day someone else can write a faster version
ab495388
RS
911 that avoids converting to DFtype, and verify it really works right. */
912 DFtype a = original_a;
913 DFtype b;
914 UDItype v;
203b91b9
RS
915
916 if (a < 0)
917 return 0;
918
919 /* Compute high word of result, as a flonum. */
920 b = (a / HIGH_WORD_COEFF);
ab495388 921 /* Convert that to fixed (but not to DItype!),
203b91b9 922 and shift it into the high word. */
ab495388 923 v = (USItype) b;
203b91b9 924 v <<= WORD_SIZE;
ab495388
RS
925 /* Remove high part from the DFtype, leaving the low part as flonum. */
926 a -= (DFtype)v;
927 /* Convert that to fixed (but not to DItype!) and add it in.
203b91b9
RS
928 Sometimes A comes out negative. This is significant, since
929 A has more bits than a long int does. */
930 if (a < 0)
ab495388 931 v -= (USItype) (- a);
203b91b9 932 else
ab495388 933 v += (USItype) a;
203b91b9
RS
934 return v;
935}
936#endif
937
938#ifdef L_fixsfdi
ab495388
RS
939DItype
940__fixsfdi (SFtype a)
203b91b9
RS
941{
942 if (a < 0)
943 return - __fixunssfdi (-a);
944 return __fixunssfdi (a);
945}
946#endif
947
e0799b34
RS
948#if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
949#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
950#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
951#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
952
953XFtype
954__floatdixf (u)
955 DItype u;
956{
957 XFtype d;
958 SItype negate = 0;
959
960 if (u < 0)
961 u = -u, negate = 1;
962
963 d = (USItype) (u >> WORD_SIZE);
964 d *= HIGH_HALFWORD_COEFF;
965 d *= HIGH_HALFWORD_COEFF;
966 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
967
968 return (negate ? -d : d);
969}
970#endif
971
ab495388
RS
972#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
973#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
974#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
975#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
976
977TFtype
978__floatditf (u)
979 DItype u;
980{
981 TFtype d;
982 SItype negate = 0;
983
984 if (u < 0)
985 u = -u, negate = 1;
986
987 d = (USItype) (u >> WORD_SIZE);
988 d *= HIGH_HALFWORD_COEFF;
989 d *= HIGH_HALFWORD_COEFF;
990 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
991
992 return (negate ? -d : d);
993}
994#endif
995
203b91b9 996#ifdef L_floatdidf
ab495388
RS
997#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
998#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
999#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 1000
ab495388 1001DFtype
203b91b9 1002__floatdidf (u)
ab495388 1003 DItype u;
203b91b9 1004{
ab495388
RS
1005 DFtype d;
1006 SItype negate = 0;
203b91b9
RS
1007
1008 if (u < 0)
1009 u = -u, negate = 1;
1010
ab495388 1011 d = (USItype) (u >> WORD_SIZE);
203b91b9
RS
1012 d *= HIGH_HALFWORD_COEFF;
1013 d *= HIGH_HALFWORD_COEFF;
ab495388 1014 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9
RS
1015
1016 return (negate ? -d : d);
1017}
1018#endif
1019
1020#ifdef L_floatdisf
ab495388
RS
1021#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1022#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1023#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
203b91b9 1024
ab495388 1025SFtype
203b91b9 1026__floatdisf (u)
ab495388 1027 DItype u;
203b91b9 1028{
56b03d5f
RS
1029 /* Do the calculation in DFmode
1030 so that we don't lose any of the precision of the high word
1031 while multiplying it. */
1032 DFtype f;
ab495388 1033 SItype negate = 0;
203b91b9
RS
1034
1035 if (u < 0)
1036 u = -u, negate = 1;
1037
ab495388 1038 f = (USItype) (u >> WORD_SIZE);
203b91b9
RS
1039 f *= HIGH_HALFWORD_COEFF;
1040 f *= HIGH_HALFWORD_COEFF;
ab495388 1041 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
203b91b9 1042
56b03d5f 1043 return (SFtype) (negate ? -f : f);
203b91b9
RS
1044}
1045#endif
1046
e0799b34
RS
1047#if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1048#include "glimits.h"
1049
1050USItype
1051__fixunsxfsi (a)
1052 XFtype a;
1053{
1054 if (a >= - (DFtype) LONG_MIN)
1055 return (SItype) (a + LONG_MIN) - LONG_MIN;
1056 return (SItype) a;
1057}
1058#endif
1059
203b91b9 1060#ifdef L_fixunsdfsi
0c7b7f30 1061#include "glimits.h"
203b91b9 1062
ab495388 1063USItype
203b91b9 1064__fixunsdfsi (a)
ab495388 1065 DFtype a;
203b91b9 1066{
ab495388 1067 if (a >= - (DFtype) LONG_MIN)
203b91b9
RS
1068 return (SItype) (a + LONG_MIN) - LONG_MIN;
1069 return (SItype) a;
1070}
1071#endif
1072
1073#ifdef L_fixunssfsi
0c7b7f30 1074#include "glimits.h"
203b91b9 1075
ab495388
RS
1076USItype
1077__fixunssfsi (SFtype a)
203b91b9 1078{
ab495388 1079 if (a >= - (SFtype) LONG_MIN)
203b91b9
RS
1080 return (SItype) (a + LONG_MIN) - LONG_MIN;
1081 return (SItype) a;
1082}
1083#endif
1084\f
ab495388
RS
1085/* From here on down, the routines use normal data types. */
1086
1087#define SItype bogus_type
1088#define USItype bogus_type
1089#define DItype bogus_type
1090#define UDItype bogus_type
1091#define SFtype bogus_type
1092#define DFtype bogus_type
1093
1094#undef char
1095#undef short
1096#undef int
1097#undef long
1098#undef unsigned
1099#undef float
1100#undef double
9bd23d2c
RS
1101\f
1102#ifdef L__gcc_bcmp
1103
1104/* Like bcmp except the sign is meaningful.
1105 Reult is negative if S1 is less than S2,
1106 positive if S1 is greater, 0 if S1 and S2 are equal. */
1107
1108int
1109__gcc_bcmp (s1, s2, size)
78e33213 1110 unsigned char *s1, *s2;
9bd23d2c
RS
1111 size_t size;
1112{
1113 while (size > 0)
1114 {
78e33213 1115 unsigned char c1 = *s1++, c2 = *s2++;
9bd23d2c
RS
1116 if (c1 != c2)
1117 return c1 - c2;
1118 size--;
1119 }
1120 return 0;
1121}
ab495388 1122
9bd23d2c
RS
1123#endif
1124\f\f
203b91b9
RS
1125#ifdef L_varargs
1126#ifdef __i860__
600032fc 1127#if defined(__svr4__) || defined(__alliant__)
203b91b9
RS
1128 asm (" .text");
1129 asm (" .align 4");
1130
27d21d32 1131/* The Alliant needs the added underscore. */
203b91b9
RS
1132 asm (".globl __builtin_saveregs");
1133asm ("__builtin_saveregs:");
27d21d32
RS
1134 asm (".globl ___builtin_saveregs");
1135asm ("___builtin_saveregs:");
1136
1137 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
203b91b9
RS
1138 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1139 area and also for a new va_list
1140 structure */
1141 /* Save all argument registers in the arg reg save area. The
1142 arg reg save area must have the following layout (according
1143 to the svr4 ABI):
1144
1145 struct {
1146 union {
1147 float freg[8];
1148 double dreg[4];
1149 } float_regs;
1150 long ireg[12];
1151 };
1152 */
1153
1154 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1155 asm (" fst.q %f12,16(%sp)");
1156
1157 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1158 asm (" st.l %r17,36(%sp)");
1159 asm (" st.l %r18,40(%sp)");
1160 asm (" st.l %r19,44(%sp)");
1161 asm (" st.l %r20,48(%sp)");
1162 asm (" st.l %r21,52(%sp)");
1163 asm (" st.l %r22,56(%sp)");
1164 asm (" st.l %r23,60(%sp)");
1165 asm (" st.l %r24,64(%sp)");
1166 asm (" st.l %r25,68(%sp)");
1167 asm (" st.l %r26,72(%sp)");
1168 asm (" st.l %r27,76(%sp)");
1169
1170 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1171 va_list structure. Put in into
1172 r16 so that it will be returned
1173 to the caller. */
1174
1175 /* Initialize all fields of the new va_list structure. This
1176 structure looks like:
1177
1178 typedef struct {
1179 unsigned long ireg_used;
1180 unsigned long freg_used;
1181 long *reg_base;
1182 long *mem_ptr;
1183 } va_list;
1184 */
1185
1186 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1187 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1188 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1189 asm (" bri %r1"); /* delayed return */
1190 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1191
24e4939e 1192#else /* not __svr4__ */
6aadf9c2
RS
1193#if defined(__PARAGON__)
1194 /*
1195 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1196 * and we stand a better chance of hooking into libraries
1197 * compiled by PGI. [andyp@ssd.intel.com]
1198 */
1199 asm (" .text");
1200 asm (" .align 4");
1201 asm (".globl __builtin_saveregs");
1202asm ("__builtin_saveregs:");
1203 asm (".globl ___builtin_saveregs");
1204asm ("___builtin_saveregs:");
1205
1206 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1207 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1208 area and also for a new va_list
1209 structure */
1210 /* Save all argument registers in the arg reg save area. The
1211 arg reg save area must have the following layout (according
1212 to the svr4 ABI):
1213
1214 struct {
1215 union {
1216 float freg[8];
1217 double dreg[4];
1218 } float_regs;
1219 long ireg[12];
1220 };
1221 */
1222
1223 asm (" fst.q f8, 0(sp)");
1224 asm (" fst.q f12,16(sp)");
1225 asm (" st.l r16,32(sp)");
1226 asm (" st.l r17,36(sp)");
1227 asm (" st.l r18,40(sp)");
1228 asm (" st.l r19,44(sp)");
1229 asm (" st.l r20,48(sp)");
1230 asm (" st.l r21,52(sp)");
1231 asm (" st.l r22,56(sp)");
1232 asm (" st.l r23,60(sp)");
1233 asm (" st.l r24,64(sp)");
1234 asm (" st.l r25,68(sp)");
1235 asm (" st.l r26,72(sp)");
1236 asm (" st.l r27,76(sp)");
1237
1238 asm (" adds 80,sp,r16"); /* compute the address of the new
1239 va_list structure. Put in into
1240 r16 so that it will be returned
1241 to the caller. */
1242
1243 /* Initialize all fields of the new va_list structure. This
1244 structure looks like:
1245
1246 typedef struct {
1247 unsigned long ireg_used;
1248 unsigned long freg_used;
1249 long *reg_base;
1250 long *mem_ptr;
1251 } va_list;
1252 */
1253
1254 asm (" st.l r0, 0(r16)"); /* nfixed */
1255 asm (" st.l r0, 4(r16)"); /* nfloating */
1256 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1257 asm (" bri r1"); /* delayed return */
1258 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1259#else /* not __PARAGON__ */
203b91b9
RS
1260 asm (" .text");
1261 asm (" .align 4");
1262
1263 asm (".globl ___builtin_saveregs");
1264 asm ("___builtin_saveregs:");
1265 asm (" mov sp,r30");
1266 asm (" andnot 0x0f,sp,sp");
1267 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1268
1269/* Fill in the __va_struct. */
1270 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1271 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1272 asm (" st.l r18, 8(sp)");
1273 asm (" st.l r19,12(sp)");
1274 asm (" st.l r20,16(sp)");
1275 asm (" st.l r21,20(sp)");
1276 asm (" st.l r22,24(sp)");
1277 asm (" st.l r23,28(sp)");
1278 asm (" st.l r24,32(sp)");
1279 asm (" st.l r25,36(sp)");
1280 asm (" st.l r26,40(sp)");
1281 asm (" st.l r27,44(sp)");
1282
1283 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1284 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1285
1286/* Fill in the __va_ctl. */
1287 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1288 asm (" st.l r28,84(sp)"); /* pointer to more args */
1289 asm (" st.l r0, 88(sp)"); /* nfixed */
1290 asm (" st.l r0, 92(sp)"); /* nfloating */
1291
1292 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1293 asm (" bri r1");
1294 asm (" mov r30,sp");
1295 /* recover stack and pass address to start
1296 of data. */
6aadf9c2 1297#endif /* not __PARAGON__ */
24e4939e 1298#endif /* not __svr4__ */
203b91b9
RS
1299#else /* not __i860__ */
1300#ifdef __sparc__
b335c2cc
TW
1301 asm (".global __builtin_saveregs");
1302 asm ("__builtin_saveregs:");
203b91b9
RS
1303 asm (".global ___builtin_saveregs");
1304 asm ("___builtin_saveregs:");
b1166fae
RS
1305#ifdef NEED_PROC_COMMAND
1306 asm (".proc 020");
b335c2cc 1307#endif
203b91b9
RS
1308 asm ("st %i0,[%fp+68]");
1309 asm ("st %i1,[%fp+72]");
1310 asm ("st %i2,[%fp+76]");
1311 asm ("st %i3,[%fp+80]");
1312 asm ("st %i4,[%fp+84]");
1313 asm ("retl");
1314 asm ("st %i5,[%fp+88]");
b1166fae
RS
1315#ifdef NEED_TYPE_COMMAND
1316 asm (".type __builtin_saveregs,#function");
1317 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1318#endif
203b91b9
RS
1319#else /* not __sparc__ */
1320#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1321
1322 asm (" .text");
1323 asm (" .ent __builtin_saveregs");
1324 asm (" .globl __builtin_saveregs");
1325 asm ("__builtin_saveregs:");
1326 asm (" sw $4,0($30)");
1327 asm (" sw $5,4($30)");
1328 asm (" sw $6,8($30)");
1329 asm (" sw $7,12($30)");
1330 asm (" j $31");
1331 asm (" .end __builtin_saveregs");
1332#else /* not __mips__, etc. */
3bd4f3b8
DE
1333
1334void *
203b91b9
RS
1335__builtin_saveregs ()
1336{
1337 abort ();
1338}
3bd4f3b8 1339
203b91b9
RS
1340#endif /* not __mips__ */
1341#endif /* not __sparc__ */
1342#endif /* not __i860__ */
1343#endif
1344\f
1345#ifdef L_eprintf
c74d5583 1346#ifndef inhibit_libc
bba2431c 1347
203b91b9
RS
1348#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1349#include <stdio.h>
1350/* This is used by the `assert' macro. */
1351void
1352__eprintf (string, expression, line, filename)
b1166fae
RS
1353 const char *string;
1354 const char *expression;
203b91b9 1355 int line;
b1166fae 1356 const char *filename;
203b91b9
RS
1357{
1358 fprintf (stderr, string, expression, line, filename);
1359 fflush (stderr);
1360 abort ();
1361}
bba2431c
RS
1362
1363#endif
203b91b9
RS
1364#endif
1365
1366#ifdef L_bb
203b91b9 1367
92832bb5 1368/* Structure emitted by -a */
203b91b9
RS
1369struct bb
1370{
92832bb5
MM
1371 long zero_word;
1372 const char *filename;
1373 long *counts;
1374 long ncounts;
1375 struct bb *next;
1376 const unsigned long *addresses;
1377
1378 /* Older GCC's did not emit these fields. */
1379 long nwords;
1380 const char **functions;
1381 const long *line_nums;
1382 const char **filenames;
203b91b9
RS
1383};
1384
92832bb5
MM
1385#ifdef BLOCK_PROFILER_CODE
1386BLOCK_PROFILER_CODE
1387#else
c7544ff7 1388#ifndef inhibit_libc
92832bb5
MM
1389
1390/* Simple minded basic block profiling output dumper for
1391 systems that don't provde tcov support. At present,
1392 it requires atexit and stdio. */
1393
ebd41309 1394#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
92832bb5 1395#include <stdio.h>
203b91b9 1396
92832bb5
MM
1397#ifdef HAVE_ATEXIT
1398extern void atexit (void (*) (void));
1399#define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1400#else
1401#ifdef sun
1402extern void on_exit (void*, void*);
1403#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1404#endif
1405#endif
1406
1407static struct bb *bb_head = (struct bb *)0;
1408
1409/* Return the number of digits needed to print a value */
1410/* __inline__ */ static int num_digits (long value, int base)
203b91b9 1411{
92832bb5
MM
1412 int minus = (value < 0 && base != 16);
1413 unsigned long v = (minus) ? -value : value;
1414 int ret = minus;
203b91b9 1415
92832bb5
MM
1416 do
1417 {
1418 v /= base;
1419 ret++;
1420 }
1421 while (v);
1422
1423 return ret;
203b91b9
RS
1424}
1425
92832bb5
MM
1426void
1427__bb_exit_func (void)
1428{
1429 FILE *file = fopen ("bb.out", "a");
1430 long time_value;
1431
1432 if (!file)
1433 perror ("bb.out");
1434
1435 else
1436 {
1437 struct bb *ptr;
1438
1439 /* This is somewhat type incorrect, but it avoids worrying about
1440 exactly where time.h is included from. It should be ok unless
1441 a void * differs from other pointer formats, or if sizeof(long)
1442 is < sizeof (time_t). It would be nice if we could assume the
1443 use of rationale standards here. */
1444
1445 time((void *) &time_value);
1446 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1447
1448 /* We check the length field explicitly in order to allow compatibility
1449 with older GCC's which did not provide it. */
1450
1451 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1452 {
1453 int i;
1454 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1455 int line_p = (func_p && ptr->line_nums);
1456 int file_p = (func_p && ptr->filenames);
1457 long ncounts = ptr->ncounts;
1458 long cnt_max = 0;
1459 long line_max = 0;
1460 long addr_max = 0;
1461 int file_len = 0;
1462 int func_len = 0;
1463 int blk_len = num_digits (ncounts, 10);
1464 int cnt_len;
1465 int line_len;
1466 int addr_len;
1467
1468 fprintf (file, "File %s, %ld basic blocks \n\n",
1469 ptr->filename, ncounts);
1470
1471 /* Get max values for each field. */
1472 for (i = 0; i < ncounts; i++)
1473 {
1474 const char *p;
1475 int len;
1476
1477 if (cnt_max < ptr->counts[i])
1478 cnt_max = ptr->counts[i];
1479
1480 if (addr_max < ptr->addresses[i])
1481 addr_max = ptr->addresses[i];
1482
1483 if (line_p && line_max < ptr->line_nums[i])
1484 line_max = ptr->line_nums[i];
1485
1486 if (func_p)
1487 {
1488 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1489 len = strlen (p);
1490 if (func_len < len)
1491 func_len = len;
1492 }
1493
1494 if (file_p)
1495 {
1496 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1497 len = strlen (p);
1498 if (file_len < len)
1499 file_len = len;
1500 }
1501 }
1502
1503 addr_len = num_digits (addr_max, 16);
1504 cnt_len = num_digits (cnt_max, 10);
1505 line_len = num_digits (line_max, 10);
1506
1507 /* Now print out the basic block information. */
1508 for (i = 0; i < ncounts; i++)
1509 {
1510 fprintf (file,
3cca99e8 1511 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
92832bb5
MM
1512 blk_len, i+1,
1513 cnt_len, ptr->counts[i],
1514 addr_len, ptr->addresses[i]);
1515
1516 if (func_p)
3cca99e8 1517 fprintf (file, " function= %-*s", func_len,
92832bb5
MM
1518 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1519
1520 if (line_p)
1d42e1b7 1521 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
92832bb5
MM
1522
1523 if (file_p)
3cca99e8 1524 fprintf (file, " file= %s",
92832bb5
MM
1525 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1526
1527 fprintf (file, "\n");
1528 }
1529
1530 fprintf (file, "\n");
1531 fflush (file);
1532 }
1533
1534 fprintf (file, "\n\n");
1535 fclose (file);
1536 }
1537}
1538
1539void
1540__bb_init_func (struct bb *blocks)
1541{
1542 /* User is supposed to check whether the first word is non-0,
1543 but just in case.... */
1544
1545 if (blocks->zero_word)
1546 return;
1547
1548#ifdef ON_EXIT
1549 /* Initialize destructor. */
1550 if (!bb_head)
1551 ON_EXIT (__bb_exit_func, 0);
203b91b9 1552#endif
92832bb5
MM
1553
1554 /* Set up linked list. */
1555 blocks->zero_word = 1;
1556 blocks->next = bb_head;
1557 bb_head = blocks;
1558}
1559
c7544ff7
RS
1560#endif /* not inhibit_libc */
1561#endif /* not BLOCK_PROFILER_CODE */
1562#endif /* L_bb */
203b91b9 1563\f
6ffe3a32
JM
1564/* Default free-store management functions for C++, per sections 12.5 and
1565 17.3.3 of the Working Paper. */
203b91b9 1566
ec06f00a 1567#ifdef L_op_new
6ffe3a32
JM
1568/* operator new (size_t), described in 17.3.3.5. This function is used by
1569 C++ programs to allocate a block of memory to hold a single object. */
203b91b9 1570
6ffe3a32 1571typedef void (*vfp)(void);
203b91b9
RS
1572extern vfp __new_handler;
1573
1574void *
ec06f00a 1575__builtin_new (size_t sz)
203b91b9
RS
1576{
1577 void *p;
1578
bcea2185
RS
1579 /* malloc (0) is unpredictable; avoid it. */
1580 if (sz == 0)
1581 sz = 1;
ecbe06a1 1582 p = (void *) malloc (sz);
442e881d
RK
1583 while (p == 0)
1584 {
1585 (*__new_handler) ();
1586 p = (void *) malloc (sz);
1587 }
1588
203b91b9
RS
1589 return p;
1590}
ec06f00a 1591#endif /* L_op_new */
203b91b9 1592
4c548483 1593#ifdef L_op_vnew
6ffe3a32
JM
1594/* void * operator new [] (size_t), described in 17.3.3.6. This function
1595 is used by C++ programs to allocate a block of memory for an array. */
1596
1597extern void * __builtin_new (size_t);
1598
1599void *
1600__builtin_vec_new (size_t sz)
1601{
1602 return __builtin_new (sz);
1603}
4c548483 1604#endif /* L_op_vnew */
6ffe3a32 1605
ec06f00a 1606#ifdef L_new_handler
6ffe3a32
JM
1607/* set_new_handler (fvoid_t *) and the default new handler, described in
1608 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1609 to allocate the amount of memory requested from operator new or new []. */
fffa6914 1610
c74d5583 1611#ifndef inhibit_libc
fffa6914 1612/* This gets us __GNU_LIBRARY__. */
98126ed6 1613#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
fffa6914
RS
1614#include <stdio.h>
1615
1616#ifdef __GNU_LIBRARY__
1617 /* Avoid forcing the library's meaning of `write' on the user program
e45d9b98 1618 by using the "internal" name (for use within the library) */
fffa6914
RS
1619#define write(fd, buf, n) __write((fd), (buf), (n))
1620#endif
c74d5583 1621#endif /* inhibit_libc */
fffa6914 1622
203b91b9 1623typedef void (*vfp)(void);
6ffe3a32 1624void __default_new_handler (void);
203b91b9 1625
442e881d 1626vfp __new_handler = __default_new_handler;
203b91b9 1627
203b91b9 1628vfp
6ffe3a32 1629set_new_handler (vfp handler)
203b91b9
RS
1630{
1631 vfp prev_handler;
1632
1633 prev_handler = __new_handler;
442e881d 1634 if (handler == 0) handler = __default_new_handler;
203b91b9
RS
1635 __new_handler = handler;
1636 return prev_handler;
1637}
1638
b1166fae
RS
1639#define MESSAGE "Virtual memory exceeded in `new'\n"
1640
6ffe3a32 1641void
442e881d 1642__default_new_handler ()
203b91b9
RS
1643{
1644 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1645 /* This should really print the name of the program, but that is hard to
1646 do. We need a standard, clean way to get at the name. */
b1166fae 1647 write (2, MESSAGE, sizeof (MESSAGE));
203b91b9
RS
1648 /* don't call exit () because that may call global destructors which
1649 may cause a loop. */
1650 _exit (-1);
1651}
1652#endif
203b91b9 1653
ec06f00a 1654#ifdef L_op_delete
6ffe3a32
JM
1655/* operator delete (void *), described in 17.3.3.3. This function is used
1656 by C++ programs to return to the free store a block of memory allocated
1657 as a single object. */
1658
203b91b9 1659void
ec06f00a 1660__builtin_delete (void *ptr)
203b91b9
RS
1661{
1662 if (ptr)
1663 free (ptr);
1664}
203b91b9 1665#endif
6ffe3a32 1666
4c548483 1667#ifdef L_op_vdel
6ffe3a32
JM
1668/* operator delete [] (void *), described in 17.3.3.4. This function is
1669 used by C++ programs to return to the free store a block of memory
1670 allocated as an array. */
1671
1672extern void __builtin_delete (void *);
1673
1674void
1675__builtin_vec_delete (void *ptr)
1676{
1677 __builtin_delete (ptr);
1678}
1679#endif
1680
1681/* End of C++ free-store management functions */
ec06f00a 1682\f
203b91b9
RS
1683#ifdef L_shtab
1684unsigned int __shtab[] = {
1685 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1686 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1687 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1688 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1689 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1690 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1691 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1692 0x10000000, 0x20000000, 0x40000000, 0x80000000
1693 };
1694#endif
1695\f
1696#ifdef L_clear_cache
1697/* Clear part of an instruction cache. */
1698
1699#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1700
1701void
1702__clear_cache (beg, end)
1703 char *beg, *end;
1704{
e1178973
KKT
1705#ifdef CLEAR_INSN_CACHE
1706 CLEAR_INSN_CACHE (beg, end);
1707#else
203b91b9
RS
1708#ifdef INSN_CACHE_SIZE
1709 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1710 static int initialized = 0;
1711 int offset;
b6422cca
RS
1712 void *start_addr
1713 void *end_addr;
203b91b9
RS
1714 typedef (*function_ptr) ();
1715
1716#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1717 /* It's cheaper to clear the whole cache.
1718 Put in a series of jump instructions so that calling the beginning
1719 of the cache will clear the whole thing. */
1720
1721 if (! initialized)
1722 {
1723 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1724 & -INSN_CACHE_LINE_WIDTH);
1725 int end_ptr = ptr + INSN_CACHE_SIZE;
1726
1727 while (ptr < end_ptr)
1728 {
1729 *(INSTRUCTION_TYPE *)ptr
1730 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1731 ptr += INSN_CACHE_LINE_WIDTH;
1732 }
1733 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1734
1735 initialized = 1;
1736 }
1737
1738 /* Call the beginning of the sequence. */
1739 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1740 & -INSN_CACHE_LINE_WIDTH))
1741 ());
1742
1743#else /* Cache is large. */
1744
1745 if (! initialized)
1746 {
1747 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1748 & -INSN_CACHE_LINE_WIDTH);
1749
1750 while (ptr < (int) array + sizeof array)
1751 {
1752 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1753 ptr += INSN_CACHE_LINE_WIDTH;
1754 }
1755
1756 initialized = 1;
1757 }
1758
1759 /* Find the location in array that occupies the same cache line as BEG. */
1760
1761 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1762 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1763 & -INSN_CACHE_PLANE_SIZE)
1764 + offset);
1765
1766 /* Compute the cache alignment of the place to stop clearing. */
1767#if 0 /* This is not needed for gcc's purposes. */
1768 /* If the block to clear is bigger than a cache plane,
1769 we clear the entire cache, and OFFSET is already correct. */
1770 if (end < beg + INSN_CACHE_PLANE_SIZE)
1771#endif
1772 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1773 & -INSN_CACHE_LINE_WIDTH)
1774 & (INSN_CACHE_PLANE_SIZE - 1));
1775
1776#if INSN_CACHE_DEPTH > 1
1777 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1778 if (end_addr <= start_addr)
1779 end_addr += INSN_CACHE_PLANE_SIZE;
1780
1781 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1782 {
1783 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1784 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1785
1786 while (addr != stop)
1787 {
1788 /* Call the return instruction at ADDR. */
1789 ((function_ptr) addr) ();
1790
1791 addr += INSN_CACHE_LINE_WIDTH;
1792 }
1793 }
1794#else /* just one plane */
1795 do
1796 {
1797 /* Call the return instruction at START_ADDR. */
1798 ((function_ptr) start_addr) ();
1799
1800 start_addr += INSN_CACHE_LINE_WIDTH;
1801 }
1802 while ((start_addr % INSN_CACHE_SIZE) != offset);
1803#endif /* just one plane */
1804#endif /* Cache is large */
1805#endif /* Cache exists */
e1178973 1806#endif /* CLEAR_INSN_CACHE */
203b91b9
RS
1807}
1808
1809#endif /* L_clear_cache */
1810\f
1811#ifdef L_trampoline
1812
1813/* Jump to a trampoline, loading the static chain address. */
1814
1815#ifdef TRANSFER_FROM_TRAMPOLINE
1816TRANSFER_FROM_TRAMPOLINE
1817#endif
1818
c1381fd3
KKT
1819#if defined (NeXT) && defined (__MACH__)
1820
1821/* Make stack executable so we can call trampolines on stack.
1822 This is called from INITIALIZE_TRAMPOLINE in next.h. */
c5df463e
RK
1823#ifdef NeXTStep21
1824 #include <mach.h>
1825#else
1826 #include <mach/mach.h>
1827#endif
c1381fd3
KKT
1828
1829void
1830__enable_execute_stack (addr)
1831 char *addr;
1832{
1833 kern_return_t r;
1834 char *eaddr = addr + TRAMPOLINE_SIZE;
1835 vm_address_t a = (vm_address_t) addr;
1836
1837 /* turn on execute access on stack */
1838 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1839 if (r != KERN_SUCCESS)
1840 {
1841 mach_error("vm_protect VM_PROT_ALL", r);
1842 exit(1);
1843 }
1844
1845 /* We inline the i-cache invalidation for speed */
1846
1847#ifdef CLEAR_INSN_CACHE
1848 CLEAR_INSN_CACHE (addr, eaddr);
1849#else
1850 __clear_cache ((int) addr, (int) eaddr);
1851#endif
1852}
1853
1854#endif /* defined (NeXT) && defined (__MACH__) */
1855
203b91b9
RS
1856#ifdef __convex__
1857
1858/* Make stack executable so we can call trampolines on stack.
1859 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1860
1861#include <sys/mman.h>
1862#include <sys/vmparam.h>
1863#include <machine/machparam.h>
1864
1865void
1866__enable_execute_stack ()
1867{
1868 int fp;
1869 static unsigned lowest = USRSTACK;
1870 unsigned current = (unsigned) &fp & -NBPG;
1871
1872 if (lowest > current)
1873 {
1874 unsigned len = lowest - current;
1875 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1876 lowest = current;
1877 }
1878
1879 /* Clear instruction cache in case an old trampoline is in it. */
1880 asm ("pich");
1881}
1882#endif /* __convex__ */
b335c2cc 1883
0c8ae3d3
RK
1884#ifdef __DOLPHIN__
1885
1886/* Modified from the convex -code above. */
1887
1888#include <sys/param.h>
1889#include <errno.h>
1890#include <sys/m88kbcs.h>
1891
1892void
1893__enable_execute_stack ()
1894{
1895 int save_errno;
1896 static unsigned long lowest = USRSTACK;
1897 unsigned long current = (unsigned long) &save_errno & -NBPC;
1898
1899 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1900 address is seen as 'negative'. That is the case with the stack. */
1901
1902 save_errno=errno;
1903 if (lowest > current)
1904 {
1905 unsigned len=lowest-current;
1906 memctl(current,len,MCT_TEXT);
1907 lowest = current;
1908 }
1909 else
1910 memctl(current,NBPC,MCT_TEXT);
1911 errno=save_errno;
1912}
1913
1914#endif /* __DOLPHIN__ */
1915
b335c2cc
TW
1916#ifdef __pyr__
1917
98126ed6 1918#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
b335c2cc
TW
1919#include <stdio.h>
1920#include <sys/mman.h>
1921#include <sys/types.h>
1922#include <sys/param.h>
1923#include <sys/vmmac.h>
1924
1925/* Modified from the convex -code above.
1926 mremap promises to clear the i-cache. */
1927
1928void
1929__enable_execute_stack ()
1930{
1931 int fp;
1932 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1933 PROT_READ|PROT_WRITE|PROT_EXEC))
1934 {
1935 perror ("mprotect in __enable_execute_stack");
1936 fflush (stderr);
1937 abort ();
1938 }
1939}
1940#endif /* __pyr__ */
203b91b9
RS
1941#endif /* L_trampoline */
1942\f
1943#ifdef L__main
1944
1945#include "gbl-ctors.h"
c06cff95
RS
1946/* Some systems use __main in a way incompatible with its use in gcc, in these
1947 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1948 give the same symbol without quotes for an alternative entry point. You
1949 must define both, or niether. */
1950#ifndef NAME__MAIN
1951#define NAME__MAIN "__main"
1952#define SYMBOL__MAIN __main
1953#endif
203b91b9
RS
1954
1955/* Run all the global destructors on exit from the program. */
1956
1957void
1958__do_global_dtors ()
1959{
89cf554b
RS
1960#ifdef DO_GLOBAL_DTORS_BODY
1961 DO_GLOBAL_DTORS_BODY;
1962#else
0dadecf6 1963 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
b6422cca 1964 unsigned i;
203b91b9
RS
1965
1966 /* Some systems place the number of pointers
1967 in the first word of the table.
1968 On other systems, that word is -1.
1969 In all cases, the table is null-terminated. */
1970
1971 /* If the length is not recorded, count up to the null. */
1972 if (nptrs == -1)
1973 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1974
1975 /* GNU LD format. */
1976 for (i = nptrs; i >= 1; i--)
1977 __DTOR_LIST__[i] ();
89cf554b 1978#endif
203b91b9
RS
1979}
1980
1981#ifndef INIT_SECTION_ASM_OP
1982/* Run all the global constructors on entry to the program. */
1983
135461d9 1984#ifndef ON_EXIT
203b91b9
RS
1985#define ON_EXIT(a, b)
1986#else
1987/* Make sure the exit routine is pulled in to define the globals as
1988 bss symbols, just in case the linker does not automatically pull
1989 bss definitions from the library. */
1990
1991extern int _exit_dummy_decl;
1992int *_exit_dummy_ref = &_exit_dummy_decl;
1993#endif /* ON_EXIT */
1994
1995void
1996__do_global_ctors ()
1997{
1998 DO_GLOBAL_CTORS_BODY;
135461d9 1999 ON_EXIT (__do_global_dtors, 0);
203b91b9 2000}
b335c2cc 2001#endif /* no INIT_SECTION_ASM_OP */
203b91b9 2002
b335c2cc 2003#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
203b91b9
RS
2004/* Subroutine called automatically by `main'.
2005 Compiling a global function named `main'
2006 produces an automatic call to this function at the beginning.
2007
2008 For many systems, this routine calls __do_global_ctors.
2009 For systems which support a .init section we use the .init section
2010 to run __do_global_ctors, so we need not do anything here. */
2011
2012void
c06cff95 2013SYMBOL__MAIN ()
203b91b9
RS
2014{
2015 /* Support recursive calls to `main': run initializers just once. */
b6422cca 2016 static int initialized = 0;
203b91b9
RS
2017 if (! initialized)
2018 {
2019 initialized = 1;
2020 __do_global_ctors ();
2021 }
2022}
b335c2cc 2023#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
203b91b9
RS
2024
2025#endif /* L__main */
2026\f
ad38743d 2027#ifdef L_ctors
203b91b9
RS
2028
2029#include "gbl-ctors.h"
2030
2031/* Provide default definitions for the lists of constructors and
2032 destructors, so that we don't get linker errors. These symbols are
2033 intentionally bss symbols, so that gld and/or collect will provide
2034 the right values. */
2035
2036/* We declare the lists here with two elements each,
2037 so that they are valid empty lists if no other definition is loaded. */
b335c2cc 2038#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
d15d0264
RS
2039#ifdef __NeXT__
2040/* After 2.3, try this definition on all systems. */
2041func_ptr __CTOR_LIST__[2] = {0, 0};
2042func_ptr __DTOR_LIST__[2] = {0, 0};
2043#else
203b91b9
RS
2044func_ptr __CTOR_LIST__[2];
2045func_ptr __DTOR_LIST__[2];
d15d0264 2046#endif
b335c2cc 2047#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
ad38743d
RS
2048#endif /* L_ctors */
2049\f
2050#ifdef L_exit
2051
2052#include "gbl-ctors.h"
203b91b9
RS
2053
2054#ifndef ON_EXIT
2055
2056/* If we have no known way of registering our own __do_global_dtors
2057 routine so that it will be invoked at program exit time, then we
2058 have to define our own exit routine which will get this to happen. */
2059
2060extern void __do_global_dtors ();
2061extern void _cleanup ();
003be455 2062extern void _exit () __attribute__ ((noreturn));
203b91b9
RS
2063
2064void
2065exit (status)
2066 int status;
2067{
2068 __do_global_dtors ();
2069#ifdef EXIT_BODY
2070 EXIT_BODY;
2071#else
2072 _cleanup ();
2073#endif
2074 _exit (status);
2075}
2076
2077#else
2078int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2079#endif
2080
2081#endif /* L_exit */
2082\f
2083/* In a.out systems, we need to have these dummy constructor and destructor
2084 lists in the library.
2085
2086 When using `collect', the first link will resolve __CTOR_LIST__
2087 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
2088 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
2089 Since we don't do the second link if no constructors existed, these
2090 dummies must be fully functional empty lists.
2091
2092 When using `gnu ld', these symbols will be used if there are no
2093 constructors. If there are constructors, the N_SETV symbol defined
2094 by the linker from the N_SETT's in input files will define __CTOR_LIST__
2095 and __DTOR_LIST__ rather than its being allocated as common storage
2096 by the definitions below.
2097
2098 When using a linker that supports constructor and destructor segments,
2099 these definitions will not be used, since crtbegin.o and crtend.o
2100 (from crtstuff.c) will have already defined __CTOR_LIST__ and
2101 __DTOR_LIST__. The crt*.o files are passed directly to the linker
2102 on its command line, by gcc. */
2103
2104/* The list needs two elements: one is ignored (the old count); the
2105 second is the terminating zero. Since both values are zero, this
2106 declaration is not initialized, and it becomes `common'. */
2107
2108#ifdef L_ctor_list
2109#include "gbl-ctors.h"
2110func_ptr __CTOR_LIST__[2];
2111#endif
2112
2113#ifdef L_dtor_list
2114#include "gbl-ctors.h"
2115func_ptr __DTOR_LIST__[2];
2116#endif
This page took 0.451498 seconds and 5 git commands to generate.