libgcc2.c revision 50600
1/* More subroutines needed by GCC output code on some machines. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 1989, 92-97, 1998 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, 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22/* As a special exception, if you link this library with other files, 23 some of which are compiled with GCC, to produce an executable, 24 this library does not by itself cause the resulting executable 25 to be covered by the GNU General Public License. 26 This exception does not however invalidate any other reasons why 27 the executable file might be covered by the GNU General Public License. */ 28 29/* It is incorrect to include config.h here, because this file is being 30 compiled for the target, and hence definitions concerning only the host 31 do not apply. */ 32 33#include "tconfig.h" 34 35/* We disable this when inhibit_libc, so that gcc can still be built without 36 needing header files first. */ 37/* ??? This is not a good solution, since prototypes may be required in 38 some cases for correct code. See also frame.c. */ 39#ifndef inhibit_libc 40/* fixproto guarantees these system headers exist. */ 41#include <stdlib.h> 42#include <unistd.h> 43#endif 44 45#include "machmode.h" 46#include "defaults.h" 47#ifndef L_trampoline 48#include <stddef.h> 49#endif 50 51/* Don't use `fancy_abort' here even if config.h says to use it. */ 52#ifdef abort 53#undef abort 54#endif 55 56#if (SUPPORTS_WEAK == 1) && (defined (ASM_OUTPUT_DEF) || defined (ASM_OUTPUT_WEAK_ALIAS)) 57#define WEAK_ALIAS 58#endif 59 60/* In a cross-compilation situation, default to inhibiting compilation 61 of routines that use libc. */ 62 63#if defined(CROSS_COMPILE) && !defined(inhibit_libc) 64#define inhibit_libc 65#endif 66 67/* Permit the tm.h file to select the endianness to use just for this 68 file. This is used when the endianness is determined when the 69 compiler is run. */ 70 71#ifndef LIBGCC2_WORDS_BIG_ENDIAN 72#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN 73#endif 74 75/* In the first part of this file, we are interfacing to calls generated 76 by the compiler itself. These calls pass values into these routines 77 which have very specific modes (rather than very specific types), and 78 these compiler-generated calls also expect any return values to have 79 very specific modes (rather than very specific types). Thus, we need 80 to avoid using regular C language type names in this part of the file 81 because the sizes for those types can be configured to be anything. 82 Instead we use the following special type names. */ 83 84typedef unsigned int UQItype __attribute__ ((mode (QI))); 85typedef int SItype __attribute__ ((mode (SI))); 86typedef unsigned int USItype __attribute__ ((mode (SI))); 87typedef int DItype __attribute__ ((mode (DI))); 88typedef unsigned int UDItype __attribute__ ((mode (DI))); 89 90typedef float SFtype __attribute__ ((mode (SF))); 91typedef float DFtype __attribute__ ((mode (DF))); 92 93#if LONG_DOUBLE_TYPE_SIZE == 96 94typedef float XFtype __attribute__ ((mode (XF))); 95#endif 96#if LONG_DOUBLE_TYPE_SIZE == 128 97typedef float TFtype __attribute__ ((mode (TF))); 98#endif 99 100typedef int word_type __attribute__ ((mode (__word__))); 101 102/* Make sure that we don't accidentally use any normal C language built-in 103 type names in the first part of this file. Instead we want to use *only* 104 the type names defined above. The following macro definitions insure 105 that if we *do* accidentally use some normal C language built-in type name, 106 we will get a syntax error. */ 107 108#define char bogus_type 109#define short bogus_type 110#define int bogus_type 111#define long bogus_type 112#define unsigned bogus_type 113#define float bogus_type 114#define double bogus_type 115 116#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) 117 118/* DIstructs are pairs of SItype values in the order determined by 119 LIBGCC2_WORDS_BIG_ENDIAN. */ 120 121#if LIBGCC2_WORDS_BIG_ENDIAN 122 struct DIstruct {SItype high, low;}; 123#else 124 struct DIstruct {SItype low, high;}; 125#endif 126 127/* We need this union to unpack/pack DImode values, since we don't have 128 any arithmetic yet. Incoming DImode parameters are stored into the 129 `ll' field, and the unpacked result is read from the struct `s'. */ 130 131typedef union 132{ 133 struct DIstruct s; 134 DItype ll; 135} DIunion; 136 137#if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\ 138 || defined (L_divdi3) || defined (L_udivdi3) \ 139 || defined (L_moddi3) || defined (L_umoddi3)) 140 141#include "longlong.h" 142 143#endif /* udiv or mul */ 144 145extern DItype __fixunssfdi (SFtype a); 146extern DItype __fixunsdfdi (DFtype a); 147#if LONG_DOUBLE_TYPE_SIZE == 96 148extern DItype __fixunsxfdi (XFtype a); 149#endif 150#if LONG_DOUBLE_TYPE_SIZE == 128 151extern DItype __fixunstfdi (TFtype a); 152#endif 153 154#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3) 155#if defined (L_divdi3) || defined (L_moddi3) 156static inline 157#endif 158DItype 159__negdi2 (DItype u) 160{ 161 DIunion w; 162 DIunion uu; 163 164 uu.ll = u; 165 166 w.s.low = -uu.s.low; 167 w.s.high = -uu.s.high - ((USItype) w.s.low > 0); 168 169 return w.ll; 170} 171#endif 172 173/* Unless shift functions are defined whith full ANSI prototypes, 174 parameter b will be promoted to int if word_type is smaller than an int. */ 175#ifdef L_lshrdi3 176DItype 177__lshrdi3 (DItype u, word_type b) 178{ 179 DIunion w; 180 word_type bm; 181 DIunion uu; 182 183 if (b == 0) 184 return u; 185 186 uu.ll = u; 187 188 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 189 if (bm <= 0) 190 { 191 w.s.high = 0; 192 w.s.low = (USItype)uu.s.high >> -bm; 193 } 194 else 195 { 196 USItype carries = (USItype)uu.s.high << bm; 197 w.s.high = (USItype)uu.s.high >> b; 198 w.s.low = ((USItype)uu.s.low >> b) | carries; 199 } 200 201 return w.ll; 202} 203#endif 204 205#ifdef L_ashldi3 206DItype 207__ashldi3 (DItype u, word_type b) 208{ 209 DIunion w; 210 word_type bm; 211 DIunion uu; 212 213 if (b == 0) 214 return u; 215 216 uu.ll = u; 217 218 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 219 if (bm <= 0) 220 { 221 w.s.low = 0; 222 w.s.high = (USItype)uu.s.low << -bm; 223 } 224 else 225 { 226 USItype carries = (USItype)uu.s.low >> bm; 227 w.s.low = (USItype)uu.s.low << b; 228 w.s.high = ((USItype)uu.s.high << b) | carries; 229 } 230 231 return w.ll; 232} 233#endif 234 235#ifdef L_ashrdi3 236DItype 237__ashrdi3 (DItype u, word_type b) 238{ 239 DIunion w; 240 word_type bm; 241 DIunion uu; 242 243 if (b == 0) 244 return u; 245 246 uu.ll = u; 247 248 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 249 if (bm <= 0) 250 { 251 /* w.s.high = 1..1 or 0..0 */ 252 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); 253 w.s.low = uu.s.high >> -bm; 254 } 255 else 256 { 257 USItype carries = (USItype)uu.s.high << bm; 258 w.s.high = uu.s.high >> b; 259 w.s.low = ((USItype)uu.s.low >> b) | carries; 260 } 261 262 return w.ll; 263} 264#endif 265 266#ifdef L_ffsdi2 267DItype 268__ffsdi2 (DItype u) 269{ 270 DIunion uu, w; 271 uu.ll = u; 272 w.s.high = 0; 273 w.s.low = ffs (uu.s.low); 274 if (w.s.low != 0) 275 return w.ll; 276 w.s.low = ffs (uu.s.high); 277 if (w.s.low != 0) 278 { 279 w.s.low += BITS_PER_UNIT * sizeof (SItype); 280 return w.ll; 281 } 282 return w.ll; 283} 284#endif 285 286#ifdef L_muldi3 287DItype 288__muldi3 (DItype u, DItype v) 289{ 290 DIunion w; 291 DIunion uu, vv; 292 293 uu.ll = u, 294 vv.ll = v; 295 296 w.ll = __umulsidi3 (uu.s.low, vv.s.low); 297 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 298 + (USItype) uu.s.high * (USItype) vv.s.low); 299 300 return w.ll; 301} 302#endif 303 304#ifdef L_udiv_w_sdiv 305#if defined (sdiv_qrnnd) 306USItype 307__udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d) 308{ 309 USItype q, r; 310 USItype c0, c1, b1; 311 312 if ((SItype) d >= 0) 313 { 314 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1))) 315 { 316 /* dividend, divisor, and quotient are nonnegative */ 317 sdiv_qrnnd (q, r, a1, a0, d); 318 } 319 else 320 { 321 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ 322 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1)); 323 /* Divide (c1*2^32 + c0) by d */ 324 sdiv_qrnnd (q, r, c1, c0, d); 325 /* Add 2^31 to quotient */ 326 q += (USItype) 1 << (SI_TYPE_SIZE - 1); 327 } 328 } 329 else 330 { 331 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 332 c1 = a1 >> 1; /* A/2 */ 333 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1); 334 335 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 336 { 337 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 338 339 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 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 if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 357 { 358 c1 = (b1 - 1) - c1; 359 c0 = ~c0; /* logical NOT */ 360 361 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 362 363 q = ~q; /* (A/2)/b1 */ 364 r = (b1 - 1) - r; 365 366 r = 2*r + (a0 & 1); /* A/(2*b1) */ 367 368 if ((d & 1) != 0) 369 { 370 if (r >= q) 371 r = r - q; 372 else if (q - r <= d) 373 { 374 r = r - q + d; 375 q--; 376 } 377 else 378 { 379 r = r - q + 2*d; 380 q -= 2; 381 } 382 } 383 } 384 else /* Implies c1 = b1 */ 385 { /* Hence a1 = d - 1 = 2*b1 - 1 */ 386 if (a0 >= -d) 387 { 388 q = -1; 389 r = a0 + d; 390 } 391 else 392 { 393 q = -2; 394 r = a0 + 2*d; 395 } 396 } 397 } 398 399 *rp = r; 400 return q; 401} 402#else 403/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ 404USItype 405__udiv_w_sdiv (USItype *rp __attribute__ ((__unused__)), 406 USItype a1 __attribute__ ((__unused__)), 407 USItype a0 __attribute__ ((__unused__)), 408 USItype d __attribute__ ((__unused__))) 409{ 410 return 0; 411} 412#endif 413#endif 414 415#if (defined (L_udivdi3) || defined (L_divdi3) || \ 416 defined (L_umoddi3) || defined (L_moddi3)) 417#define L_udivmoddi4 418#endif 419 420#ifdef L_udivmoddi4 421static const UQItype __clz_tab[] = 422{ 423 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, 424 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, 425 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, 426 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, 427 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, 428 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, 429 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, 430 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, 431}; 432 433#if (defined (L_udivdi3) || defined (L_divdi3) || \ 434 defined (L_umoddi3) || defined (L_moddi3)) 435static inline 436#endif 437UDItype 438__udivmoddi4 (UDItype n, UDItype d, UDItype *rp) 439{ 440 DIunion ww; 441 DIunion nn, dd; 442 DIunion rr; 443 USItype d0, d1, n0, n1, n2; 444 USItype q0, q1; 445 USItype b, bm; 446 447 nn.ll = n; 448 dd.ll = d; 449 450 d0 = dd.s.low; 451 d1 = dd.s.high; 452 n0 = nn.s.low; 453 n1 = nn.s.high; 454 455#if !UDIV_NEEDS_NORMALIZATION 456 if (d1 == 0) 457 { 458 if (d0 > n1) 459 { 460 /* 0q = nn / 0D */ 461 462 udiv_qrnnd (q0, n0, n1, n0, d0); 463 q1 = 0; 464 465 /* Remainder in n0. */ 466 } 467 else 468 { 469 /* qq = NN / 0d */ 470 471 if (d0 == 0) 472 d0 = 1 / d0; /* Divide intentionally by zero. */ 473 474 udiv_qrnnd (q1, n1, 0, n1, d0); 475 udiv_qrnnd (q0, n0, n1, n0, d0); 476 477 /* Remainder in n0. */ 478 } 479 480 if (rp != 0) 481 { 482 rr.s.low = n0; 483 rr.s.high = 0; 484 *rp = rr.ll; 485 } 486 } 487 488#else /* UDIV_NEEDS_NORMALIZATION */ 489 490 if (d1 == 0) 491 { 492 if (d0 > n1) 493 { 494 /* 0q = nn / 0D */ 495 496 count_leading_zeros (bm, d0); 497 498 if (bm != 0) 499 { 500 /* Normalize, i.e. make the most significant bit of the 501 denominator set. */ 502 503 d0 = d0 << bm; 504 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); 505 n0 = n0 << bm; 506 } 507 508 udiv_qrnnd (q0, n0, n1, n0, d0); 509 q1 = 0; 510 511 /* Remainder in n0 >> bm. */ 512 } 513 else 514 { 515 /* qq = NN / 0d */ 516 517 if (d0 == 0) 518 d0 = 1 / d0; /* Divide intentionally by zero. */ 519 520 count_leading_zeros (bm, d0); 521 522 if (bm == 0) 523 { 524 /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 525 conclude (the most significant bit of n1 is set) /\ (the 526 leading quotient digit q1 = 1). 527 528 This special case is necessary, not an optimization. 529 (Shifts counts of SI_TYPE_SIZE are undefined.) */ 530 531 n1 -= d0; 532 q1 = 1; 533 } 534 else 535 { 536 /* Normalize. */ 537 538 b = SI_TYPE_SIZE - bm; 539 540 d0 = d0 << bm; 541 n2 = n1 >> b; 542 n1 = (n1 << bm) | (n0 >> b); 543 n0 = n0 << bm; 544 545 udiv_qrnnd (q1, n1, n2, n1, d0); 546 } 547 548 /* n1 != d0... */ 549 550 udiv_qrnnd (q0, n0, n1, n0, d0); 551 552 /* Remainder in n0 >> bm. */ 553 } 554 555 if (rp != 0) 556 { 557 rr.s.low = n0 >> bm; 558 rr.s.high = 0; 559 *rp = rr.ll; 560 } 561 } 562#endif /* UDIV_NEEDS_NORMALIZATION */ 563 564 else 565 { 566 if (d1 > n1) 567 { 568 /* 00 = nn / DD */ 569 570 q0 = 0; 571 q1 = 0; 572 573 /* Remainder in n1n0. */ 574 if (rp != 0) 575 { 576 rr.s.low = n0; 577 rr.s.high = n1; 578 *rp = rr.ll; 579 } 580 } 581 else 582 { 583 /* 0q = NN / dd */ 584 585 count_leading_zeros (bm, d1); 586 if (bm == 0) 587 { 588 /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 589 conclude (the most significant bit of n1 is set) /\ (the 590 quotient digit q0 = 0 or 1). 591 592 This special case is necessary, not an optimization. */ 593 594 /* The condition on the next line takes advantage of that 595 n1 >= d1 (true due to program flow). */ 596 if (n1 > d1 || n0 >= d0) 597 { 598 q0 = 1; 599 sub_ddmmss (n1, n0, n1, n0, d1, d0); 600 } 601 else 602 q0 = 0; 603 604 q1 = 0; 605 606 if (rp != 0) 607 { 608 rr.s.low = n0; 609 rr.s.high = n1; 610 *rp = rr.ll; 611 } 612 } 613 else 614 { 615 USItype m1, m0; 616 /* Normalize. */ 617 618 b = SI_TYPE_SIZE - bm; 619 620 d1 = (d1 << bm) | (d0 >> b); 621 d0 = d0 << bm; 622 n2 = n1 >> b; 623 n1 = (n1 << bm) | (n0 >> b); 624 n0 = n0 << bm; 625 626 udiv_qrnnd (q0, n1, n2, n1, d1); 627 umul_ppmm (m1, m0, q0, d0); 628 629 if (m1 > n1 || (m1 == n1 && m0 > n0)) 630 { 631 q0--; 632 sub_ddmmss (m1, m0, m1, m0, d1, d0); 633 } 634 635 q1 = 0; 636 637 /* Remainder in (n1n0 - m1m0) >> bm. */ 638 if (rp != 0) 639 { 640 sub_ddmmss (n1, n0, n1, n0, m1, m0); 641 rr.s.low = (n1 << b) | (n0 >> bm); 642 rr.s.high = n1 >> bm; 643 *rp = rr.ll; 644 } 645 } 646 } 647 } 648 649 ww.s.low = q0; 650 ww.s.high = q1; 651 return ww.ll; 652} 653#endif 654 655#ifdef L_divdi3 656UDItype __udivmoddi4 (); 657 658DItype 659__divdi3 (DItype u, DItype v) 660{ 661 word_type c = 0; 662 DIunion uu, vv; 663 DItype w; 664 665 uu.ll = u; 666 vv.ll = v; 667 668 if (uu.s.high < 0) 669 c = ~c, 670 uu.ll = __negdi2 (uu.ll); 671 if (vv.s.high < 0) 672 c = ~c, 673 vv.ll = __negdi2 (vv.ll); 674 675 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0); 676 if (c) 677 w = __negdi2 (w); 678 679 return w; 680} 681#endif 682 683#ifdef L_moddi3 684UDItype __udivmoddi4 (); 685DItype 686__moddi3 (DItype u, DItype v) 687{ 688 word_type c = 0; 689 DIunion uu, vv; 690 DItype w; 691 692 uu.ll = u; 693 vv.ll = v; 694 695 if (uu.s.high < 0) 696 c = ~c, 697 uu.ll = __negdi2 (uu.ll); 698 if (vv.s.high < 0) 699 vv.ll = __negdi2 (vv.ll); 700 701 (void) __udivmoddi4 (uu.ll, vv.ll, &w); 702 if (c) 703 w = __negdi2 (w); 704 705 return w; 706} 707#endif 708 709#ifdef L_umoddi3 710UDItype __udivmoddi4 (); 711UDItype 712__umoddi3 (UDItype u, UDItype v) 713{ 714 UDItype w; 715 716 (void) __udivmoddi4 (u, v, &w); 717 718 return w; 719} 720#endif 721 722#ifdef L_udivdi3 723UDItype __udivmoddi4 (); 724UDItype 725__udivdi3 (UDItype n, UDItype d) 726{ 727 return __udivmoddi4 (n, d, (UDItype *) 0); 728} 729#endif 730 731#ifdef L_cmpdi2 732word_type 733__cmpdi2 (DItype a, DItype b) 734{ 735 DIunion au, bu; 736 737 au.ll = a, bu.ll = b; 738 739 if (au.s.high < bu.s.high) 740 return 0; 741 else if (au.s.high > bu.s.high) 742 return 2; 743 if ((USItype) au.s.low < (USItype) bu.s.low) 744 return 0; 745 else if ((USItype) au.s.low > (USItype) bu.s.low) 746 return 2; 747 return 1; 748} 749#endif 750 751#ifdef L_ucmpdi2 752word_type 753__ucmpdi2 (DItype a, DItype b) 754{ 755 DIunion au, bu; 756 757 au.ll = a, bu.ll = b; 758 759 if ((USItype) au.s.high < (USItype) bu.s.high) 760 return 0; 761 else if ((USItype) au.s.high > (USItype) bu.s.high) 762 return 2; 763 if ((USItype) au.s.low < (USItype) bu.s.low) 764 return 0; 765 else if ((USItype) au.s.low > (USItype) bu.s.low) 766 return 2; 767 return 1; 768} 769#endif 770 771#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128) 772#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 773#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 774 775DItype 776__fixunstfdi (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 (TFtype a) 806{ 807 if (a < 0) 808 return - __fixunstfdi (-a); 809 return __fixunstfdi (a); 810} 811#endif 812 813#if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96) 814#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 815#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 816 817DItype 818__fixunsxfdi (XFtype a) 819{ 820 XFtype b; 821 UDItype v; 822 823 if (a < 0) 824 return 0; 825 826 /* Compute high word of result, as a flonum. */ 827 b = (a / HIGH_WORD_COEFF); 828 /* Convert that to fixed (but not to DItype!), 829 and shift it into the high word. */ 830 v = (USItype) b; 831 v <<= WORD_SIZE; 832 /* Remove high part from the XFtype, leaving the low part as flonum. */ 833 a -= (XFtype)v; 834 /* Convert that to fixed (but not to DItype!) and add it in. 835 Sometimes A comes out negative. This is significant, since 836 A has more bits than a long int does. */ 837 if (a < 0) 838 v -= (USItype) (- a); 839 else 840 v += (USItype) a; 841 return v; 842} 843#endif 844 845#if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96) 846DItype 847__fixxfdi (XFtype a) 848{ 849 if (a < 0) 850 return - __fixunsxfdi (-a); 851 return __fixunsxfdi (a); 852} 853#endif 854 855#ifdef L_fixunsdfdi 856#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 857#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 858 859DItype 860__fixunsdfdi (DFtype a) 861{ 862 DFtype b; 863 UDItype v; 864 865 if (a < 0) 866 return 0; 867 868 /* Compute high word of result, as a flonum. */ 869 b = (a / HIGH_WORD_COEFF); 870 /* Convert that to fixed (but not to DItype!), 871 and shift it into the high word. */ 872 v = (USItype) b; 873 v <<= WORD_SIZE; 874 /* Remove high part from the DFtype, leaving the low part as flonum. */ 875 a -= (DFtype)v; 876 /* Convert that to fixed (but not to DItype!) and add it in. 877 Sometimes A comes out negative. This is significant, since 878 A has more bits than a long int does. */ 879 if (a < 0) 880 v -= (USItype) (- a); 881 else 882 v += (USItype) a; 883 return v; 884} 885#endif 886 887#ifdef L_fixdfdi 888DItype 889__fixdfdi (DFtype a) 890{ 891 if (a < 0) 892 return - __fixunsdfdi (-a); 893 return __fixunsdfdi (a); 894} 895#endif 896 897#ifdef L_fixunssfdi 898#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 899#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 900 901DItype 902__fixunssfdi (SFtype original_a) 903{ 904 /* Convert the SFtype to a DFtype, because that is surely not going 905 to lose any bits. Some day someone else can write a faster version 906 that avoids converting to DFtype, and verify it really works right. */ 907 DFtype a = original_a; 908 DFtype b; 909 UDItype v; 910 911 if (a < 0) 912 return 0; 913 914 /* Compute high word of result, as a flonum. */ 915 b = (a / HIGH_WORD_COEFF); 916 /* Convert that to fixed (but not to DItype!), 917 and shift it into the high word. */ 918 v = (USItype) b; 919 v <<= WORD_SIZE; 920 /* Remove high part from the DFtype, leaving the low part as flonum. */ 921 a -= (DFtype)v; 922 /* Convert that to fixed (but not to DItype!) and add it in. 923 Sometimes A comes out negative. This is significant, since 924 A has more bits than a long int does. */ 925 if (a < 0) 926 v -= (USItype) (- a); 927 else 928 v += (USItype) a; 929 return v; 930} 931#endif 932 933#ifdef L_fixsfdi 934DItype 935__fixsfdi (SFtype a) 936{ 937 if (a < 0) 938 return - __fixunssfdi (-a); 939 return __fixunssfdi (a); 940} 941#endif 942 943#if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96) 944#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 945#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 946#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 947 948XFtype 949__floatdixf (DItype u) 950{ 951 XFtype d; 952 953 d = (SItype) (u >> WORD_SIZE); 954 d *= HIGH_HALFWORD_COEFF; 955 d *= HIGH_HALFWORD_COEFF; 956 d += (USItype) (u & (HIGH_WORD_COEFF - 1)); 957 958 return d; 959} 960#endif 961 962#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128) 963#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 964#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 965#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 966 967TFtype 968__floatditf (DItype u) 969{ 970 TFtype d; 971 972 d = (SItype) (u >> WORD_SIZE); 973 d *= HIGH_HALFWORD_COEFF; 974 d *= HIGH_HALFWORD_COEFF; 975 d += (USItype) (u & (HIGH_WORD_COEFF - 1)); 976 977 return d; 978} 979#endif 980 981#ifdef L_floatdidf 982#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 983#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 984#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 985 986DFtype 987__floatdidf (DItype u) 988{ 989 DFtype d; 990 991 d = (SItype) (u >> WORD_SIZE); 992 d *= HIGH_HALFWORD_COEFF; 993 d *= HIGH_HALFWORD_COEFF; 994 d += (USItype) (u & (HIGH_WORD_COEFF - 1)); 995 996 return d; 997} 998#endif 999 1000#ifdef L_floatdisf 1001#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 1002#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) 1003#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) 1004#define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT) 1005 1006/* Define codes for all the float formats that we know of. Note 1007 that this is copied from real.h. */ 1008 1009#define UNKNOWN_FLOAT_FORMAT 0 1010#define IEEE_FLOAT_FORMAT 1 1011#define VAX_FLOAT_FORMAT 2 1012#define IBM_FLOAT_FORMAT 3 1013 1014/* Default to IEEE float if not specified. Nearly all machines use it. */ 1015#ifndef HOST_FLOAT_FORMAT 1016#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT 1017#endif 1018 1019#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT 1020#define DF_SIZE 53 1021#define SF_SIZE 24 1022#endif 1023 1024#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT 1025#define DF_SIZE 56 1026#define SF_SIZE 24 1027#endif 1028 1029#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT 1030#define DF_SIZE 56 1031#define SF_SIZE 24 1032#endif 1033 1034SFtype 1035__floatdisf (DItype u) 1036{ 1037 /* Do the calculation in DFmode 1038 so that we don't lose any of the precision of the high word 1039 while multiplying it. */ 1040 DFtype f; 1041 1042 /* Protect against double-rounding error. 1043 Represent any low-order bits, that might be truncated in DFmode, 1044 by a bit that won't be lost. The bit can go in anywhere below the 1045 rounding position of the SFmode. A fixed mask and bit position 1046 handles all usual configurations. It doesn't handle the case 1047 of 128-bit DImode, however. */ 1048 if (DF_SIZE < DI_SIZE 1049 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) 1050 { 1051#define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE)) 1052 if (! (- ((DItype) 1 << DF_SIZE) < u 1053 && u < ((DItype) 1 << DF_SIZE))) 1054 { 1055 if ((USItype) u & (REP_BIT - 1)) 1056 u |= REP_BIT; 1057 } 1058 } 1059 f = (SItype) (u >> WORD_SIZE); 1060 f *= HIGH_HALFWORD_COEFF; 1061 f *= HIGH_HALFWORD_COEFF; 1062 f += (USItype) (u & (HIGH_WORD_COEFF - 1)); 1063 1064 return (SFtype) f; 1065} 1066#endif 1067 1068#if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96 1069/* Reenable the normal types, in case limits.h needs them. */ 1070#undef char 1071#undef short 1072#undef int 1073#undef long 1074#undef unsigned 1075#undef float 1076#undef double 1077#undef MIN 1078#undef MAX 1079#include <limits.h> 1080 1081USItype 1082__fixunsxfsi (XFtype a) 1083{ 1084 if (a >= - (DFtype) LONG_MIN) 1085 return (SItype) (a + LONG_MIN) - LONG_MIN; 1086 return (SItype) a; 1087} 1088#endif 1089 1090#ifdef L_fixunsdfsi 1091/* Reenable the normal types, in case limits.h needs them. */ 1092#undef char 1093#undef short 1094#undef int 1095#undef long 1096#undef unsigned 1097#undef float 1098#undef double 1099#undef MIN 1100#undef MAX 1101#include <limits.h> 1102 1103USItype 1104__fixunsdfsi (DFtype a) 1105{ 1106 if (a >= - (DFtype) LONG_MIN) 1107 return (SItype) (a + LONG_MIN) - LONG_MIN; 1108 return (SItype) a; 1109} 1110#endif 1111 1112#ifdef L_fixunssfsi 1113/* Reenable the normal types, in case limits.h needs them. */ 1114#undef char 1115#undef short 1116#undef int 1117#undef long 1118#undef unsigned 1119#undef float 1120#undef double 1121#undef MIN 1122#undef MAX 1123#include <limits.h> 1124 1125USItype 1126__fixunssfsi (SFtype a) 1127{ 1128 if (a >= - (SFtype) LONG_MIN) 1129 return (SItype) (a + LONG_MIN) - LONG_MIN; 1130 return (SItype) a; 1131} 1132#endif 1133 1134/* From here on down, the routines use normal data types. */ 1135 1136#define SItype bogus_type 1137#define USItype bogus_type 1138#define DItype bogus_type 1139#define UDItype bogus_type 1140#define SFtype bogus_type 1141#define DFtype bogus_type 1142 1143#undef char 1144#undef short 1145#undef int 1146#undef long 1147#undef unsigned 1148#undef float 1149#undef double 1150 1151#ifdef L__gcc_bcmp 1152 1153/* Like bcmp except the sign is meaningful. 1154 Result is negative if S1 is less than S2, 1155 positive if S1 is greater, 0 if S1 and S2 are equal. */ 1156 1157int 1158__gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size) 1159{ 1160 while (size > 0) 1161 { 1162 unsigned char c1 = *s1++, c2 = *s2++; 1163 if (c1 != c2) 1164 return c1 - c2; 1165 size--; 1166 } 1167 return 0; 1168} 1169 1170#endif 1171 1172#ifdef L__dummy 1173void 1174__dummy () {} 1175#endif 1176 1177#ifdef L_varargs 1178#ifdef __i860__ 1179#if defined(__svr4__) || defined(__alliant__) 1180 asm (" .text"); 1181 asm (" .align 4"); 1182 1183/* The Alliant needs the added underscore. */ 1184 asm (".globl __builtin_saveregs"); 1185asm ("__builtin_saveregs:"); 1186 asm (".globl ___builtin_saveregs"); 1187asm ("___builtin_saveregs:"); 1188 1189 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */ 1190 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save 1191 area and also for a new va_list 1192 structure */ 1193 /* Save all argument registers in the arg reg save area. The 1194 arg reg save area must have the following layout (according 1195 to the svr4 ABI): 1196 1197 struct { 1198 union { 1199 float freg[8]; 1200 double dreg[4]; 1201 } float_regs; 1202 long ireg[12]; 1203 }; 1204 */ 1205 1206 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */ 1207 asm (" fst.q %f12,16(%sp)"); 1208 1209 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */ 1210 asm (" st.l %r17,36(%sp)"); 1211 asm (" st.l %r18,40(%sp)"); 1212 asm (" st.l %r19,44(%sp)"); 1213 asm (" st.l %r20,48(%sp)"); 1214 asm (" st.l %r21,52(%sp)"); 1215 asm (" st.l %r22,56(%sp)"); 1216 asm (" st.l %r23,60(%sp)"); 1217 asm (" st.l %r24,64(%sp)"); 1218 asm (" st.l %r25,68(%sp)"); 1219 asm (" st.l %r26,72(%sp)"); 1220 asm (" st.l %r27,76(%sp)"); 1221 1222 asm (" adds 80,%sp,%r16"); /* compute the address of the new 1223 va_list structure. Put in into 1224 r16 so that it will be returned 1225 to the caller. */ 1226 1227 /* Initialize all fields of the new va_list structure. This 1228 structure looks like: 1229 1230 typedef struct { 1231 unsigned long ireg_used; 1232 unsigned long freg_used; 1233 long *reg_base; 1234 long *mem_ptr; 1235 } va_list; 1236 */ 1237 1238 asm (" st.l %r0, 0(%r16)"); /* nfixed */ 1239 asm (" st.l %r0, 4(%r16)"); /* nfloating */ 1240 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */ 1241 asm (" bri %r1"); /* delayed return */ 1242 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */ 1243 1244#else /* not __svr4__ */ 1245#if defined(__PARAGON__) 1246 /* 1247 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax, 1248 * and we stand a better chance of hooking into libraries 1249 * compiled by PGI. [andyp@ssd.intel.com] 1250 */ 1251 asm (" .text"); 1252 asm (" .align 4"); 1253 asm (".globl __builtin_saveregs"); 1254asm ("__builtin_saveregs:"); 1255 asm (".globl ___builtin_saveregs"); 1256asm ("___builtin_saveregs:"); 1257 1258 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */ 1259 asm (" adds -96,sp,sp"); /* allocate stack space for reg save 1260 area and also for a new va_list 1261 structure */ 1262 /* Save all argument registers in the arg reg save area. The 1263 arg reg save area must have the following layout (according 1264 to the svr4 ABI): 1265 1266 struct { 1267 union { 1268 float freg[8]; 1269 double dreg[4]; 1270 } float_regs; 1271 long ireg[12]; 1272 }; 1273 */ 1274 1275 asm (" fst.q f8, 0(sp)"); 1276 asm (" fst.q f12,16(sp)"); 1277 asm (" st.l r16,32(sp)"); 1278 asm (" st.l r17,36(sp)"); 1279 asm (" st.l r18,40(sp)"); 1280 asm (" st.l r19,44(sp)"); 1281 asm (" st.l r20,48(sp)"); 1282 asm (" st.l r21,52(sp)"); 1283 asm (" st.l r22,56(sp)"); 1284 asm (" st.l r23,60(sp)"); 1285 asm (" st.l r24,64(sp)"); 1286 asm (" st.l r25,68(sp)"); 1287 asm (" st.l r26,72(sp)"); 1288 asm (" st.l r27,76(sp)"); 1289 1290 asm (" adds 80,sp,r16"); /* compute the address of the new 1291 va_list structure. Put in into 1292 r16 so that it will be returned 1293 to the caller. */ 1294 1295 /* Initialize all fields of the new va_list structure. This 1296 structure looks like: 1297 1298 typedef struct { 1299 unsigned long ireg_used; 1300 unsigned long freg_used; 1301 long *reg_base; 1302 long *mem_ptr; 1303 } va_list; 1304 */ 1305 1306 asm (" st.l r0, 0(r16)"); /* nfixed */ 1307 asm (" st.l r0, 4(r16)"); /* nfloating */ 1308 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */ 1309 asm (" bri r1"); /* delayed return */ 1310 asm (" st.l r28,12(r16)"); /* pointer to overflow args */ 1311#else /* not __PARAGON__ */ 1312 asm (" .text"); 1313 asm (" .align 4"); 1314 1315 asm (".globl ___builtin_saveregs"); 1316 asm ("___builtin_saveregs:"); 1317 asm (" mov sp,r30"); 1318 asm (" andnot 0x0f,sp,sp"); 1319 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */ 1320 1321/* Fill in the __va_struct. */ 1322 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */ 1323 asm (" st.l r17, 4(sp)"); /* int fixed[12] */ 1324 asm (" st.l r18, 8(sp)"); 1325 asm (" st.l r19,12(sp)"); 1326 asm (" st.l r20,16(sp)"); 1327 asm (" st.l r21,20(sp)"); 1328 asm (" st.l r22,24(sp)"); 1329 asm (" st.l r23,28(sp)"); 1330 asm (" st.l r24,32(sp)"); 1331 asm (" st.l r25,36(sp)"); 1332 asm (" st.l r26,40(sp)"); 1333 asm (" st.l r27,44(sp)"); 1334 1335 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */ 1336 asm (" fst.q f12,64(sp)"); /* int floating[8] */ 1337 1338/* Fill in the __va_ctl. */ 1339 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */ 1340 asm (" st.l r28,84(sp)"); /* pointer to more args */ 1341 asm (" st.l r0, 88(sp)"); /* nfixed */ 1342 asm (" st.l r0, 92(sp)"); /* nfloating */ 1343 1344 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */ 1345 asm (" bri r1"); 1346 asm (" mov r30,sp"); 1347 /* recover stack and pass address to start 1348 of data. */ 1349#endif /* not __PARAGON__ */ 1350#endif /* not __svr4__ */ 1351#else /* not __i860__ */ 1352#ifdef __sparc__ 1353 asm (".global __builtin_saveregs"); 1354 asm ("__builtin_saveregs:"); 1355 asm (".global ___builtin_saveregs"); 1356 asm ("___builtin_saveregs:"); 1357#ifdef NEED_PROC_COMMAND 1358 asm (".proc 020"); 1359#endif 1360 asm ("st %i0,[%fp+68]"); 1361 asm ("st %i1,[%fp+72]"); 1362 asm ("st %i2,[%fp+76]"); 1363 asm ("st %i3,[%fp+80]"); 1364 asm ("st %i4,[%fp+84]"); 1365 asm ("retl"); 1366 asm ("st %i5,[%fp+88]"); 1367#ifdef NEED_TYPE_COMMAND 1368 asm (".type __builtin_saveregs,#function"); 1369 asm (".size __builtin_saveregs,.-__builtin_saveregs"); 1370#endif 1371#else /* not __sparc__ */ 1372#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__) 1373 1374 asm (" .text"); 1375#ifdef __mips16 1376 asm (" .set nomips16"); 1377#endif 1378 asm (" .ent __builtin_saveregs"); 1379 asm (" .globl __builtin_saveregs"); 1380 asm ("__builtin_saveregs:"); 1381 asm (" sw $4,0($30)"); 1382 asm (" sw $5,4($30)"); 1383 asm (" sw $6,8($30)"); 1384 asm (" sw $7,12($30)"); 1385 asm (" j $31"); 1386 asm (" .end __builtin_saveregs"); 1387#else /* not __mips__, etc. */ 1388 1389void * 1390__builtin_saveregs () 1391{ 1392 abort (); 1393} 1394 1395#endif /* not __mips__ */ 1396#endif /* not __sparc__ */ 1397#endif /* not __i860__ */ 1398#endif 1399 1400#ifdef L_eprintf 1401#ifndef inhibit_libc 1402 1403#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1404#include <stdio.h> 1405/* This is used by the `assert' macro. */ 1406void 1407__eprintf (const char *string, const char *expression, 1408 unsigned int line, const char *filename) 1409{ 1410 fprintf (stderr, string, expression, line, filename); 1411 fflush (stderr); 1412 abort (); 1413} 1414 1415#endif 1416#endif 1417 1418#ifdef L_bb 1419 1420/* Structure emitted by -a */ 1421struct bb 1422{ 1423 long zero_word; 1424 const char *filename; 1425 long *counts; 1426 long ncounts; 1427 struct bb *next; 1428 const unsigned long *addresses; 1429 1430 /* Older GCC's did not emit these fields. */ 1431 long nwords; 1432 const char **functions; 1433 const long *line_nums; 1434 const char **filenames; 1435 char *flags; 1436}; 1437 1438#ifdef BLOCK_PROFILER_CODE 1439BLOCK_PROFILER_CODE 1440#else 1441#ifndef inhibit_libc 1442 1443/* Simple minded basic block profiling output dumper for 1444 systems that don't provide tcov support. At present, 1445 it requires atexit and stdio. */ 1446 1447#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1448#include <stdio.h> 1449char *ctime (); 1450 1451#include "gbl-ctors.h" 1452#include "gcov-io.h" 1453#include <string.h> 1454 1455static struct bb *bb_head; 1456 1457/* Return the number of digits needed to print a value */ 1458/* __inline__ */ static int num_digits (long value, int base) 1459{ 1460 int minus = (value < 0 && base != 16); 1461 unsigned long v = (minus) ? -value : value; 1462 int ret = minus; 1463 1464 do 1465 { 1466 v /= base; 1467 ret++; 1468 } 1469 while (v); 1470 1471 return ret; 1472} 1473 1474void 1475__bb_exit_func (void) 1476{ 1477 FILE *da_file, *file; 1478 long time_value; 1479 int i; 1480 1481 if (bb_head == 0) 1482 return; 1483 1484 i = strlen (bb_head->filename) - 3; 1485 1486 if (!strcmp (bb_head->filename+i, ".da")) 1487 { 1488 /* Must be -fprofile-arcs not -a. 1489 Dump data in a form that gcov expects. */ 1490 1491 struct bb *ptr; 1492 1493 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) 1494 { 1495 /* If the file exists, and the number of counts in it is the same, 1496 then merge them in. */ 1497 1498 if ((da_file = fopen (ptr->filename, "r")) != 0) 1499 { 1500 long n_counts = 0; 1501 1502 if (__read_long (&n_counts, da_file, 8) != 0) 1503 { 1504 fprintf (stderr, "arc profiling: Can't read output file %s.\n", 1505 ptr->filename); 1506 continue; 1507 } 1508 1509 if (n_counts == ptr->ncounts) 1510 { 1511 int i; 1512 1513 for (i = 0; i < n_counts; i++) 1514 { 1515 long v = 0; 1516 1517 if (__read_long (&v, da_file, 8) != 0) 1518 { 1519 fprintf (stderr, "arc profiling: Can't read output file %s.\n", 1520 ptr->filename); 1521 break; 1522 } 1523 ptr->counts[i] += v; 1524 } 1525 } 1526 1527 if (fclose (da_file) == EOF) 1528 fprintf (stderr, "arc profiling: Error closing output file %s.\n", 1529 ptr->filename); 1530 } 1531 if ((da_file = fopen (ptr->filename, "w")) == 0) 1532 { 1533 fprintf (stderr, "arc profiling: Can't open output file %s.\n", 1534 ptr->filename); 1535 continue; 1536 } 1537 1538 /* ??? Should first write a header to the file. Preferably, a 4 byte 1539 magic number, 4 bytes containing the time the program was 1540 compiled, 4 bytes containing the last modification time of the 1541 source file, and 4 bytes indicating the compiler options used. 1542 1543 That way we can easily verify that the proper source/executable/ 1544 data file combination is being used from gcov. */ 1545 1546 if (__write_long (ptr->ncounts, da_file, 8) != 0) 1547 { 1548 1549 fprintf (stderr, "arc profiling: Error writing output file %s.\n", 1550 ptr->filename); 1551 } 1552 else 1553 { 1554 int j; 1555 long *count_ptr = ptr->counts; 1556 int ret = 0; 1557 for (j = ptr->ncounts; j > 0; j--) 1558 { 1559 if (__write_long (*count_ptr, da_file, 8) != 0) 1560 { 1561 ret=1; 1562 break; 1563 } 1564 count_ptr++; 1565 } 1566 if (ret) 1567 fprintf (stderr, "arc profiling: Error writing output file %s.\n", 1568 ptr->filename); 1569 } 1570 1571 if (fclose (da_file) == EOF) 1572 fprintf (stderr, "arc profiling: Error closing output file %s.\n", 1573 ptr->filename); 1574 } 1575 1576 return; 1577 } 1578 1579 /* Must be basic block profiling. Emit a human readable output file. */ 1580 1581 file = fopen ("bb.out", "a"); 1582 1583 if (!file) 1584 perror ("bb.out"); 1585 1586 else 1587 { 1588 struct bb *ptr; 1589 1590 /* This is somewhat type incorrect, but it avoids worrying about 1591 exactly where time.h is included from. It should be ok unless 1592 a void * differs from other pointer formats, or if sizeof (long) 1593 is < sizeof (time_t). It would be nice if we could assume the 1594 use of rationale standards here. */ 1595 1596 time ((void *) &time_value); 1597 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value)); 1598 1599 /* We check the length field explicitly in order to allow compatibility 1600 with older GCC's which did not provide it. */ 1601 1602 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) 1603 { 1604 int i; 1605 int func_p = (ptr->nwords >= sizeof (struct bb) 1606 && ptr->nwords <= 1000 1607 && ptr->functions); 1608 int line_p = (func_p && ptr->line_nums); 1609 int file_p = (func_p && ptr->filenames); 1610 int addr_p = (ptr->addresses != 0); 1611 long ncounts = ptr->ncounts; 1612 long cnt_max = 0; 1613 long line_max = 0; 1614 long addr_max = 0; 1615 int file_len = 0; 1616 int func_len = 0; 1617 int blk_len = num_digits (ncounts, 10); 1618 int cnt_len; 1619 int line_len; 1620 int addr_len; 1621 1622 fprintf (file, "File %s, %ld basic blocks \n\n", 1623 ptr->filename, ncounts); 1624 1625 /* Get max values for each field. */ 1626 for (i = 0; i < ncounts; i++) 1627 { 1628 const char *p; 1629 int len; 1630 1631 if (cnt_max < ptr->counts[i]) 1632 cnt_max = ptr->counts[i]; 1633 1634 if (addr_p && addr_max < ptr->addresses[i]) 1635 addr_max = ptr->addresses[i]; 1636 1637 if (line_p && line_max < ptr->line_nums[i]) 1638 line_max = ptr->line_nums[i]; 1639 1640 if (func_p) 1641 { 1642 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>"; 1643 len = strlen (p); 1644 if (func_len < len) 1645 func_len = len; 1646 } 1647 1648 if (file_p) 1649 { 1650 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>"; 1651 len = strlen (p); 1652 if (file_len < len) 1653 file_len = len; 1654 } 1655 } 1656 1657 addr_len = num_digits (addr_max, 16); 1658 cnt_len = num_digits (cnt_max, 10); 1659 line_len = num_digits (line_max, 10); 1660 1661 /* Now print out the basic block information. */ 1662 for (i = 0; i < ncounts; i++) 1663 { 1664 fprintf (file, 1665 " Block #%*d: executed %*ld time(s)", 1666 blk_len, i+1, 1667 cnt_len, ptr->counts[i]); 1668 1669 if (addr_p) 1670 fprintf (file, " address= 0x%.*lx", addr_len, 1671 ptr->addresses[i]); 1672 1673 if (func_p) 1674 fprintf (file, " function= %-*s", func_len, 1675 (ptr->functions[i]) ? ptr->functions[i] : "<none>"); 1676 1677 if (line_p) 1678 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]); 1679 1680 if (file_p) 1681 fprintf (file, " file= %s", 1682 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>"); 1683 1684 fprintf (file, "\n"); 1685 } 1686 1687 fprintf (file, "\n"); 1688 fflush (file); 1689 } 1690 1691 fprintf (file, "\n\n"); 1692 fclose (file); 1693 } 1694} 1695 1696void 1697__bb_init_func (struct bb *blocks) 1698{ 1699 /* User is supposed to check whether the first word is non-0, 1700 but just in case.... */ 1701 1702 if (blocks->zero_word) 1703 return; 1704 1705#ifdef ON_EXIT 1706 /* Initialize destructor. */ 1707 if (!bb_head) 1708 ON_EXIT (__bb_exit_func, 0); 1709#endif 1710 1711 /* Set up linked list. */ 1712 blocks->zero_word = 1; 1713 blocks->next = bb_head; 1714 bb_head = blocks; 1715} 1716 1717#ifndef MACHINE_STATE_SAVE 1718#define MACHINE_STATE_SAVE(ID) 1719#endif 1720#ifndef MACHINE_STATE_RESTORE 1721#define MACHINE_STATE_RESTORE(ID) 1722#endif 1723 1724/* Number of buckets in hashtable of basic block addresses. */ 1725 1726#define BB_BUCKETS 311 1727 1728/* Maximum length of string in file bb.in. */ 1729 1730#define BBINBUFSIZE 500 1731 1732/* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or 1733 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */ 1734 1735#define BBINBUFSIZESTR "499" 1736 1737struct bb_edge 1738{ 1739 struct bb_edge *next; 1740 unsigned long src_addr; 1741 unsigned long dst_addr; 1742 unsigned long count; 1743}; 1744 1745enum bb_func_mode 1746{ 1747 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2 1748}; 1749 1750struct bb_func 1751{ 1752 struct bb_func *next; 1753 char *funcname; 1754 char *filename; 1755 enum bb_func_mode mode; 1756}; 1757 1758/* This is the connection to the outside world. 1759 The BLOCK_PROFILER macro must set __bb.blocks 1760 and __bb.blockno. */ 1761 1762struct { 1763 unsigned long blockno; 1764 struct bb *blocks; 1765} __bb; 1766 1767/* Vars to store addrs of source and destination basic blocks 1768 of a jump. */ 1769 1770static unsigned long bb_src = 0; 1771static unsigned long bb_dst = 0; 1772 1773static FILE *bb_tracefile = (FILE *) 0; 1774static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0; 1775static struct bb_func *bb_func_head = (struct bb_func *) 0; 1776static unsigned long bb_callcount = 0; 1777static int bb_mode = 0; 1778 1779static unsigned long *bb_stack = (unsigned long *) 0; 1780static size_t bb_stacksize = 0; 1781 1782static int reported = 0; 1783 1784/* Trace modes: 1785Always : Print execution frequencies of basic blocks 1786 to file bb.out. 1787bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz] 1788bb_mode & 2 != 0 : Print jump frequencies to file bb.out. 1789bb_mode & 4 != 0 : Cut call instructions from basic block flow. 1790bb_mode & 8 != 0 : Insert return instructions in basic block flow. 1791*/ 1792 1793#ifdef HAVE_POPEN 1794 1795/*#include <sys/types.h>*/ 1796#include <sys/stat.h> 1797/*#include <malloc.h>*/ 1798 1799/* Commands executed by gopen. */ 1800 1801#define GOPENDECOMPRESS "gzip -cd " 1802#define GOPENCOMPRESS "gzip -c >" 1803 1804/* Like fopen but pipes through gzip. mode may only be "r" or "w". 1805 If it does not compile, simply replace gopen by fopen and delete 1806 '.gz' from any first parameter to gopen. */ 1807 1808static FILE * 1809gopen (char *fn, char *mode) 1810{ 1811 int use_gzip; 1812 char *p; 1813 1814 if (mode[1]) 1815 return (FILE *) 0; 1816 1817 if (mode[0] != 'r' && mode[0] != 'w') 1818 return (FILE *) 0; 1819 1820 p = fn + strlen (fn)-1; 1821 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) 1822 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z')); 1823 1824 if (use_gzip) 1825 { 1826 if (mode[0]=='r') 1827 { 1828 FILE *f; 1829 char *s = (char *) malloc (sizeof (char) * strlen (fn) 1830 + sizeof (GOPENDECOMPRESS)); 1831 strcpy (s, GOPENDECOMPRESS); 1832 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn); 1833 f = popen (s, mode); 1834 free (s); 1835 return f; 1836 } 1837 1838 else 1839 { 1840 FILE *f; 1841 char *s = (char *) malloc (sizeof (char) * strlen (fn) 1842 + sizeof (GOPENCOMPRESS)); 1843 strcpy (s, GOPENCOMPRESS); 1844 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn); 1845 if (!(f = popen (s, mode))) 1846 f = fopen (s, mode); 1847 free (s); 1848 return f; 1849 } 1850 } 1851 1852 else 1853 return fopen (fn, mode); 1854} 1855 1856static int 1857gclose (FILE *f) 1858{ 1859 struct stat buf; 1860 1861 if (f != 0) 1862 { 1863 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode)) 1864 return pclose (f); 1865 1866 return fclose (f); 1867 } 1868 return 0; 1869} 1870 1871#endif /* HAVE_POPEN */ 1872 1873/* Called once per program. */ 1874 1875static void 1876__bb_exit_trace_func () 1877{ 1878 FILE *file = fopen ("bb.out", "a"); 1879 struct bb_func *f; 1880 struct bb *b; 1881 1882 if (!file) 1883 perror ("bb.out"); 1884 1885 if (bb_mode & 1) 1886 { 1887 if (!bb_tracefile) 1888 perror ("bbtrace"); 1889 else 1890#ifdef HAVE_POPEN 1891 gclose (bb_tracefile); 1892#else 1893 fclose (bb_tracefile); 1894#endif /* HAVE_POPEN */ 1895 } 1896 1897 /* Check functions in `bb.in'. */ 1898 1899 if (file) 1900 { 1901 long time_value; 1902 const struct bb_func *p; 1903 int printed_something = 0; 1904 struct bb *ptr; 1905 long blk; 1906 1907 /* This is somewhat type incorrect. */ 1908 time ((void *) &time_value); 1909 1910 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next) 1911 { 1912 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) 1913 { 1914 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))) 1915 continue; 1916 for (blk = 0; blk < ptr->ncounts; blk++) 1917 { 1918 if (!strcmp (p->funcname, ptr->functions[blk])) 1919 goto found; 1920 } 1921 } 1922 1923 if (!printed_something) 1924 { 1925 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value)); 1926 printed_something = 1; 1927 } 1928 1929 fprintf (file, "\tFunction %s", p->funcname); 1930 if (p->filename) 1931 fprintf (file, " of file %s", p->filename); 1932 fprintf (file, "\n" ); 1933 1934found: ; 1935 } 1936 1937 if (printed_something) 1938 fprintf (file, "\n"); 1939 1940 } 1941 1942 if (bb_mode & 2) 1943 { 1944 if (!bb_hashbuckets) 1945 { 1946 if (!reported) 1947 { 1948 fprintf (stderr, "Profiler: out of memory\n"); 1949 reported = 1; 1950 } 1951 return; 1952 } 1953 1954 else if (file) 1955 { 1956 long time_value; 1957 int i; 1958 unsigned long addr_max = 0; 1959 unsigned long cnt_max = 0; 1960 int cnt_len; 1961 int addr_len; 1962 1963 /* This is somewhat type incorrect, but it avoids worrying about 1964 exactly where time.h is included from. It should be ok unless 1965 a void * differs from other pointer formats, or if sizeof (long) 1966 is < sizeof (time_t). It would be nice if we could assume the 1967 use of rationale standards here. */ 1968 1969 time ((void *) &time_value); 1970 fprintf (file, "Basic block jump tracing"); 1971 1972 switch (bb_mode & 12) 1973 { 1974 case 0: 1975 fprintf (file, " (with call)"); 1976 break; 1977 1978 case 4: 1979 /* Print nothing. */ 1980 break; 1981 1982 case 8: 1983 fprintf (file, " (with call & ret)"); 1984 break; 1985 1986 case 12: 1987 fprintf (file, " (with ret)"); 1988 break; 1989 } 1990 1991 fprintf (file, " finished on %s\n", ctime ((void *) &time_value)); 1992 1993 for (i = 0; i < BB_BUCKETS; i++) 1994 { 1995 struct bb_edge *bucket = bb_hashbuckets[i]; 1996 for ( ; bucket; bucket = bucket->next ) 1997 { 1998 if (addr_max < bucket->src_addr) 1999 addr_max = bucket->src_addr; 2000 if (addr_max < bucket->dst_addr) 2001 addr_max = bucket->dst_addr; 2002 if (cnt_max < bucket->count) 2003 cnt_max = bucket->count; 2004 } 2005 } 2006 addr_len = num_digits (addr_max, 16); 2007 cnt_len = num_digits (cnt_max, 10); 2008 2009 for ( i = 0; i < BB_BUCKETS; i++) 2010 { 2011 struct bb_edge *bucket = bb_hashbuckets[i]; 2012 for ( ; bucket; bucket = bucket->next ) 2013 { 2014 fprintf (file, "Jump from block 0x%.*lx to " 2015 "block 0x%.*lx executed %*lu time(s)\n", 2016 addr_len, bucket->src_addr, 2017 addr_len, bucket->dst_addr, 2018 cnt_len, bucket->count); 2019 } 2020 } 2021 2022 fprintf (file, "\n"); 2023 2024 } 2025 } 2026 2027 if (file) 2028 fclose (file); 2029 2030 /* Free allocated memory. */ 2031 2032 f = bb_func_head; 2033 while (f) 2034 { 2035 struct bb_func *old = f; 2036 2037 f = f->next; 2038 if (old->funcname) free (old->funcname); 2039 if (old->filename) free (old->filename); 2040 free (old); 2041 } 2042 2043 if (bb_stack) 2044 free (bb_stack); 2045 2046 if (bb_hashbuckets) 2047 { 2048 int i; 2049 2050 for (i = 0; i < BB_BUCKETS; i++) 2051 { 2052 struct bb_edge *old, *bucket = bb_hashbuckets[i]; 2053 2054 while (bucket) 2055 { 2056 old = bucket; 2057 bucket = bucket->next; 2058 free (old); 2059 } 2060 } 2061 free (bb_hashbuckets); 2062 } 2063 2064 for (b = bb_head; b; b = b->next) 2065 if (b->flags) free (b->flags); 2066} 2067 2068/* Called once per program. */ 2069 2070static void 2071__bb_init_prg () 2072{ 2073 2074 FILE *file; 2075 char buf[BBINBUFSIZE]; 2076 const char *p; 2077 const char *pos; 2078 enum bb_func_mode m; 2079 2080#ifdef ON_EXIT 2081 /* Initialize destructor. */ 2082 ON_EXIT (__bb_exit_func, 0); 2083#endif 2084 2085 if (!(file = fopen ("bb.in", "r"))) 2086 return; 2087 2088 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF) 2089 { 2090 p = buf; 2091 if (*p == '-') 2092 { 2093 m = TRACE_OFF; 2094 p++; 2095 } 2096 else 2097 { 2098 m = TRACE_ON; 2099 } 2100 if (!strcmp (p, "__bb_trace__")) 2101 bb_mode |= 1; 2102 else if (!strcmp (p, "__bb_jumps__")) 2103 bb_mode |= 2; 2104 else if (!strcmp (p, "__bb_hidecall__")) 2105 bb_mode |= 4; 2106 else if (!strcmp (p, "__bb_showret__")) 2107 bb_mode |= 8; 2108 else 2109 { 2110 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func)); 2111 if (f) 2112 { 2113 unsigned long l; 2114 f->next = bb_func_head; 2115 if ((pos = strchr (p, ':'))) 2116 { 2117 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1))) 2118 continue; 2119 strcpy (f->funcname, pos+1); 2120 l = pos-p; 2121 if ((f->filename = (char *) malloc (l+1))) 2122 { 2123 strncpy (f->filename, p, l); 2124 f->filename[l] = '\0'; 2125 } 2126 else 2127 f->filename = (char *) 0; 2128 } 2129 else 2130 { 2131 if (!(f->funcname = (char *) malloc (strlen (p)+1))) 2132 continue; 2133 strcpy (f->funcname, p); 2134 f->filename = (char *) 0; 2135 } 2136 f->mode = m; 2137 bb_func_head = f; 2138 } 2139 } 2140 } 2141 fclose (file); 2142 2143#ifdef HAVE_POPEN 2144 2145 if (bb_mode & 1) 2146 bb_tracefile = gopen ("bbtrace.gz", "w"); 2147 2148#else 2149 2150 if (bb_mode & 1) 2151 bb_tracefile = fopen ("bbtrace", "w"); 2152 2153#endif /* HAVE_POPEN */ 2154 2155 if (bb_mode & 2) 2156 { 2157 bb_hashbuckets = (struct bb_edge **) 2158 malloc (BB_BUCKETS * sizeof (struct bb_edge *)); 2159 if (bb_hashbuckets) 2160 memset (bb_hashbuckets, 0, BB_BUCKETS * sizeof (struct bb_edge *)); 2161 } 2162 2163 if (bb_mode & 12) 2164 { 2165 bb_stacksize = 10; 2166 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack)); 2167 } 2168 2169#ifdef ON_EXIT 2170 /* Initialize destructor. */ 2171 ON_EXIT (__bb_exit_trace_func, 0); 2172#endif 2173 2174} 2175 2176/* Called upon entering a basic block. */ 2177 2178void 2179__bb_trace_func () 2180{ 2181 struct bb_edge *bucket; 2182 2183 MACHINE_STATE_SAVE("1") 2184 2185 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF))) 2186 goto skip; 2187 2188 bb_dst = __bb.blocks->addresses[__bb.blockno]; 2189 __bb.blocks->counts[__bb.blockno]++; 2190 2191 if (bb_tracefile) 2192 { 2193 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile); 2194 } 2195 2196 if (bb_hashbuckets) 2197 { 2198 struct bb_edge **startbucket, **oldnext; 2199 2200 oldnext = startbucket 2201 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ]; 2202 bucket = *startbucket; 2203 2204 for (bucket = *startbucket; bucket; 2205 oldnext = &(bucket->next), bucket = *oldnext) 2206 { 2207 if (bucket->src_addr == bb_src 2208 && bucket->dst_addr == bb_dst) 2209 { 2210 bucket->count++; 2211 *oldnext = bucket->next; 2212 bucket->next = *startbucket; 2213 *startbucket = bucket; 2214 goto ret; 2215 } 2216 } 2217 2218 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge)); 2219 2220 if (!bucket) 2221 { 2222 if (!reported) 2223 { 2224 fprintf (stderr, "Profiler: out of memory\n"); 2225 reported = 1; 2226 } 2227 } 2228 2229 else 2230 { 2231 bucket->src_addr = bb_src; 2232 bucket->dst_addr = bb_dst; 2233 bucket->next = *startbucket; 2234 *startbucket = bucket; 2235 bucket->count = 1; 2236 } 2237 } 2238 2239ret: 2240 bb_src = bb_dst; 2241 2242skip: 2243 ; 2244 2245 MACHINE_STATE_RESTORE("1") 2246 2247} 2248 2249/* Called when returning from a function and `__bb_showret__' is set. */ 2250 2251static void 2252__bb_trace_func_ret () 2253{ 2254 struct bb_edge *bucket; 2255 2256 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF))) 2257 goto skip; 2258 2259 if (bb_hashbuckets) 2260 { 2261 struct bb_edge **startbucket, **oldnext; 2262 2263 oldnext = startbucket 2264 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ]; 2265 bucket = *startbucket; 2266 2267 for (bucket = *startbucket; bucket; 2268 oldnext = &(bucket->next), bucket = *oldnext) 2269 { 2270 if (bucket->src_addr == bb_dst 2271 && bucket->dst_addr == bb_src) 2272 { 2273 bucket->count++; 2274 *oldnext = bucket->next; 2275 bucket->next = *startbucket; 2276 *startbucket = bucket; 2277 goto ret; 2278 } 2279 } 2280 2281 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge)); 2282 2283 if (!bucket) 2284 { 2285 if (!reported) 2286 { 2287 fprintf (stderr, "Profiler: out of memory\n"); 2288 reported = 1; 2289 } 2290 } 2291 2292 else 2293 { 2294 bucket->src_addr = bb_dst; 2295 bucket->dst_addr = bb_src; 2296 bucket->next = *startbucket; 2297 *startbucket = bucket; 2298 bucket->count = 1; 2299 } 2300 } 2301 2302ret: 2303 bb_dst = bb_src; 2304 2305skip: 2306 ; 2307 2308} 2309 2310/* Called upon entering the first function of a file. */ 2311 2312static void 2313__bb_init_file (struct bb *blocks) 2314{ 2315 2316 const struct bb_func *p; 2317 long blk, ncounts = blocks->ncounts; 2318 const char **functions = blocks->functions; 2319 2320 /* Set up linked list. */ 2321 blocks->zero_word = 1; 2322 blocks->next = bb_head; 2323 bb_head = blocks; 2324 2325 blocks->flags = 0; 2326 if (!bb_func_head 2327 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts))) 2328 return; 2329 2330 for (blk = 0; blk < ncounts; blk++) 2331 blocks->flags[blk] = 0; 2332 2333 for (blk = 0; blk < ncounts; blk++) 2334 { 2335 for (p = bb_func_head; p; p = p->next) 2336 { 2337 if (!strcmp (p->funcname, functions[blk]) 2338 && (!p->filename || !strcmp (p->filename, blocks->filename))) 2339 { 2340 blocks->flags[blk] |= p->mode; 2341 } 2342 } 2343 } 2344 2345} 2346 2347/* Called when exiting from a function. */ 2348 2349void 2350__bb_trace_ret () 2351{ 2352 2353 MACHINE_STATE_SAVE("2") 2354 2355 if (bb_callcount) 2356 { 2357 if ((bb_mode & 12) && bb_stacksize > bb_callcount) 2358 { 2359 bb_src = bb_stack[bb_callcount]; 2360 if (bb_mode & 8) 2361 __bb_trace_func_ret (); 2362 } 2363 2364 bb_callcount -= 1; 2365 } 2366 2367 MACHINE_STATE_RESTORE("2") 2368 2369} 2370 2371/* Called when entering a function. */ 2372 2373void 2374__bb_init_trace_func (struct bb *blocks, unsigned long blockno) 2375{ 2376 static int trace_init = 0; 2377 2378 MACHINE_STATE_SAVE("3") 2379 2380 if (!blocks->zero_word) 2381 { 2382 if (!trace_init) 2383 { 2384 trace_init = 1; 2385 __bb_init_prg (); 2386 } 2387 __bb_init_file (blocks); 2388 } 2389 2390 if (bb_callcount) 2391 { 2392 2393 bb_callcount += 1; 2394 2395 if (bb_mode & 12) 2396 { 2397 if (bb_callcount >= bb_stacksize) 2398 { 2399 size_t newsize = bb_callcount + 100; 2400 2401 bb_stack = (unsigned long *) realloc (bb_stack, newsize); 2402 if (! bb_stack) 2403 { 2404 if (!reported) 2405 { 2406 fprintf (stderr, "Profiler: out of memory\n"); 2407 reported = 1; 2408 } 2409 bb_stacksize = 0; 2410 goto stack_overflow; 2411 } 2412 bb_stacksize = newsize; 2413 } 2414 bb_stack[bb_callcount] = bb_src; 2415 2416 if (bb_mode & 4) 2417 bb_src = 0; 2418 2419 } 2420 2421stack_overflow:; 2422 2423 } 2424 2425 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON)) 2426 { 2427 bb_callcount = 1; 2428 bb_src = 0; 2429 2430 if (bb_stack) 2431 bb_stack[bb_callcount] = bb_src; 2432 } 2433 2434 MACHINE_STATE_RESTORE("3") 2435} 2436 2437#endif /* not inhibit_libc */ 2438#endif /* not BLOCK_PROFILER_CODE */ 2439#endif /* L_bb */ 2440 2441#ifdef L_shtab 2442unsigned int __shtab[] = { 2443 0x00000001, 0x00000002, 0x00000004, 0x00000008, 2444 0x00000010, 0x00000020, 0x00000040, 0x00000080, 2445 0x00000100, 0x00000200, 0x00000400, 0x00000800, 2446 0x00001000, 0x00002000, 0x00004000, 0x00008000, 2447 0x00010000, 0x00020000, 0x00040000, 0x00080000, 2448 0x00100000, 0x00200000, 0x00400000, 0x00800000, 2449 0x01000000, 0x02000000, 0x04000000, 0x08000000, 2450 0x10000000, 0x20000000, 0x40000000, 0x80000000 2451 }; 2452#endif 2453 2454#ifdef L_clear_cache 2455/* Clear part of an instruction cache. */ 2456 2457#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH) 2458 2459void 2460__clear_cache (char *beg, char *end) 2461{ 2462#ifdef CLEAR_INSN_CACHE 2463 CLEAR_INSN_CACHE (beg, end); 2464#else 2465#ifdef INSN_CACHE_SIZE 2466 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH]; 2467 static int initialized; 2468 int offset; 2469 void *start_addr 2470 void *end_addr; 2471 typedef (*function_ptr) (); 2472 2473#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16 2474 /* It's cheaper to clear the whole cache. 2475 Put in a series of jump instructions so that calling the beginning 2476 of the cache will clear the whole thing. */ 2477 2478 if (! initialized) 2479 { 2480 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 2481 & -INSN_CACHE_LINE_WIDTH); 2482 int end_ptr = ptr + INSN_CACHE_SIZE; 2483 2484 while (ptr < end_ptr) 2485 { 2486 *(INSTRUCTION_TYPE *)ptr 2487 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH; 2488 ptr += INSN_CACHE_LINE_WIDTH; 2489 } 2490 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION; 2491 2492 initialized = 1; 2493 } 2494 2495 /* Call the beginning of the sequence. */ 2496 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1) 2497 & -INSN_CACHE_LINE_WIDTH)) 2498 ()); 2499 2500#else /* Cache is large. */ 2501 2502 if (! initialized) 2503 { 2504 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 2505 & -INSN_CACHE_LINE_WIDTH); 2506 2507 while (ptr < (int) array + sizeof array) 2508 { 2509 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION; 2510 ptr += INSN_CACHE_LINE_WIDTH; 2511 } 2512 2513 initialized = 1; 2514 } 2515 2516 /* Find the location in array that occupies the same cache line as BEG. */ 2517 2518 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1); 2519 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1) 2520 & -INSN_CACHE_PLANE_SIZE) 2521 + offset); 2522 2523 /* Compute the cache alignment of the place to stop clearing. */ 2524#if 0 /* This is not needed for gcc's purposes. */ 2525 /* If the block to clear is bigger than a cache plane, 2526 we clear the entire cache, and OFFSET is already correct. */ 2527 if (end < beg + INSN_CACHE_PLANE_SIZE) 2528#endif 2529 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1) 2530 & -INSN_CACHE_LINE_WIDTH) 2531 & (INSN_CACHE_PLANE_SIZE - 1)); 2532 2533#if INSN_CACHE_DEPTH > 1 2534 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset; 2535 if (end_addr <= start_addr) 2536 end_addr += INSN_CACHE_PLANE_SIZE; 2537 2538 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++) 2539 { 2540 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE; 2541 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE; 2542 2543 while (addr != stop) 2544 { 2545 /* Call the return instruction at ADDR. */ 2546 ((function_ptr) addr) (); 2547 2548 addr += INSN_CACHE_LINE_WIDTH; 2549 } 2550 } 2551#else /* just one plane */ 2552 do 2553 { 2554 /* Call the return instruction at START_ADDR. */ 2555 ((function_ptr) start_addr) (); 2556 2557 start_addr += INSN_CACHE_LINE_WIDTH; 2558 } 2559 while ((start_addr % INSN_CACHE_SIZE) != offset); 2560#endif /* just one plane */ 2561#endif /* Cache is large */ 2562#endif /* Cache exists */ 2563#endif /* CLEAR_INSN_CACHE */ 2564} 2565 2566#endif /* L_clear_cache */ 2567 2568#ifdef L_trampoline 2569 2570/* Jump to a trampoline, loading the static chain address. */ 2571 2572#if defined(WINNT) && ! defined(__CYGWIN32__) 2573 2574long getpagesize() 2575{ 2576#ifdef _ALPHA_ 2577 return 8192; 2578#else 2579 return 4096; 2580#endif 2581} 2582 2583#ifdef i386 2584extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); 2585#endif 2586 2587int 2588mprotect (char *addr, int len, int prot) 2589{ 2590 int np, op; 2591 2592 if (prot == 7) 2593 np = 0x40; 2594 else if (prot == 5) 2595 np = 0x20; 2596 else if (prot == 4) 2597 np = 0x10; 2598 else if (prot == 3) 2599 np = 0x04; 2600 else if (prot == 1) 2601 np = 0x02; 2602 else if (prot == 0) 2603 np = 0x01; 2604 2605 if (VirtualProtect (addr, len, np, &op)) 2606 return 0; 2607 else 2608 return -1; 2609} 2610 2611#endif 2612 2613#ifdef TRANSFER_FROM_TRAMPOLINE 2614TRANSFER_FROM_TRAMPOLINE 2615#endif 2616 2617#if defined (NeXT) && defined (__MACH__) 2618 2619/* Make stack executable so we can call trampolines on stack. 2620 This is called from INITIALIZE_TRAMPOLINE in next.h. */ 2621#ifdef NeXTStep21 2622 #include <mach.h> 2623#else 2624 #include <mach/mach.h> 2625#endif 2626 2627void 2628__enable_execute_stack (char *addr) 2629{ 2630 kern_return_t r; 2631 char *eaddr = addr + TRAMPOLINE_SIZE; 2632 vm_address_t a = (vm_address_t) addr; 2633 2634 /* turn on execute access on stack */ 2635 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL); 2636 if (r != KERN_SUCCESS) 2637 { 2638 mach_error("vm_protect VM_PROT_ALL", r); 2639 exit(1); 2640 } 2641 2642 /* We inline the i-cache invalidation for speed */ 2643 2644#ifdef CLEAR_INSN_CACHE 2645 CLEAR_INSN_CACHE (addr, eaddr); 2646#else 2647 __clear_cache ((int) addr, (int) eaddr); 2648#endif 2649} 2650 2651#endif /* defined (NeXT) && defined (__MACH__) */ 2652 2653#ifdef __convex__ 2654 2655/* Make stack executable so we can call trampolines on stack. 2656 This is called from INITIALIZE_TRAMPOLINE in convex.h. */ 2657 2658#include <sys/mman.h> 2659#include <sys/vmparam.h> 2660#include <machine/machparam.h> 2661 2662void 2663__enable_execute_stack () 2664{ 2665 int fp; 2666 static unsigned lowest = USRSTACK; 2667 unsigned current = (unsigned) &fp & -NBPG; 2668 2669 if (lowest > current) 2670 { 2671 unsigned len = lowest - current; 2672 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); 2673 lowest = current; 2674 } 2675 2676 /* Clear instruction cache in case an old trampoline is in it. */ 2677 asm ("pich"); 2678} 2679#endif /* __convex__ */ 2680 2681#ifdef __sysV88__ 2682 2683/* Modified from the convex -code above. */ 2684 2685#include <sys/param.h> 2686#include <errno.h> 2687#include <sys/m88kbcs.h> 2688 2689void 2690__enable_execute_stack () 2691{ 2692 int save_errno; 2693 static unsigned long lowest = USRSTACK; 2694 unsigned long current = (unsigned long) &save_errno & -NBPC; 2695 2696 /* Ignore errno being set. memctl sets errno to EINVAL whenever the 2697 address is seen as 'negative'. That is the case with the stack. */ 2698 2699 save_errno=errno; 2700 if (lowest > current) 2701 { 2702 unsigned len=lowest-current; 2703 memctl(current,len,MCT_TEXT); 2704 lowest = current; 2705 } 2706 else 2707 memctl(current,NBPC,MCT_TEXT); 2708 errno=save_errno; 2709} 2710 2711#endif /* __sysV88__ */ 2712 2713#ifdef __sysV68__ 2714 2715#include <sys/signal.h> 2716#include <errno.h> 2717 2718/* Motorola forgot to put memctl.o in the libp version of libc881.a, 2719 so define it here, because we need it in __clear_insn_cache below */ 2720/* On older versions of this OS, no memctl or MCT_TEXT are defined; 2721 hence we enable this stuff only if MCT_TEXT is #define'd. */ 2722 2723#ifdef MCT_TEXT 2724asm("\n\ 2725 global memctl\n\ 2726memctl:\n\ 2727 movq &75,%d0\n\ 2728 trap &0\n\ 2729 bcc.b noerror\n\ 2730 jmp cerror%\n\ 2731noerror:\n\ 2732 movq &0,%d0\n\ 2733 rts"); 2734#endif 2735 2736/* Clear instruction cache so we can call trampolines on stack. 2737 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */ 2738 2739void 2740__clear_insn_cache () 2741{ 2742#ifdef MCT_TEXT 2743 int save_errno; 2744 2745 /* Preserve errno, because users would be surprised to have 2746 errno changing without explicitly calling any system-call. */ 2747 save_errno = errno; 2748 2749 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 2750 No need to use an address derived from _start or %sp, as 0 works also. */ 2751 memctl(0, 4096, MCT_TEXT); 2752 errno = save_errno; 2753#endif 2754} 2755 2756#endif /* __sysV68__ */ 2757 2758#ifdef __pyr__ 2759 2760#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 2761#include <stdio.h> 2762#include <sys/mman.h> 2763#include <sys/types.h> 2764#include <sys/param.h> 2765#include <sys/vmmac.h> 2766 2767/* Modified from the convex -code above. 2768 mremap promises to clear the i-cache. */ 2769 2770void 2771__enable_execute_stack () 2772{ 2773 int fp; 2774 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ, 2775 PROT_READ|PROT_WRITE|PROT_EXEC)) 2776 { 2777 perror ("mprotect in __enable_execute_stack"); 2778 fflush (stderr); 2779 abort (); 2780 } 2781} 2782#endif /* __pyr__ */ 2783 2784#if defined (sony_news) && defined (SYSTYPE_BSD) 2785 2786#include <stdio.h> 2787#include <sys/types.h> 2788#include <sys/param.h> 2789#include <syscall.h> 2790#include <machine/sysnews.h> 2791 2792/* cacheflush function for NEWS-OS 4.2. 2793 This function is called from trampoline-initialize code 2794 defined in config/mips/mips.h. */ 2795 2796void 2797cacheflush (char *beg, int size, int flag) 2798{ 2799 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE)) 2800 { 2801 perror ("cache_flush"); 2802 fflush (stderr); 2803 abort (); 2804 } 2805} 2806 2807#endif /* sony_news */ 2808#endif /* L_trampoline */ 2809 2810#ifndef __CYGWIN32__ 2811#ifdef L__main 2812 2813#include "gbl-ctors.h" 2814/* Some systems use __main in a way incompatible with its use in gcc, in these 2815 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 2816 give the same symbol without quotes for an alternative entry point. You 2817 must define both, or neither. */ 2818#ifndef NAME__MAIN 2819#define NAME__MAIN "__main" 2820#define SYMBOL__MAIN __main 2821#endif 2822 2823#ifdef INIT_SECTION_ASM_OP 2824#undef HAS_INIT_SECTION 2825#define HAS_INIT_SECTION 2826#endif 2827 2828#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) 2829/* Run all the global destructors on exit from the program. */ 2830 2831void 2832__do_global_dtors () 2833{ 2834#ifdef DO_GLOBAL_DTORS_BODY 2835 DO_GLOBAL_DTORS_BODY; 2836#else 2837 static func_ptr *p = __DTOR_LIST__ + 1; 2838 while (*p) 2839 { 2840 p++; 2841 (*(p-1)) (); 2842 } 2843#endif 2844} 2845#endif 2846 2847#ifndef HAS_INIT_SECTION 2848/* Run all the global constructors on entry to the program. */ 2849 2850#ifndef ON_EXIT 2851#define ON_EXIT(a, b) 2852#else 2853/* Make sure the exit routine is pulled in to define the globals as 2854 bss symbols, just in case the linker does not automatically pull 2855 bss definitions from the library. */ 2856 2857extern int _exit_dummy_decl; 2858int *_exit_dummy_ref = &_exit_dummy_decl; 2859#endif /* ON_EXIT */ 2860 2861void 2862__do_global_ctors () 2863{ 2864 DO_GLOBAL_CTORS_BODY; 2865 ON_EXIT (__do_global_dtors, 0); 2866} 2867#endif /* no HAS_INIT_SECTION */ 2868 2869#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) 2870/* Subroutine called automatically by `main'. 2871 Compiling a global function named `main' 2872 produces an automatic call to this function at the beginning. 2873 2874 For many systems, this routine calls __do_global_ctors. 2875 For systems which support a .init section we use the .init section 2876 to run __do_global_ctors, so we need not do anything here. */ 2877 2878void 2879SYMBOL__MAIN () 2880{ 2881 /* Support recursive calls to `main': run initializers just once. */ 2882 static int initialized; 2883 if (! initialized) 2884 { 2885 initialized = 1; 2886 __do_global_ctors (); 2887 } 2888} 2889#endif /* no HAS_INIT_SECTION or INVOKE__main */ 2890 2891#endif /* L__main */ 2892#endif /* __CYGWIN32__ */ 2893 2894#ifdef L_ctors 2895 2896#include "gbl-ctors.h" 2897 2898/* Provide default definitions for the lists of constructors and 2899 destructors, so that we don't get linker errors. These symbols are 2900 intentionally bss symbols, so that gld and/or collect will provide 2901 the right values. */ 2902 2903/* We declare the lists here with two elements each, 2904 so that they are valid empty lists if no other definition is loaded. */ 2905#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 2906#if defined(__NeXT__) || defined(_AIX) 2907/* After 2.3, try this definition on all systems. */ 2908func_ptr __CTOR_LIST__[2] = {0, 0}; 2909func_ptr __DTOR_LIST__[2] = {0, 0}; 2910#else 2911func_ptr __CTOR_LIST__[2]; 2912func_ptr __DTOR_LIST__[2]; 2913#endif 2914#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 2915#endif /* L_ctors */ 2916 2917#ifdef L_exit 2918 2919#include "gbl-ctors.h" 2920 2921#ifdef NEED_ATEXIT 2922# ifdef ON_EXIT 2923# undef ON_EXIT 2924# endif 2925int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ 2926#endif 2927 2928#ifndef ON_EXIT 2929 2930#ifdef NEED_ATEXIT 2931# include <errno.h> 2932 2933static func_ptr *atexit_chain = 0; 2934static long atexit_chain_length = 0; 2935static volatile long last_atexit_chain_slot = -1; 2936 2937int atexit (func_ptr func) 2938{ 2939 if (++last_atexit_chain_slot == atexit_chain_length) 2940 { 2941 atexit_chain_length += 32; 2942 if (atexit_chain) 2943 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length 2944 * sizeof (func_ptr)); 2945 else 2946 atexit_chain = (func_ptr *) malloc (atexit_chain_length 2947 * sizeof (func_ptr)); 2948 if (! atexit_chain) 2949 { 2950 atexit_chain_length = 0; 2951 last_atexit_chain_slot = -1; 2952 errno = ENOMEM; 2953 return (-1); 2954 } 2955 } 2956 atexit_chain[last_atexit_chain_slot] = func; 2957 return (0); 2958} 2959#endif /* NEED_ATEXIT */ 2960 2961/* If we have no known way of registering our own __do_global_dtors 2962 routine so that it will be invoked at program exit time, then we 2963 have to define our own exit routine which will get this to happen. */ 2964 2965extern void __do_global_dtors (); 2966extern void __bb_exit_func (); 2967extern void _cleanup (); 2968extern void _exit () __attribute__ ((noreturn)); 2969 2970void 2971exit (int status) 2972{ 2973#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) 2974#ifdef NEED_ATEXIT 2975 if (atexit_chain) 2976 { 2977 for ( ; last_atexit_chain_slot-- >= 0; ) 2978 { 2979 (*atexit_chain[last_atexit_chain_slot + 1]) (); 2980 atexit_chain[last_atexit_chain_slot + 1] = 0; 2981 } 2982 free (atexit_chain); 2983 atexit_chain = 0; 2984 } 2985#else /* No NEED_ATEXIT */ 2986 __do_global_dtors (); 2987#endif /* No NEED_ATEXIT */ 2988#endif /* !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) */ 2989/* In gbl-ctors.h, ON_EXIT is defined if HAVE_ATEXIT is defined. In 2990 __bb_init_func and _bb_init_prg, __bb_exit_func is registered with 2991 ON_EXIT if ON_EXIT is defined. Thus we must not call __bb_exit_func here 2992 if HAVE_ATEXIT is defined. */ 2993#ifndef HAVE_ATEXIT 2994#ifndef inhibit_libc 2995 __bb_exit_func (); 2996#endif 2997#endif /* !HAVE_ATEXIT */ 2998#ifdef EXIT_BODY 2999 EXIT_BODY; 3000#else 3001 _cleanup (); 3002#endif 3003 _exit (status); 3004} 3005 3006#else /* ON_EXIT defined */ 3007int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ 3008 3009# ifndef HAVE_ATEXIT 3010/* Provide a fake for atexit() using ON_EXIT. */ 3011int atexit (func_ptr func) 3012{ 3013 return ON_EXIT (func, NULL); 3014} 3015# endif /* HAVE_ATEXIT */ 3016#endif /* ON_EXIT defined */ 3017 3018#endif /* L_exit */ 3019 3020#ifdef L_eh 3021 3022#include "gthr.h" 3023 3024/* Shared exception handling support routines. */ 3025 3026void 3027__default_terminate () 3028{ 3029 abort (); 3030} 3031 3032void (*__terminate_func)() = __default_terminate; 3033 3034void 3035__terminate () 3036{ 3037 (*__terminate_func)(); 3038} 3039 3040void * 3041__throw_type_match (void *catch_type, void *throw_type, void *obj) 3042{ 3043#if 0 3044 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n", 3045 catch_type, throw_type); 3046#endif 3047 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0) 3048 return obj; 3049 return 0; 3050} 3051 3052void 3053__empty () 3054{ 3055} 3056 3057 3058/* Include definitions of EH context and table layout */ 3059 3060#include "eh-common.h" 3061 3062/* Allocate and return a new EH context structure. */ 3063 3064extern void __throw (); 3065 3066static void * 3067new_eh_context () 3068{ 3069 struct eh_full_context { 3070 struct eh_context c; 3071 void *top_elt[2]; 3072 } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc); 3073 3074 if (! ehfc) 3075 __terminate (); 3076 3077 memset (ehfc, 0, sizeof *ehfc); 3078 3079 ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt; 3080 3081 /* This should optimize out entirely. This should always be true, 3082 but just in case it ever isn't, don't allow bogus code to be 3083 generated. */ 3084 3085 if ((void*)(&ehfc->c) != (void*)ehfc) 3086 __terminate (); 3087 3088 return &ehfc->c; 3089} 3090 3091#if __GTHREADS 3092static __gthread_key_t eh_context_key; 3093 3094/* Destructor for struct eh_context. */ 3095static void 3096eh_context_free (void *ptr) 3097{ 3098 __gthread_key_dtor (eh_context_key, ptr); 3099 if (ptr) 3100 free (ptr); 3101} 3102#endif 3103 3104/* Pointer to function to return EH context. */ 3105 3106static struct eh_context *eh_context_initialize (); 3107static struct eh_context *eh_context_static (); 3108#if __GTHREADS 3109static struct eh_context *eh_context_specific (); 3110#endif 3111 3112static struct eh_context *(*get_eh_context) () = &eh_context_initialize; 3113 3114/* Routine to get EH context. 3115 This one will simply call the function pointer. */ 3116 3117void * 3118__get_eh_context () 3119{ 3120 return (void *) (*get_eh_context) (); 3121} 3122 3123/* Get and set the language specific info pointer. */ 3124 3125void ** 3126__get_eh_info () 3127{ 3128 struct eh_context *eh = (*get_eh_context) (); 3129 return &eh->info; 3130} 3131 3132#if __GTHREADS 3133static void 3134eh_threads_initialize () 3135{ 3136 /* Try to create the key. If it fails, revert to static method, 3137 otherwise start using thread specific EH contexts. */ 3138 if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0) 3139 get_eh_context = &eh_context_specific; 3140 else 3141 get_eh_context = &eh_context_static; 3142} 3143#endif /* no __GTHREADS */ 3144 3145/* Initialize EH context. 3146 This will be called only once, since we change GET_EH_CONTEXT 3147 pointer to another routine. */ 3148 3149static struct eh_context * 3150eh_context_initialize () 3151{ 3152#if __GTHREADS 3153 3154 static __gthread_once_t once = __GTHREAD_ONCE_INIT; 3155 /* Make sure that get_eh_context does not point to us anymore. 3156 Some systems have dummy thread routines in their libc that 3157 return a success (Solaris 2.6 for example). */ 3158 if (__gthread_once (&once, eh_threads_initialize) != 0 3159 || get_eh_context == &eh_context_initialize) 3160 { 3161 /* Use static version of EH context. */ 3162 get_eh_context = &eh_context_static; 3163 } 3164 3165#else /* no __GTHREADS */ 3166 3167 /* Use static version of EH context. */ 3168 get_eh_context = &eh_context_static; 3169 3170#endif /* no __GTHREADS */ 3171 3172 return (*get_eh_context) (); 3173} 3174 3175/* Return a static EH context. */ 3176 3177static struct eh_context * 3178eh_context_static () 3179{ 3180 static struct eh_context *eh; 3181 if (! eh) 3182 eh = new_eh_context (); 3183 return eh; 3184} 3185 3186#if __GTHREADS 3187/* Return a thread specific EH context. */ 3188 3189static struct eh_context * 3190eh_context_specific () 3191{ 3192 struct eh_context *eh; 3193 eh = (struct eh_context *) __gthread_getspecific (eh_context_key); 3194 if (! eh) 3195 { 3196 eh = new_eh_context (); 3197 if (__gthread_setspecific (eh_context_key, (void *) eh) != 0) 3198 __terminate (); 3199 } 3200 3201 return eh; 3202} 3203#endif __GTHREADS 3204 3205/* Support routines for setjmp/longjmp exception handling. */ 3206 3207/* Calls to __sjthrow are generated by the compiler when an exception 3208 is raised when using the setjmp/longjmp exception handling codegen 3209 method. */ 3210 3211#ifdef DONT_USE_BUILTIN_SETJMP 3212extern void longjmp (void *, int); 3213#endif 3214 3215/* Routine to get the head of the current thread's dynamic handler chain 3216 use for exception handling. */ 3217 3218void *** 3219__get_dynamic_handler_chain () 3220{ 3221 struct eh_context *eh = (*get_eh_context) (); 3222 return &eh->dynamic_handler_chain; 3223} 3224 3225/* This is used to throw an exception when the setjmp/longjmp codegen 3226 method is used for exception handling. 3227 3228 We call __terminate if there are no handlers left. Otherwise we run the 3229 cleanup actions off the dynamic cleanup stack, and pop the top of the 3230 dynamic handler chain, and use longjmp to transfer back to the associated 3231 handler. */ 3232 3233void 3234__sjthrow () 3235{ 3236 struct eh_context *eh = (*get_eh_context) (); 3237 void ***dhc = &eh->dynamic_handler_chain; 3238 void *jmpbuf; 3239 void (*func)(void *, int); 3240 void *arg; 3241 void ***cleanup; 3242 3243 /* The cleanup chain is one word into the buffer. Get the cleanup 3244 chain. */ 3245 cleanup = (void***)&(*dhc)[1]; 3246 3247 /* If there are any cleanups in the chain, run them now. */ 3248 if (cleanup[0]) 3249 { 3250 double store[200]; 3251 void **buf = (void**)store; 3252 buf[1] = 0; 3253 buf[0] = (*dhc); 3254 3255 /* try { */ 3256#ifdef DONT_USE_BUILTIN_SETJMP 3257 if (! setjmp (&buf[2])) 3258#else 3259 if (! __builtin_setjmp (&buf[2])) 3260#endif 3261 { 3262 *dhc = buf; 3263 while (cleanup[0]) 3264 { 3265 func = (void(*)(void*, int))cleanup[0][1]; 3266 arg = (void*)cleanup[0][2]; 3267 3268 /* Update this before running the cleanup. */ 3269 cleanup[0] = (void **)cleanup[0][0]; 3270 3271 (*func)(arg, 2); 3272 } 3273 *dhc = buf[0]; 3274 } 3275 /* catch (...) */ 3276 else 3277 { 3278 __terminate (); 3279 } 3280 } 3281 3282 /* We must call terminate if we try and rethrow an exception, when 3283 there is no exception currently active and when there are no 3284 handlers left. */ 3285 if (! eh->info || (*dhc)[0] == 0) 3286 __terminate (); 3287 3288 /* Find the jmpbuf associated with the top element of the dynamic 3289 handler chain. The jumpbuf starts two words into the buffer. */ 3290 jmpbuf = &(*dhc)[2]; 3291 3292 /* Then we pop the top element off the dynamic handler chain. */ 3293 *dhc = (void**)(*dhc)[0]; 3294 3295 /* And then we jump to the handler. */ 3296 3297#ifdef DONT_USE_BUILTIN_SETJMP 3298 longjmp (jmpbuf, 1); 3299#else 3300 __builtin_longjmp (jmpbuf, 1); 3301#endif 3302} 3303 3304/* Run cleanups on the dynamic cleanup stack for the current dynamic 3305 handler, then pop the handler off the dynamic handler stack, and 3306 then throw. This is used to skip the first handler, and transfer 3307 control to the next handler in the dynamic handler stack. */ 3308 3309void 3310__sjpopnthrow () 3311{ 3312 struct eh_context *eh = (*get_eh_context) (); 3313 void ***dhc = &eh->dynamic_handler_chain; 3314 void (*func)(void *, int); 3315 void *arg; 3316 void ***cleanup; 3317 3318 /* The cleanup chain is one word into the buffer. Get the cleanup 3319 chain. */ 3320 cleanup = (void***)&(*dhc)[1]; 3321 3322 /* If there are any cleanups in the chain, run them now. */ 3323 if (cleanup[0]) 3324 { 3325 double store[200]; 3326 void **buf = (void**)store; 3327 buf[1] = 0; 3328 buf[0] = (*dhc); 3329 3330 /* try { */ 3331#ifdef DONT_USE_BUILTIN_SETJMP 3332 if (! setjmp (&buf[2])) 3333#else 3334 if (! __builtin_setjmp (&buf[2])) 3335#endif 3336 { 3337 *dhc = buf; 3338 while (cleanup[0]) 3339 { 3340 func = (void(*)(void*, int))cleanup[0][1]; 3341 arg = (void*)cleanup[0][2]; 3342 3343 /* Update this before running the cleanup. */ 3344 cleanup[0] = (void **)cleanup[0][0]; 3345 3346 (*func)(arg, 2); 3347 } 3348 *dhc = buf[0]; 3349 } 3350 /* catch (...) */ 3351 else 3352 { 3353 __terminate (); 3354 } 3355 } 3356 3357 /* Then we pop the top element off the dynamic handler chain. */ 3358 *dhc = (void**)(*dhc)[0]; 3359 3360 __sjthrow (); 3361} 3362 3363/* Support code for all exception region-based exception handling. */ 3364 3365/* This value identifies the place from which an exception is being 3366 thrown. */ 3367 3368#ifdef EH_TABLE_LOOKUP 3369 3370EH_TABLE_LOOKUP 3371 3372#else 3373 3374#ifdef DWARF2_UNWIND_INFO 3375 3376 3377/* Return the table version of an exception descriptor */ 3378 3379short 3380__get_eh_table_version (exception_descriptor *table) 3381{ 3382 return table->lang.version; 3383} 3384 3385/* Return the originating table language of an exception descriptor */ 3386 3387short 3388__get_eh_table_language (exception_descriptor *table) 3389{ 3390 return table->lang.language; 3391} 3392 3393/* This routine takes a PC and a pointer to the exception region TABLE for 3394 its translation unit, and returns the address of the exception handler 3395 associated with the closest exception table handler entry associated 3396 with that PC, or 0 if there are no table entries the PC fits in. 3397 3398 In the advent of a tie, we have to give the last entry, as it represents 3399 an inner block. */ 3400 3401static void * 3402old_find_exception_handler (void *pc, old_exception_table *table) 3403{ 3404 if (table) 3405 { 3406 int pos; 3407 int best = -1; 3408 3409 /* We can't do a binary search because the table isn't guaranteed 3410 to be sorted from function to function. */ 3411 for (pos = 0; table[pos].start_region != (void *) -1; ++pos) 3412 { 3413 if (table[pos].start_region <= pc && table[pos].end_region > pc) 3414 { 3415 /* This can apply. Make sure it is at least as small as 3416 the previous best. */ 3417 if (best == -1 || (table[pos].end_region <= table[best].end_region 3418 && table[pos].start_region >= table[best].start_region)) 3419 best = pos; 3420 } 3421 /* But it is sorted by starting PC within a function. */ 3422 else if (best >= 0 && table[pos].start_region > pc) 3423 break; 3424 } 3425 if (best != -1) 3426 return table[best].exception_handler; 3427 } 3428 3429 return (void *) 0; 3430} 3431 3432static void * 3433find_exception_handler (void *pc, exception_descriptor *table, void *eh_info) 3434{ 3435 if (table) 3436 { 3437 /* The new model assumed the table is sorted inner-most out so the 3438 first region we find which matches is the correct one */ 3439 3440 int pos; 3441 void *ret; 3442 exception_table *tab = &(table->table[0]); 3443 3444 /* Subtract 1 from the PC to avoid hitting the next region */ 3445 pc--; 3446 3447 /* We can't do a binary search because the table is in inner-most 3448 to outermost address ranges within functions */ 3449 for (pos = 0; tab[pos].start_region != (void *) -1; pos++) 3450 { 3451 if (tab[pos].start_region <= pc && tab[pos].end_region > pc) 3452 { 3453 if (tab[pos].match_info) 3454 { 3455 __eh_matcher matcher = ((__eh_info *)eh_info)->match_function; 3456 /* match info but no matcher is NOT a match */ 3457 if (matcher) 3458 { 3459 ret = (*matcher)(eh_info, tab[pos].match_info, table); 3460 if (ret) 3461 return tab[pos].exception_handler; 3462 } 3463 } 3464 else 3465 return tab[pos].exception_handler; 3466 } 3467 } 3468 } 3469 3470 return (void *) 0; 3471} 3472#endif /* DWARF2_UNWIND_INFO */ 3473#endif /* EH_TABLE_LOOKUP */ 3474 3475#ifdef DWARF2_UNWIND_INFO 3476/* Support code for exception handling using static unwind information. */ 3477 3478#include "frame.h" 3479 3480/* This type is used in get_reg and put_reg to deal with ABIs where a void* 3481 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to 3482 avoid a warning about casting between int and pointer of different 3483 sizes. */ 3484 3485typedef int ptr_type __attribute__ ((mode (pointer))); 3486 3487/* Get the value of register REG as saved in UDATA, where SUB_UDATA is a 3488 frame called by UDATA or 0. */ 3489 3490static void* 3491get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata) 3492{ 3493 if (udata->saved[reg] == REG_SAVED_OFFSET) 3494 return (void *)(ptr_type) 3495 *(word_type *)(udata->cfa + udata->reg_or_offset[reg]); 3496 else if (udata->saved[reg] == REG_SAVED_REG && sub_udata) 3497 return get_reg (udata->reg_or_offset[reg], sub_udata, 0); 3498 else 3499 abort (); 3500} 3501 3502/* Overwrite the saved value for register REG in frame UDATA with VAL. */ 3503 3504static void 3505put_reg (unsigned reg, void *val, frame_state *udata) 3506{ 3507 if (udata->saved[reg] == REG_SAVED_OFFSET) 3508 *(word_type *)(udata->cfa + udata->reg_or_offset[reg]) 3509 = (word_type)(ptr_type) val; 3510 else 3511 abort (); 3512} 3513 3514/* Copy the saved value for register REG from frame UDATA to frame 3515 TARGET_UDATA. Unlike the previous two functions, this can handle 3516 registers that are not one word large. */ 3517 3518static void 3519copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata) 3520{ 3521 if (udata->saved[reg] == REG_SAVED_OFFSET 3522 && target_udata->saved[reg] == REG_SAVED_OFFSET) 3523 memcpy (target_udata->cfa + target_udata->reg_or_offset[reg], 3524 udata->cfa + udata->reg_or_offset[reg], 3525 __builtin_dwarf_reg_size (reg)); 3526 else 3527 abort (); 3528} 3529 3530/* Retrieve the return address for frame UDATA, where SUB_UDATA is a 3531 frame called by UDATA or 0. */ 3532 3533static inline void * 3534get_return_addr (frame_state *udata, frame_state *sub_udata) 3535{ 3536 return __builtin_extract_return_addr 3537 (get_reg (udata->retaddr_column, udata, sub_udata)); 3538} 3539 3540/* Overwrite the return address for frame UDATA with VAL. */ 3541 3542static inline void 3543put_return_addr (void *val, frame_state *udata) 3544{ 3545 val = __builtin_frob_return_addr (val); 3546 put_reg (udata->retaddr_column, val, udata); 3547} 3548 3549/* Given the current frame UDATA and its return address PC, return the 3550 information about the calling frame in CALLER_UDATA. */ 3551 3552static void * 3553next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata) 3554{ 3555 caller_udata = __frame_state_for (pc, caller_udata); 3556 if (! caller_udata) 3557 return 0; 3558 3559 /* Now go back to our caller's stack frame. If our caller's CFA register 3560 was saved in our stack frame, restore it; otherwise, assume the CFA 3561 register is SP and restore it to our CFA value. */ 3562 if (udata->saved[caller_udata->cfa_reg]) 3563 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0); 3564 else 3565 caller_udata->cfa = udata->cfa; 3566 caller_udata->cfa += caller_udata->cfa_offset; 3567 3568 return caller_udata; 3569} 3570 3571#ifdef INCOMING_REGNO 3572/* Is the saved value for register REG in frame UDATA stored in a register 3573 window in the previous frame? */ 3574 3575static int 3576in_reg_window (int reg, frame_state *udata) 3577{ 3578 if (udata->saved[reg] != REG_SAVED_OFFSET) 3579 return 0; 3580 3581#ifdef STACK_GROWS_DOWNWARD 3582 return udata->reg_or_offset[reg] > 0; 3583#else 3584 return udata->reg_or_offset[reg] < 0; 3585#endif 3586} 3587#endif /* INCOMING_REGNO */ 3588 3589/* We first search for an exception handler, and if we don't find 3590 it, we call __terminate on the current stack frame so that we may 3591 use the debugger to walk the stack and understand why no handler 3592 was found. 3593 3594 If we find one, then we unwind the frames down to the one that 3595 has the handler and transfer control into the handler. */ 3596 3597void 3598__throw () 3599{ 3600 struct eh_context *eh = (*get_eh_context) (); 3601 void *saved_pc, *pc, *handler, *retaddr; 3602 frame_state ustruct, ustruct2; 3603 frame_state *udata = &ustruct; 3604 frame_state *sub_udata = &ustruct2; 3605 frame_state my_ustruct, *my_udata = &my_ustruct; 3606 long args_size; 3607 int new_exception_model; 3608 3609 /* This is required for C++ semantics. We must call terminate if we 3610 try and rethrow an exception, when there is no exception currently 3611 active. */ 3612 if (! eh->info) 3613 __terminate (); 3614 3615 /* Start at our stack frame. */ 3616label: 3617 udata = __frame_state_for (&&label, udata); 3618 if (! udata) 3619 __terminate (); 3620 3621 /* We need to get the value from the CFA register. At this point in 3622 compiling __throw we don't know whether or not we will use the frame 3623 pointer register for the CFA, so we check our unwind info. */ 3624 if (udata->cfa_reg == __builtin_dwarf_fp_regnum ()) 3625 udata->cfa = __builtin_fp (); 3626 else 3627 udata->cfa = __builtin_sp (); 3628 udata->cfa += udata->cfa_offset; 3629 3630 memcpy (my_udata, udata, sizeof (*udata)); 3631 3632 /* Do any necessary initialization to access arbitrary stack frames. 3633 On the SPARC, this means flushing the register windows. */ 3634 __builtin_unwind_init (); 3635 3636 /* Now reset pc to the right throw point. */ 3637 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1; 3638 saved_pc = pc; 3639 3640 handler = 0; 3641 for (;;) 3642 { 3643 frame_state *p = udata; 3644 udata = next_stack_level (pc, udata, sub_udata); 3645 sub_udata = p; 3646 3647 /* If we couldn't find the next frame, we lose. */ 3648 if (! udata) 3649 break; 3650 3651 if (udata->eh_ptr == NULL) 3652 new_exception_model = 0; 3653 else 3654 new_exception_model = (((exception_descriptor *)(udata->eh_ptr))-> 3655 runtime_id_field == NEW_EH_RUNTIME); 3656 3657 if (new_exception_model) 3658 handler = find_exception_handler (pc, udata->eh_ptr, eh->info); 3659 else 3660 handler = old_find_exception_handler (pc, udata->eh_ptr); 3661 3662 /* If we found one, we can stop searching. */ 3663 if (handler) 3664 { 3665 args_size = udata->args_size; 3666 break; 3667 } 3668 3669 /* Otherwise, we continue searching. We subtract 1 from PC to avoid 3670 hitting the beginning of the next region. */ 3671 pc = get_return_addr (udata, sub_udata) - 1; 3672 } 3673 3674 /* If we haven't found a handler by now, this is an unhandled 3675 exception. */ 3676 if (! handler) 3677 __terminate (); 3678 3679 eh->handler_label = handler; 3680 3681 if (pc == saved_pc) 3682 /* We found a handler in the throw context, no need to unwind. */ 3683 udata = my_udata; 3684 else 3685 { 3686 int i; 3687 3688 /* Unwind all the frames between this one and the handler by copying 3689 their saved register values into our register save slots. */ 3690 3691 /* Remember the PC where we found the handler. */ 3692 void *handler_pc = pc; 3693 3694 /* Start from the throw context again. */ 3695 pc = saved_pc; 3696 memcpy (udata, my_udata, sizeof (*udata)); 3697 3698 while (pc != handler_pc) 3699 { 3700 frame_state *p = udata; 3701 udata = next_stack_level (pc, udata, sub_udata); 3702 sub_udata = p; 3703 3704 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) 3705 if (i != udata->retaddr_column && udata->saved[i]) 3706 { 3707#ifdef INCOMING_REGNO 3708 /* If you modify the saved value of the return address 3709 register on the SPARC, you modify the return address for 3710 your caller's frame. Don't do that here, as it will 3711 confuse get_return_addr. */ 3712 if (in_reg_window (i, udata) 3713 && udata->saved[udata->retaddr_column] == REG_SAVED_REG 3714 && udata->reg_or_offset[udata->retaddr_column] == i) 3715 continue; 3716#endif 3717 copy_reg (i, udata, my_udata); 3718 } 3719 3720 pc = get_return_addr (udata, sub_udata) - 1; 3721 } 3722 3723#ifdef INCOMING_REGNO 3724 /* But we do need to update the saved return address register from 3725 the last frame we unwind, or the handler frame will have the wrong 3726 return address. */ 3727 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG) 3728 { 3729 i = udata->reg_or_offset[udata->retaddr_column]; 3730 if (in_reg_window (i, udata)) 3731 copy_reg (i, udata, my_udata); 3732 } 3733#endif 3734 } 3735 /* udata now refers to the frame called by the handler frame. */ 3736 3737 /* Emit the stub to adjust sp and jump to the handler. */ 3738 if (new_exception_model) 3739 retaddr = __builtin_eh_stub (); 3740 else 3741 retaddr = __builtin_eh_stub_old (); 3742 3743 /* And then set our return address to point to the stub. */ 3744 if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET) 3745 put_return_addr (retaddr, my_udata); 3746 else 3747 __builtin_set_return_addr_reg (retaddr); 3748 3749 /* Set up the registers we use to communicate with the stub. 3750 We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */ 3751 3752 if (new_exception_model) 3753 __builtin_set_eh_regs ((void *)eh, 3754#ifdef STACK_GROWS_DOWNWARD 3755 udata->cfa - my_udata->cfa 3756#else 3757 my_udata->cfa - udata->cfa 3758#endif 3759 + args_size); 3760 else 3761 __builtin_set_eh_regs (handler, 3762 3763#ifdef STACK_GROWS_DOWNWARD 3764 udata->cfa - my_udata->cfa 3765#else 3766 my_udata->cfa - udata->cfa 3767#endif 3768 + args_size); 3769 3770 /* Epilogue: restore the handler frame's register values and return 3771 to the stub. */ 3772} 3773#endif /* DWARF2_UNWIND_INFO */ 3774 3775#endif /* L_eh */ 3776 3777#ifdef L_pure 3778#ifndef inhibit_libc 3779/* This gets us __GNU_LIBRARY__. */ 3780#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 3781#include <stdio.h> 3782 3783#ifdef __GNU_LIBRARY__ 3784 /* Avoid forcing the library's meaning of `write' on the user program 3785 by using the "internal" name (for use within the library) */ 3786#define write(fd, buf, n) __write((fd), (buf), (n)) 3787#endif 3788#endif /* inhibit_libc */ 3789 3790#define MESSAGE "pure virtual method called\n" 3791 3792void 3793__pure_virtual () 3794{ 3795#ifndef inhibit_libc 3796 write (2, MESSAGE, sizeof (MESSAGE) - 1); 3797#endif 3798 _exit (-1); 3799} 3800#endif 3801