libgcc2.c revision 104764
1362679Sdim/* More subroutines needed by GCC output code on some machines. */ 2362679Sdim/* Compile this one with gcc. */ 3362679Sdim/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 4362679Sdim 2000, 2001, 2002 Free Software Foundation, Inc. 5362679Sdim 6362679SdimThis file is part of GCC. 7362679Sdim 8362679SdimGCC is free software; you can redistribute it and/or modify it under 9362679Sdimthe terms of the GNU General Public License as published by the Free 10362679SdimSoftware Foundation; either version 2, or (at your option) any later 11362679Sdimversion. 12362679Sdim 13362679SdimIn addition to the permissions in the GNU General Public License, the 14362679SdimFree Software Foundation gives you unlimited permission to link the 15362679Sdimcompiled version of this file into combinations with other programs, 16362679Sdimand to distribute those combinations without any restriction coming 17362679Sdimfrom the use of this file. (The General Public License restrictions 18362679Sdimdo apply in other respects; for example, they cover modification of 19362679Sdimthe file, and distribution when not linked into a combine 20362679Sdimexecutable.) 21362679Sdim 22362679SdimGCC is distributed in the hope that it will be useful, but WITHOUT ANY 23362679SdimWARRANTY; without even the implied warranty of MERCHANTABILITY or 24362679SdimFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25362679Sdimfor more details. 26362679Sdim 27362679SdimYou should have received a copy of the GNU General Public License 28362679Sdimalong with GCC; see the file COPYING. If not, write to the Free 29362679SdimSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 30362679Sdim02111-1307, USA. */ 31362679Sdim 32362679Sdim/* $FreeBSD: head/contrib/gcc/libgcc2.c 104764 2002-10-10 04:50:29Z kan $ */ 33362679Sdim 34362679Sdim/* It is incorrect to include config.h here, because this file is being 35362679Sdim compiled for the target, and hence definitions concerning only the host 36362679Sdim do not apply. */ 37362679Sdim 38362679Sdim#include "tconfig.h" 39362679Sdim#include "tsystem.h" 40362679Sdim 41362679Sdim/* Don't use `fancy_abort' here even if config.h says to use it. */ 42362679Sdim#ifdef abort 43362679Sdim#undef abort 44362679Sdim#endif 45362679Sdim 46362679Sdim#include "libgcc2.h" 47362679Sdim 48362679Sdim#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3) 49362679Sdim#if defined (L_divdi3) || defined (L_moddi3) 50362679Sdimstatic inline 51362679Sdim#endif 52362679SdimDWtype 53362679Sdim__negdi2 (DWtype u) 54362679Sdim{ 55362679Sdim DWunion w; 56362679Sdim DWunion uu; 57362679Sdim 58362679Sdim uu.ll = u; 59362679Sdim 60362679Sdim w.s.low = -uu.s.low; 61362679Sdim w.s.high = -uu.s.high - ((UWtype) w.s.low > 0); 62362679Sdim 63362679Sdim return w.ll; 64362679Sdim} 65362679Sdim#endif 66362679Sdim 67362679Sdim#ifdef L_addvsi3 68362679SdimWtype 69362679Sdim__addvsi3 (Wtype a, Wtype b) 70362679Sdim{ 71362679Sdim Wtype w; 72362679Sdim 73362679Sdim w = a + b; 74362679Sdim 75362679Sdim if (b >= 0 ? w < a : w > a) 76362679Sdim abort (); 77362679Sdim 78362679Sdim return w; 79362679Sdim} 80362679Sdim#endif 81362679Sdim 82362679Sdim#ifdef L_addvdi3 83362679SdimDWtype 84362679Sdim__addvdi3 (DWtype a, DWtype b) 85362679Sdim{ 86362679Sdim DWtype w; 87362679Sdim 88362679Sdim w = a + b; 89362679Sdim 90362679Sdim if (b >= 0 ? w < a : w > a) 91362679Sdim abort (); 92362679Sdim 93362679Sdim return w; 94362679Sdim} 95362679Sdim#endif 96362679Sdim 97362679Sdim#ifdef L_subvsi3 98362679SdimWtype 99362679Sdim__subvsi3 (Wtype a, Wtype b) 100362679Sdim{ 101362679Sdim#ifdef L_addvsi3 102362679Sdim return __addvsi3 (a, (-b)); 103362679Sdim#else 104362679Sdim DWtype w; 105362679Sdim 106362679Sdim w = a - b; 107362679Sdim 108362679Sdim if (b >= 0 ? w > a : w < a) 109362679Sdim abort (); 110362679Sdim 111362679Sdim return w; 112362679Sdim#endif 113362679Sdim} 114362679Sdim#endif 115362679Sdim 116362679Sdim#ifdef L_subvdi3 117362679SdimDWtype 118362679Sdim__subvdi3 (DWtype a, DWtype b) 119362679Sdim{ 120362679Sdim#ifdef L_addvdi3 121362679Sdim return (a, (-b)); 122362679Sdim#else 123362679Sdim DWtype w; 124362679Sdim 125362679Sdim w = a - b; 126362679Sdim 127362679Sdim if (b >= 0 ? w > a : w < a) 128362679Sdim abort (); 129362679Sdim 130362679Sdim return w; 131362679Sdim#endif 132362679Sdim} 133362679Sdim#endif 134362679Sdim 135362679Sdim#ifdef L_mulvsi3 136362679SdimWtype 137362679Sdim__mulvsi3 (Wtype a, Wtype b) 138362679Sdim{ 139362679Sdim DWtype w; 140362679Sdim 141362679Sdim w = a * b; 142362679Sdim 143362679Sdim if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0) 144362679Sdim abort (); 145362679Sdim 146362679Sdim return w; 147362679Sdim} 148362679Sdim#endif 149362679Sdim 150362679Sdim#ifdef L_negvsi2 151362679SdimWtype 152362679Sdim__negvsi2 (Wtype a) 153362679Sdim{ 154362679Sdim Wtype w; 155362679Sdim 156362679Sdim w = -a; 157362679Sdim 158362679Sdim if (a >= 0 ? w > 0 : w < 0) 159362679Sdim abort (); 160362679Sdim 161362679Sdim return w; 162362679Sdim} 163362679Sdim#endif 164362679Sdim 165362679Sdim#ifdef L_negvdi2 166362679SdimDWtype 167362679Sdim__negvdi2 (DWtype a) 168362679Sdim{ 169362679Sdim DWtype w; 170362679Sdim 171362679Sdim w = -a; 172362679Sdim 173362679Sdim if (a >= 0 ? w > 0 : w < 0) 174362679Sdim abort (); 175362679Sdim 176362679Sdim return w; 177362679Sdim} 178362679Sdim#endif 179362679Sdim 180362679Sdim#ifdef L_absvsi2 181362679SdimWtype 182362679Sdim__absvsi2 (Wtype a) 183362679Sdim{ 184362679Sdim Wtype w = a; 185362679Sdim 186362679Sdim if (a < 0) 187362679Sdim#ifdef L_negvsi2 188362679Sdim w = __negvsi2 (a); 189362679Sdim#else 190362679Sdim w = -a; 191362679Sdim 192362679Sdim if (w < 0) 193362679Sdim abort (); 194362679Sdim#endif 195362679Sdim 196362679Sdim return w; 197362679Sdim} 198362679Sdim#endif 199362679Sdim 200362679Sdim#ifdef L_absvdi2 201362679SdimDWtype 202362679Sdim__absvdi2 (DWtype a) 203362679Sdim{ 204362679Sdim DWtype w = a; 205362679Sdim 206362679Sdim if (a < 0) 207362679Sdim#ifdef L_negvsi2 208362679Sdim w = __negvsi2 (a); 209362679Sdim#else 210362679Sdim w = -a; 211362679Sdim 212362679Sdim if (w < 0) 213362679Sdim abort (); 214362679Sdim#endif 215362679Sdim 216362679Sdim return w; 217362679Sdim} 218362679Sdim#endif 219362679Sdim 220362679Sdim#ifdef L_mulvdi3 221362679SdimDWtype 222362679Sdim__mulvdi3 (DWtype u, DWtype v) 223362679Sdim{ 224362679Sdim DWtype w; 225362679Sdim 226362679Sdim w = u * v; 227362679Sdim 228362679Sdim if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0) 229362679Sdim abort (); 230362679Sdim 231362679Sdim return w; 232362679Sdim} 233362679Sdim#endif 234362679Sdim 235362679Sdim 236362679Sdim/* Unless shift functions are defined whith full ANSI prototypes, 237362679Sdim parameter b will be promoted to int if word_type is smaller than an int. */ 238362679Sdim#ifdef L_lshrdi3 239362679SdimDWtype 240362679Sdim__lshrdi3 (DWtype u, word_type b) 241362679Sdim{ 242362679Sdim DWunion w; 243362679Sdim word_type bm; 244362679Sdim DWunion uu; 245362679Sdim 246362679Sdim if (b == 0) 247362679Sdim return u; 248362679Sdim 249362679Sdim uu.ll = u; 250362679Sdim 251362679Sdim bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 252362679Sdim if (bm <= 0) 253362679Sdim { 254362679Sdim w.s.high = 0; 255362679Sdim w.s.low = (UWtype) uu.s.high >> -bm; 256362679Sdim } 257362679Sdim else 258362679Sdim { 259362679Sdim UWtype carries = (UWtype) uu.s.high << bm; 260362679Sdim 261362679Sdim w.s.high = (UWtype) uu.s.high >> b; 262362679Sdim w.s.low = ((UWtype) uu.s.low >> b) | carries; 263362679Sdim } 264362679Sdim 265362679Sdim return w.ll; 266362679Sdim} 267362679Sdim#endif 268362679Sdim 269362679Sdim#ifdef L_ashldi3 270362679SdimDWtype 271362679Sdim__ashldi3 (DWtype u, word_type b) 272362679Sdim{ 273362679Sdim DWunion w; 274362679Sdim word_type bm; 275362679Sdim DWunion uu; 276362679Sdim 277362679Sdim if (b == 0) 278362679Sdim return u; 279362679Sdim 280362679Sdim uu.ll = u; 281362679Sdim 282362679Sdim bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 283362679Sdim if (bm <= 0) 284362679Sdim { 285362679Sdim w.s.low = 0; 286362679Sdim w.s.high = (UWtype) uu.s.low << -bm; 287362679Sdim } 288362679Sdim else 289362679Sdim { 290362679Sdim UWtype carries = (UWtype) uu.s.low >> bm; 291362679Sdim 292362679Sdim w.s.low = (UWtype) uu.s.low << b; 293362679Sdim w.s.high = ((UWtype) uu.s.high << b) | carries; 294362679Sdim } 295362679Sdim 296362679Sdim return w.ll; 297362679Sdim} 298362679Sdim#endif 299362679Sdim 300362679Sdim#ifdef L_ashrdi3 301362679SdimDWtype 302362679Sdim__ashrdi3 (DWtype u, word_type b) 303362679Sdim{ 304362679Sdim DWunion w; 305362679Sdim word_type bm; 306362679Sdim DWunion uu; 307362679Sdim 308362679Sdim if (b == 0) 309362679Sdim return u; 310362679Sdim 311362679Sdim uu.ll = u; 312362679Sdim 313362679Sdim bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 314362679Sdim if (bm <= 0) 315362679Sdim { 316362679Sdim /* w.s.high = 1..1 or 0..0 */ 317362679Sdim w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1); 318362679Sdim w.s.low = uu.s.high >> -bm; 319362679Sdim } 320362679Sdim else 321362679Sdim { 322362679Sdim UWtype carries = (UWtype) uu.s.high << bm; 323362679Sdim 324362679Sdim w.s.high = uu.s.high >> b; 325362679Sdim w.s.low = ((UWtype) uu.s.low >> b) | carries; 326362679Sdim } 327362679Sdim 328362679Sdim return w.ll; 329362679Sdim} 330362679Sdim#endif 331362679Sdim 332362679Sdim#ifdef L_ffsdi2 333362679SdimDWtype 334362679Sdim__ffsdi2 (DWtype u) 335362679Sdim{ 336362679Sdim DWunion uu; 337362679Sdim UWtype word, count, add; 338362679Sdim 339362679Sdim uu.ll = u; 340362679Sdim if (uu.s.low != 0) 341362679Sdim word = uu.s.low, add = 0; 342362679Sdim else if (uu.s.high != 0) 343362679Sdim word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype); 344362679Sdim else 345362679Sdim return 0; 346362679Sdim 347362679Sdim count_trailing_zeros (count, word); 348362679Sdim return count + add + 1; 349362679Sdim} 350362679Sdim#endif 351362679Sdim 352362679Sdim#ifdef L_muldi3 353362679SdimDWtype 354362679Sdim__muldi3 (DWtype u, DWtype v) 355362679Sdim{ 356362679Sdim DWunion w; 357362679Sdim DWunion uu, vv; 358362679Sdim 359362679Sdim uu.ll = u, 360362679Sdim vv.ll = v; 361362679Sdim 362362679Sdim w.ll = __umulsidi3 (uu.s.low, vv.s.low); 363362679Sdim w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high 364362679Sdim + (UWtype) uu.s.high * (UWtype) vv.s.low); 365362679Sdim 366362679Sdim return w.ll; 367362679Sdim} 368362679Sdim#endif 369362679Sdim 370362679Sdim#ifdef L_udiv_w_sdiv 371362679Sdim#if defined (sdiv_qrnnd) 372362679SdimUWtype 373362679Sdim__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) 374362679Sdim{ 375362679Sdim UWtype q, r; 376362679Sdim UWtype c0, c1, b1; 377362679Sdim 378362679Sdim if ((Wtype) d >= 0) 379362679Sdim { 380362679Sdim if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) 381362679Sdim { 382362679Sdim /* dividend, divisor, and quotient are nonnegative */ 383362679Sdim sdiv_qrnnd (q, r, a1, a0, d); 384362679Sdim } 385362679Sdim else 386362679Sdim { 387362679Sdim /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ 388362679Sdim sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); 389362679Sdim /* Divide (c1*2^32 + c0) by d */ 390362679Sdim sdiv_qrnnd (q, r, c1, c0, d); 391362679Sdim /* Add 2^31 to quotient */ 392362679Sdim q += (UWtype) 1 << (W_TYPE_SIZE - 1); 393362679Sdim } 394362679Sdim } 395362679Sdim else 396362679Sdim { 397362679Sdim b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 398362679Sdim c1 = a1 >> 1; /* A/2 */ 399362679Sdim c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); 400362679Sdim 401362679Sdim if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 402362679Sdim { 403362679Sdim sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 404362679Sdim 405362679Sdim r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 406362679Sdim if ((d & 1) != 0) 407362679Sdim { 408362679Sdim if (r >= q) 409362679Sdim r = r - q; 410362679Sdim else if (q - r <= d) 411362679Sdim { 412362679Sdim r = r - q + d; 413362679Sdim q--; 414362679Sdim } 415362679Sdim else 416362679Sdim { 417362679Sdim r = r - q + 2*d; 418362679Sdim q -= 2; 419362679Sdim } 420362679Sdim } 421362679Sdim } 422362679Sdim else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 423362679Sdim { 424362679Sdim c1 = (b1 - 1) - c1; 425362679Sdim c0 = ~c0; /* logical NOT */ 426362679Sdim 427362679Sdim sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 428362679Sdim 429362679Sdim q = ~q; /* (A/2)/b1 */ 430362679Sdim r = (b1 - 1) - r; 431362679Sdim 432362679Sdim r = 2*r + (a0 & 1); /* A/(2*b1) */ 433362679Sdim 434362679Sdim if ((d & 1) != 0) 435362679Sdim { 436362679Sdim if (r >= q) 437362679Sdim r = r - q; 438362679Sdim else if (q - r <= d) 439362679Sdim { 440362679Sdim r = r - q + d; 441362679Sdim q--; 442362679Sdim } 443362679Sdim else 444362679Sdim { 445362679Sdim r = r - q + 2*d; 446362679Sdim q -= 2; 447362679Sdim } 448362679Sdim } 449362679Sdim } 450362679Sdim else /* Implies c1 = b1 */ 451362679Sdim { /* Hence a1 = d - 1 = 2*b1 - 1 */ 452362679Sdim if (a0 >= -d) 453362679Sdim { 454362679Sdim q = -1; 455362679Sdim r = a0 + d; 456362679Sdim } 457362679Sdim else 458362679Sdim { 459362679Sdim q = -2; 460362679Sdim r = a0 + 2*d; 461362679Sdim } 462362679Sdim } 463362679Sdim } 464362679Sdim 465362679Sdim *rp = r; 466362679Sdim return q; 467362679Sdim} 468362679Sdim#else 469362679Sdim/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ 470362679SdimUWtype 471362679Sdim__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), 472362679Sdim UWtype a1 __attribute__ ((__unused__)), 473362679Sdim UWtype a0 __attribute__ ((__unused__)), 474362679Sdim UWtype d __attribute__ ((__unused__))) 475362679Sdim{ 476362679Sdim return 0; 477362679Sdim} 478362679Sdim#endif 479362679Sdim#endif 480362679Sdim 481362679Sdim#if (defined (L_udivdi3) || defined (L_divdi3) || \ 482362679Sdim defined (L_umoddi3) || defined (L_moddi3)) 483362679Sdim#define L_udivmoddi4 484362679Sdim#endif 485362679Sdim 486362679Sdim#ifdef L_clz 487362679Sdimconst UQItype __clz_tab[] = 488362679Sdim{ 489362679Sdim 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, 490362679Sdim 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, 491362679Sdim 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, 492362679Sdim 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, 493362679Sdim 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, 494362679Sdim 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, 495362679Sdim 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, 496362679Sdim 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, 497362679Sdim}; 498362679Sdim#endif 499362679Sdim 500362679Sdim#ifdef L_udivmoddi4 501362679Sdim 502362679Sdim#if (defined (L_udivdi3) || defined (L_divdi3) || \ 503362679Sdim defined (L_umoddi3) || defined (L_moddi3)) 504362679Sdimstatic inline 505362679Sdim#endif 506362679SdimUDWtype 507362679Sdim__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) 508362679Sdim{ 509362679Sdim DWunion ww; 510362679Sdim DWunion nn, dd; 511362679Sdim DWunion rr; 512362679Sdim UWtype d0, d1, n0, n1, n2; 513362679Sdim UWtype q0, q1; 514362679Sdim UWtype b, bm; 515362679Sdim 516362679Sdim nn.ll = n; 517362679Sdim dd.ll = d; 518362679Sdim 519362679Sdim d0 = dd.s.low; 520362679Sdim d1 = dd.s.high; 521362679Sdim n0 = nn.s.low; 522362679Sdim n1 = nn.s.high; 523362679Sdim 524362679Sdim#if !UDIV_NEEDS_NORMALIZATION 525362679Sdim if (d1 == 0) 526362679Sdim { 527362679Sdim if (d0 > n1) 528362679Sdim { 529362679Sdim /* 0q = nn / 0D */ 530362679Sdim 531362679Sdim udiv_qrnnd (q0, n0, n1, n0, d0); 532362679Sdim q1 = 0; 533362679Sdim 534362679Sdim /* Remainder in n0. */ 535362679Sdim } 536362679Sdim else 537362679Sdim { 538362679Sdim /* qq = NN / 0d */ 539362679Sdim 540362679Sdim if (d0 == 0) 541362679Sdim d0 = 1 / d0; /* Divide intentionally by zero. */ 542362679Sdim 543362679Sdim udiv_qrnnd (q1, n1, 0, n1, d0); 544362679Sdim udiv_qrnnd (q0, n0, n1, n0, d0); 545362679Sdim 546362679Sdim /* Remainder in n0. */ 547362679Sdim } 548362679Sdim 549362679Sdim if (rp != 0) 550362679Sdim { 551362679Sdim rr.s.low = n0; 552362679Sdim rr.s.high = 0; 553362679Sdim *rp = rr.ll; 554362679Sdim } 555362679Sdim } 556362679Sdim 557362679Sdim#else /* UDIV_NEEDS_NORMALIZATION */ 558362679Sdim 559362679Sdim if (d1 == 0) 560362679Sdim { 561362679Sdim if (d0 > n1) 562362679Sdim { 563362679Sdim /* 0q = nn / 0D */ 564362679Sdim 565362679Sdim count_leading_zeros (bm, d0); 566362679Sdim 567362679Sdim if (bm != 0) 568362679Sdim { 569362679Sdim /* Normalize, i.e. make the most significant bit of the 570362679Sdim denominator set. */ 571362679Sdim 572362679Sdim d0 = d0 << bm; 573362679Sdim n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); 574362679Sdim n0 = n0 << bm; 575362679Sdim } 576362679Sdim 577362679Sdim udiv_qrnnd (q0, n0, n1, n0, d0); 578362679Sdim q1 = 0; 579362679Sdim 580362679Sdim /* Remainder in n0 >> bm. */ 581362679Sdim } 582362679Sdim else 583362679Sdim { 584362679Sdim /* qq = NN / 0d */ 585362679Sdim 586362679Sdim if (d0 == 0) 587362679Sdim d0 = 1 / d0; /* Divide intentionally by zero. */ 588362679Sdim 589362679Sdim count_leading_zeros (bm, d0); 590362679Sdim 591362679Sdim if (bm == 0) 592362679Sdim { 593362679Sdim /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 594362679Sdim conclude (the most significant bit of n1 is set) /\ (the 595362679Sdim leading quotient digit q1 = 1). 596362679Sdim 597362679Sdim This special case is necessary, not an optimization. 598362679Sdim (Shifts counts of W_TYPE_SIZE are undefined.) */ 599362679Sdim 600362679Sdim n1 -= d0; 601362679Sdim q1 = 1; 602362679Sdim } 603362679Sdim else 604362679Sdim { 605362679Sdim /* Normalize. */ 606362679Sdim 607362679Sdim b = W_TYPE_SIZE - bm; 608362679Sdim 609362679Sdim d0 = d0 << bm; 610362679Sdim n2 = n1 >> b; 611362679Sdim n1 = (n1 << bm) | (n0 >> b); 612362679Sdim n0 = n0 << bm; 613362679Sdim 614362679Sdim udiv_qrnnd (q1, n1, n2, n1, d0); 615362679Sdim } 616362679Sdim 617362679Sdim /* n1 != d0... */ 618362679Sdim 619362679Sdim udiv_qrnnd (q0, n0, n1, n0, d0); 620362679Sdim 621362679Sdim /* Remainder in n0 >> bm. */ 622362679Sdim } 623362679Sdim 624362679Sdim if (rp != 0) 625362679Sdim { 626362679Sdim rr.s.low = n0 >> bm; 627362679Sdim rr.s.high = 0; 628362679Sdim *rp = rr.ll; 629362679Sdim } 630362679Sdim } 631362679Sdim#endif /* UDIV_NEEDS_NORMALIZATION */ 632362679Sdim 633362679Sdim else 634362679Sdim { 635362679Sdim if (d1 > n1) 636362679Sdim { 637362679Sdim /* 00 = nn / DD */ 638362679Sdim 639362679Sdim q0 = 0; 640362679Sdim q1 = 0; 641362679Sdim 642362679Sdim /* Remainder in n1n0. */ 643362679Sdim if (rp != 0) 644362679Sdim { 645362679Sdim rr.s.low = n0; 646362679Sdim rr.s.high = n1; 647362679Sdim *rp = rr.ll; 648362679Sdim } 649362679Sdim } 650362679Sdim else 651362679Sdim { 652362679Sdim /* 0q = NN / dd */ 653362679Sdim 654362679Sdim count_leading_zeros (bm, d1); 655362679Sdim if (bm == 0) 656362679Sdim { 657362679Sdim /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 658362679Sdim conclude (the most significant bit of n1 is set) /\ (the 659362679Sdim quotient digit q0 = 0 or 1). 660362679Sdim 661362679Sdim This special case is necessary, not an optimization. */ 662362679Sdim 663362679Sdim /* The condition on the next line takes advantage of that 664362679Sdim n1 >= d1 (true due to program flow). */ 665362679Sdim if (n1 > d1 || n0 >= d0) 666362679Sdim { 667362679Sdim q0 = 1; 668362679Sdim sub_ddmmss (n1, n0, n1, n0, d1, d0); 669362679Sdim } 670362679Sdim else 671362679Sdim q0 = 0; 672362679Sdim 673362679Sdim q1 = 0; 674362679Sdim 675362679Sdim if (rp != 0) 676362679Sdim { 677362679Sdim rr.s.low = n0; 678362679Sdim rr.s.high = n1; 679362679Sdim *rp = rr.ll; 680362679Sdim } 681362679Sdim } 682362679Sdim else 683362679Sdim { 684362679Sdim UWtype m1, m0; 685362679Sdim /* Normalize. */ 686362679Sdim 687362679Sdim b = W_TYPE_SIZE - bm; 688362679Sdim 689362679Sdim d1 = (d1 << bm) | (d0 >> b); 690362679Sdim d0 = d0 << bm; 691362679Sdim n2 = n1 >> b; 692362679Sdim n1 = (n1 << bm) | (n0 >> b); 693362679Sdim n0 = n0 << bm; 694362679Sdim 695362679Sdim udiv_qrnnd (q0, n1, n2, n1, d1); 696362679Sdim umul_ppmm (m1, m0, q0, d0); 697362679Sdim 698362679Sdim if (m1 > n1 || (m1 == n1 && m0 > n0)) 699362679Sdim { 700362679Sdim q0--; 701362679Sdim sub_ddmmss (m1, m0, m1, m0, d1, d0); 702362679Sdim } 703362679Sdim 704362679Sdim q1 = 0; 705362679Sdim 706362679Sdim /* Remainder in (n1n0 - m1m0) >> bm. */ 707362679Sdim if (rp != 0) 708362679Sdim { 709362679Sdim sub_ddmmss (n1, n0, n1, n0, m1, m0); 710362679Sdim rr.s.low = (n1 << b) | (n0 >> bm); 711362679Sdim rr.s.high = n1 >> bm; 712362679Sdim *rp = rr.ll; 713362679Sdim } 714362679Sdim } 715362679Sdim } 716362679Sdim } 717362679Sdim 718362679Sdim ww.s.low = q0; 719362679Sdim ww.s.high = q1; 720362679Sdim return ww.ll; 721362679Sdim} 722#endif 723 724#ifdef L_divdi3 725DWtype 726__divdi3 (DWtype u, DWtype v) 727{ 728 word_type c = 0; 729 DWunion uu, vv; 730 DWtype w; 731 732 uu.ll = u; 733 vv.ll = v; 734 735 if (uu.s.high < 0) 736 c = ~c, 737 uu.ll = __negdi2 (uu.ll); 738 if (vv.s.high < 0) 739 c = ~c, 740 vv.ll = __negdi2 (vv.ll); 741 742 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); 743 if (c) 744 w = __negdi2 (w); 745 746 return w; 747} 748#endif 749 750#ifdef L_moddi3 751DWtype 752__moddi3 (DWtype u, DWtype v) 753{ 754 word_type c = 0; 755 DWunion uu, vv; 756 DWtype w; 757 758 uu.ll = u; 759 vv.ll = v; 760 761 if (uu.s.high < 0) 762 c = ~c, 763 uu.ll = __negdi2 (uu.ll); 764 if (vv.s.high < 0) 765 vv.ll = __negdi2 (vv.ll); 766 767 (void) __udivmoddi4 (uu.ll, vv.ll, &w); 768 if (c) 769 w = __negdi2 (w); 770 771 return w; 772} 773#endif 774 775#ifdef L_umoddi3 776UDWtype 777__umoddi3 (UDWtype u, UDWtype v) 778{ 779 UDWtype w; 780 781 (void) __udivmoddi4 (u, v, &w); 782 783 return w; 784} 785#endif 786 787#ifdef L_udivdi3 788UDWtype 789__udivdi3 (UDWtype n, UDWtype d) 790{ 791 return __udivmoddi4 (n, d, (UDWtype *) 0); 792} 793#endif 794 795#ifdef L_cmpdi2 796word_type 797__cmpdi2 (DWtype a, DWtype b) 798{ 799 DWunion au, bu; 800 801 au.ll = a, bu.ll = b; 802 803 if (au.s.high < bu.s.high) 804 return 0; 805 else if (au.s.high > bu.s.high) 806 return 2; 807 if ((UWtype) au.s.low < (UWtype) bu.s.low) 808 return 0; 809 else if ((UWtype) au.s.low > (UWtype) bu.s.low) 810 return 2; 811 return 1; 812} 813#endif 814 815#ifdef L_ucmpdi2 816word_type 817__ucmpdi2 (DWtype a, DWtype b) 818{ 819 DWunion au, bu; 820 821 au.ll = a, bu.ll = b; 822 823 if ((UWtype) au.s.high < (UWtype) bu.s.high) 824 return 0; 825 else if ((UWtype) au.s.high > (UWtype) bu.s.high) 826 return 2; 827 if ((UWtype) au.s.low < (UWtype) bu.s.low) 828 return 0; 829 else if ((UWtype) au.s.low > (UWtype) bu.s.low) 830 return 2; 831 return 1; 832} 833#endif 834 835#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 836#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 837#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 838 839DWtype 840__fixunstfDI (TFtype a) 841{ 842 TFtype b; 843 UDWtype v; 844 845 if (a < 0) 846 return 0; 847 848 /* Compute high word of result, as a flonum. */ 849 b = (a / HIGH_WORD_COEFF); 850 /* Convert that to fixed (but not to DWtype!), 851 and shift it into the high word. */ 852 v = (UWtype) b; 853 v <<= WORD_SIZE; 854 /* Remove high part from the TFtype, leaving the low part as flonum. */ 855 a -= (TFtype)v; 856 /* Convert that to fixed (but not to DWtype!) and add it in. 857 Sometimes A comes out negative. This is significant, since 858 A has more bits than a long int does. */ 859 if (a < 0) 860 v -= (UWtype) (- a); 861 else 862 v += (UWtype) a; 863 return v; 864} 865#endif 866 867#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 868DWtype 869__fixtfdi (TFtype a) 870{ 871 if (a < 0) 872 return - __fixunstfDI (-a); 873 return __fixunstfDI (a); 874} 875#endif 876 877#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 878#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 879#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 880 881DWtype 882__fixunsxfDI (XFtype a) 883{ 884 XFtype b; 885 UDWtype v; 886 887 if (a < 0) 888 return 0; 889 890 /* Compute high word of result, as a flonum. */ 891 b = (a / HIGH_WORD_COEFF); 892 /* Convert that to fixed (but not to DWtype!), 893 and shift it into the high word. */ 894 v = (UWtype) b; 895 v <<= WORD_SIZE; 896 /* Remove high part from the XFtype, leaving the low part as flonum. */ 897 a -= (XFtype)v; 898 /* Convert that to fixed (but not to DWtype!) and add it in. 899 Sometimes A comes out negative. This is significant, since 900 A has more bits than a long int does. */ 901 if (a < 0) 902 v -= (UWtype) (- a); 903 else 904 v += (UWtype) a; 905 return v; 906} 907#endif 908 909#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 910DWtype 911__fixxfdi (XFtype a) 912{ 913 if (a < 0) 914 return - __fixunsxfDI (-a); 915 return __fixunsxfDI (a); 916} 917#endif 918 919#ifdef L_fixunsdfdi 920#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 921#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 922 923DWtype 924__fixunsdfDI (DFtype a) 925{ 926 DFtype b; 927 UDWtype v; 928 929 if (a < 0) 930 return 0; 931 932 /* Compute high word of result, as a flonum. */ 933 b = (a / HIGH_WORD_COEFF); 934 /* Convert that to fixed (but not to DWtype!), 935 and shift it into the high word. */ 936 v = (UWtype) b; 937 v <<= WORD_SIZE; 938 /* Remove high part from the DFtype, leaving the low part as flonum. */ 939 a -= (DFtype)v; 940 /* Convert that to fixed (but not to DWtype!) and add it in. 941 Sometimes A comes out negative. This is significant, since 942 A has more bits than a long int does. */ 943 if (a < 0) 944 v -= (UWtype) (- a); 945 else 946 v += (UWtype) a; 947 return v; 948} 949#endif 950 951#ifdef L_fixdfdi 952DWtype 953__fixdfdi (DFtype a) 954{ 955 if (a < 0) 956 return - __fixunsdfDI (-a); 957 return __fixunsdfDI (a); 958} 959#endif 960 961#ifdef L_fixunssfdi 962#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 963#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 964 965DWtype 966__fixunssfDI (SFtype original_a) 967{ 968 /* Convert the SFtype to a DFtype, because that is surely not going 969 to lose any bits. Some day someone else can write a faster version 970 that avoids converting to DFtype, and verify it really works right. */ 971 DFtype a = original_a; 972 DFtype b; 973 UDWtype v; 974 975 if (a < 0) 976 return 0; 977 978 /* Compute high word of result, as a flonum. */ 979 b = (a / HIGH_WORD_COEFF); 980 /* Convert that to fixed (but not to DWtype!), 981 and shift it into the high word. */ 982 v = (UWtype) b; 983 v <<= WORD_SIZE; 984 /* Remove high part from the DFtype, leaving the low part as flonum. */ 985 a -= (DFtype) v; 986 /* Convert that to fixed (but not to DWtype!) and add it in. 987 Sometimes A comes out negative. This is significant, since 988 A has more bits than a long int does. */ 989 if (a < 0) 990 v -= (UWtype) (- a); 991 else 992 v += (UWtype) a; 993 return v; 994} 995#endif 996 997#ifdef L_fixsfdi 998DWtype 999__fixsfdi (SFtype a) 1000{ 1001 if (a < 0) 1002 return - __fixunssfDI (-a); 1003 return __fixunssfDI (a); 1004} 1005#endif 1006 1007#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 1008#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 1009#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 1010#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 1011 1012XFtype 1013__floatdixf (DWtype u) 1014{ 1015 XFtype d; 1016 1017 d = (Wtype) (u >> WORD_SIZE); 1018 d *= HIGH_HALFWORD_COEFF; 1019 d *= HIGH_HALFWORD_COEFF; 1020 d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 1021 1022 return d; 1023} 1024#endif 1025 1026#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 1027#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 1028#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 1029#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 1030 1031TFtype 1032__floatditf (DWtype u) 1033{ 1034 TFtype d; 1035 1036 d = (Wtype) (u >> WORD_SIZE); 1037 d *= HIGH_HALFWORD_COEFF; 1038 d *= HIGH_HALFWORD_COEFF; 1039 d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 1040 1041 return d; 1042} 1043#endif 1044 1045#ifdef L_floatdidf 1046#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 1047#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 1048#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 1049 1050DFtype 1051__floatdidf (DWtype u) 1052{ 1053 DFtype d; 1054 1055 d = (Wtype) (u >> WORD_SIZE); 1056 d *= HIGH_HALFWORD_COEFF; 1057 d *= HIGH_HALFWORD_COEFF; 1058 d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 1059 1060 return d; 1061} 1062#endif 1063 1064#ifdef L_floatdisf 1065#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 1066#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 1067#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 1068#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT) 1069 1070/* Define codes for all the float formats that we know of. Note 1071 that this is copied from real.h. */ 1072 1073#define UNKNOWN_FLOAT_FORMAT 0 1074#define IEEE_FLOAT_FORMAT 1 1075#define VAX_FLOAT_FORMAT 2 1076#define IBM_FLOAT_FORMAT 3 1077 1078/* Default to IEEE float if not specified. Nearly all machines use it. */ 1079#ifndef HOST_FLOAT_FORMAT 1080#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT 1081#endif 1082 1083#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT 1084#define DF_SIZE 53 1085#define SF_SIZE 24 1086#endif 1087 1088#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT 1089#define DF_SIZE 56 1090#define SF_SIZE 24 1091#endif 1092 1093#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT 1094#define DF_SIZE 56 1095#define SF_SIZE 24 1096#endif 1097 1098SFtype 1099__floatdisf (DWtype u) 1100{ 1101 /* Do the calculation in DFmode 1102 so that we don't lose any of the precision of the high word 1103 while multiplying it. */ 1104 DFtype f; 1105 1106 /* Protect against double-rounding error. 1107 Represent any low-order bits, that might be truncated in DFmode, 1108 by a bit that won't be lost. The bit can go in anywhere below the 1109 rounding position of the SFmode. A fixed mask and bit position 1110 handles all usual configurations. It doesn't handle the case 1111 of 128-bit DImode, however. */ 1112 if (DF_SIZE < DI_SIZE 1113 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) 1114 { 1115#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE)) 1116 if (! (- ((DWtype) 1 << DF_SIZE) < u 1117 && u < ((DWtype) 1 << DF_SIZE))) 1118 { 1119 if ((UDWtype) u & (REP_BIT - 1)) 1120 { 1121 u &= ~ (REP_BIT - 1); 1122 u |= REP_BIT; 1123 } 1124 } 1125 } 1126 f = (Wtype) (u >> WORD_SIZE); 1127 f *= HIGH_HALFWORD_COEFF; 1128 f *= HIGH_HALFWORD_COEFF; 1129 f += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 1130 1131 return (SFtype) f; 1132} 1133#endif 1134 1135#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96 1136/* Reenable the normal types, in case limits.h needs them. */ 1137#undef char 1138#undef short 1139#undef int 1140#undef long 1141#undef unsigned 1142#undef float 1143#undef double 1144#undef MIN 1145#undef MAX 1146#include <limits.h> 1147 1148UWtype 1149__fixunsxfSI (XFtype a) 1150{ 1151 if (a >= - (DFtype) Wtype_MIN) 1152 return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 1153 return (Wtype) a; 1154} 1155#endif 1156 1157#ifdef L_fixunsdfsi 1158/* Reenable the normal types, in case limits.h needs them. */ 1159#undef char 1160#undef short 1161#undef int 1162#undef long 1163#undef unsigned 1164#undef float 1165#undef double 1166#undef MIN 1167#undef MAX 1168#include <limits.h> 1169 1170UWtype 1171__fixunsdfSI (DFtype a) 1172{ 1173 if (a >= - (DFtype) Wtype_MIN) 1174 return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 1175 return (Wtype) a; 1176} 1177#endif 1178 1179#ifdef L_fixunssfsi 1180/* Reenable the normal types, in case limits.h needs them. */ 1181#undef char 1182#undef short 1183#undef int 1184#undef long 1185#undef unsigned 1186#undef float 1187#undef double 1188#undef MIN 1189#undef MAX 1190#include <limits.h> 1191 1192UWtype 1193__fixunssfSI (SFtype a) 1194{ 1195 if (a >= - (SFtype) Wtype_MIN) 1196 return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 1197 return (Wtype) a; 1198} 1199#endif 1200 1201/* From here on down, the routines use normal data types. */ 1202 1203#define SItype bogus_type 1204#define USItype bogus_type 1205#define DItype bogus_type 1206#define UDItype bogus_type 1207#define SFtype bogus_type 1208#define DFtype bogus_type 1209#undef Wtype 1210#undef UWtype 1211#undef HWtype 1212#undef UHWtype 1213#undef DWtype 1214#undef UDWtype 1215 1216#undef char 1217#undef short 1218#undef int 1219#undef long 1220#undef unsigned 1221#undef float 1222#undef double 1223 1224#ifdef L__gcc_bcmp 1225 1226/* Like bcmp except the sign is meaningful. 1227 Result is negative if S1 is less than S2, 1228 positive if S1 is greater, 0 if S1 and S2 are equal. */ 1229 1230int 1231__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) 1232{ 1233 while (size > 0) 1234 { 1235 unsigned char c1 = *s1++, c2 = *s2++; 1236 if (c1 != c2) 1237 return c1 - c2; 1238 size--; 1239 } 1240 return 0; 1241} 1242 1243#endif 1244 1245/* __eprintf used to be used by GCC's private version of <assert.h>. 1246 We no longer provide that header, but this routine remains in libgcc.a 1247 for binary backward compatibility. Note that it is not included in 1248 the shared version of libgcc. */ 1249#ifdef L_eprintf 1250#ifndef inhibit_libc 1251 1252#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1253#include <stdio.h> 1254 1255void 1256__eprintf (const char *string, const char *expression, 1257 unsigned int line, const char *filename) 1258{ 1259 fprintf (stderr, string, expression, line, filename); 1260 fflush (stderr); 1261 abort (); 1262} 1263 1264#endif 1265#endif 1266 1267#ifdef L_bb 1268 1269#if LONG_TYPE_SIZE == GCOV_TYPE_SIZE 1270typedef long gcov_type; 1271#else 1272typedef long long gcov_type; 1273#endif 1274 1275 1276/* Structure emitted by -a */ 1277struct bb 1278{ 1279 long zero_word; 1280 const char *filename; 1281 gcov_type *counts; 1282 long ncounts; 1283 struct bb *next; 1284 const unsigned long *addresses; 1285 1286 /* Older GCC's did not emit these fields. */ 1287 long nwords; 1288 const char **functions; 1289 const long *line_nums; 1290 const char **filenames; 1291 char *flags; 1292}; 1293 1294#ifndef inhibit_libc 1295 1296/* Simple minded basic block profiling output dumper for 1297 systems that don't provide tcov support. At present, 1298 it requires atexit and stdio. */ 1299 1300#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1301#include <stdio.h> 1302 1303#include "gbl-ctors.h" 1304#include "gcov-io.h" 1305#include <string.h> 1306#ifdef TARGET_HAS_F_SETLKW 1307#include <fcntl.h> 1308#include <errno.h> 1309#endif 1310 1311static struct bb *bb_head; 1312 1313void 1314__bb_exit_func (void) 1315{ 1316 FILE *da_file; 1317 int i; 1318 struct bb *ptr; 1319 1320 if (bb_head == 0) 1321 return; 1322 1323 i = strlen (bb_head->filename) - 3; 1324 1325 1326 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) 1327 { 1328 int firstchar; 1329 1330 /* Make sure the output file exists - 1331 but don't clobber exiting data. */ 1332 if ((da_file = fopen (ptr->filename, "a")) != 0) 1333 fclose (da_file); 1334 1335 /* Need to re-open in order to be able to write from the start. */ 1336 da_file = fopen (ptr->filename, "r+b"); 1337 /* Some old systems might not allow the 'b' mode modifier. 1338 Therefore, try to open without it. This can lead to a race 1339 condition so that when you delete and re-create the file, the 1340 file might be opened in text mode, but then, you shouldn't 1341 delete the file in the first place. */ 1342 if (da_file == 0) 1343 da_file = fopen (ptr->filename, "r+"); 1344 if (da_file == 0) 1345 { 1346 fprintf (stderr, "arc profiling: Can't open output file %s.\n", 1347 ptr->filename); 1348 continue; 1349 } 1350 1351 /* After a fork, another process might try to read and/or write 1352 the same file simultanously. So if we can, lock the file to 1353 avoid race conditions. */ 1354#if defined (TARGET_HAS_F_SETLKW) 1355 { 1356 struct flock s_flock; 1357 1358 s_flock.l_type = F_WRLCK; 1359 s_flock.l_whence = SEEK_SET; 1360 s_flock.l_start = 0; 1361 s_flock.l_len = 1; 1362 s_flock.l_pid = getpid (); 1363 1364 while (fcntl (fileno (da_file), F_SETLKW, &s_flock) 1365 && errno == EINTR); 1366 } 1367#endif 1368 1369 /* If the file is not empty, and the number of counts in it is the 1370 same, then merge them in. */ 1371 firstchar = fgetc (da_file); 1372 if (firstchar == EOF) 1373 { 1374 if (ferror (da_file)) 1375 { 1376 fprintf (stderr, "arc profiling: Can't read output file "); 1377 perror (ptr->filename); 1378 } 1379 } 1380 else 1381 { 1382 long n_counts = 0; 1383 1384 if (ungetc (firstchar, da_file) == EOF) 1385 rewind (da_file); 1386 if (__read_long (&n_counts, da_file, 8) != 0) 1387 { 1388 fprintf (stderr, "arc profiling: Can't read output file %s.\n", 1389 ptr->filename); 1390 continue; 1391 } 1392 1393 if (n_counts == ptr->ncounts) 1394 { 1395 int i; 1396 1397 for (i = 0; i < n_counts; i++) 1398 { 1399 gcov_type v = 0; 1400 1401 if (__read_gcov_type (&v, da_file, 8) != 0) 1402 { 1403 fprintf (stderr, 1404 "arc profiling: Can't read output file %s.\n", 1405 ptr->filename); 1406 break; 1407 } 1408 ptr->counts[i] += v; 1409 } 1410 } 1411 1412 } 1413 1414 rewind (da_file); 1415 1416 /* ??? Should first write a header to the file. Preferably, a 4 byte 1417 magic number, 4 bytes containing the time the program was 1418 compiled, 4 bytes containing the last modification time of the 1419 source file, and 4 bytes indicating the compiler options used. 1420 1421 That way we can easily verify that the proper source/executable/ 1422 data file combination is being used from gcov. */ 1423 1424 if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0) 1425 { 1426 1427 fprintf (stderr, "arc profiling: Error writing output file %s.\n", 1428 ptr->filename); 1429 } 1430 else 1431 { 1432 int j; 1433 gcov_type *count_ptr = ptr->counts; 1434 int ret = 0; 1435 for (j = ptr->ncounts; j > 0; j--) 1436 { 1437 if (__write_gcov_type (*count_ptr, da_file, 8) != 0) 1438 { 1439 ret = 1; 1440 break; 1441 } 1442 count_ptr++; 1443 } 1444 if (ret) 1445 fprintf (stderr, "arc profiling: Error writing output file %s.\n", 1446 ptr->filename); 1447 } 1448 1449 if (fclose (da_file) == EOF) 1450 fprintf (stderr, "arc profiling: Error closing output file %s.\n", 1451 ptr->filename); 1452 } 1453 1454 return; 1455} 1456 1457void 1458__bb_init_func (struct bb *blocks) 1459{ 1460 /* User is supposed to check whether the first word is non-0, 1461 but just in case.... */ 1462 1463 if (blocks->zero_word) 1464 return; 1465 1466 /* Initialize destructor. */ 1467 if (!bb_head) 1468 atexit (__bb_exit_func); 1469 1470 /* Set up linked list. */ 1471 blocks->zero_word = 1; 1472 blocks->next = bb_head; 1473 bb_head = blocks; 1474} 1475 1476/* Called before fork or exec - write out profile information gathered so 1477 far and reset it to zero. This avoids duplication or loss of the 1478 profile information gathered so far. */ 1479void 1480__bb_fork_func (void) 1481{ 1482 struct bb *ptr; 1483 1484 __bb_exit_func (); 1485 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) 1486 { 1487 long i; 1488 for (i = ptr->ncounts - 1; i >= 0; i--) 1489 ptr->counts[i] = 0; 1490 } 1491} 1492 1493#endif /* not inhibit_libc */ 1494#endif /* L_bb */ 1495 1496#ifdef L_clear_cache 1497/* Clear part of an instruction cache. */ 1498 1499#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH) 1500 1501void 1502__clear_cache (char *beg __attribute__((__unused__)), 1503 char *end __attribute__((__unused__))) 1504{ 1505#ifdef CLEAR_INSN_CACHE 1506 CLEAR_INSN_CACHE (beg, end); 1507#else 1508#ifdef INSN_CACHE_SIZE 1509 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH]; 1510 static int initialized; 1511 int offset; 1512 void *start_addr 1513 void *end_addr; 1514 typedef (*function_ptr) (void); 1515 1516#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16 1517 /* It's cheaper to clear the whole cache. 1518 Put in a series of jump instructions so that calling the beginning 1519 of the cache will clear the whole thing. */ 1520 1521 if (! initialized) 1522 { 1523 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1524 & -INSN_CACHE_LINE_WIDTH); 1525 int end_ptr = ptr + INSN_CACHE_SIZE; 1526 1527 while (ptr < end_ptr) 1528 { 1529 *(INSTRUCTION_TYPE *)ptr 1530 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH; 1531 ptr += INSN_CACHE_LINE_WIDTH; 1532 } 1533 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION; 1534 1535 initialized = 1; 1536 } 1537 1538 /* Call the beginning of the sequence. */ 1539 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1540 & -INSN_CACHE_LINE_WIDTH)) 1541 ()); 1542 1543#else /* Cache is large. */ 1544 1545 if (! initialized) 1546 { 1547 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) 1548 & -INSN_CACHE_LINE_WIDTH); 1549 1550 while (ptr < (int) array + sizeof array) 1551 { 1552 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION; 1553 ptr += INSN_CACHE_LINE_WIDTH; 1554 } 1555 1556 initialized = 1; 1557 } 1558 1559 /* Find the location in array that occupies the same cache line as BEG. */ 1560 1561 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1); 1562 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1) 1563 & -INSN_CACHE_PLANE_SIZE) 1564 + offset); 1565 1566 /* Compute the cache alignment of the place to stop clearing. */ 1567#if 0 /* This is not needed for gcc's purposes. */ 1568 /* If the block to clear is bigger than a cache plane, 1569 we clear the entire cache, and OFFSET is already correct. */ 1570 if (end < beg + INSN_CACHE_PLANE_SIZE) 1571#endif 1572 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1) 1573 & -INSN_CACHE_LINE_WIDTH) 1574 & (INSN_CACHE_PLANE_SIZE - 1)); 1575 1576#if INSN_CACHE_DEPTH > 1 1577 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset; 1578 if (end_addr <= start_addr) 1579 end_addr += INSN_CACHE_PLANE_SIZE; 1580 1581 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++) 1582 { 1583 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE; 1584 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE; 1585 1586 while (addr != stop) 1587 { 1588 /* Call the return instruction at ADDR. */ 1589 ((function_ptr) addr) (); 1590 1591 addr += INSN_CACHE_LINE_WIDTH; 1592 } 1593 } 1594#else /* just one plane */ 1595 do 1596 { 1597 /* Call the return instruction at START_ADDR. */ 1598 ((function_ptr) start_addr) (); 1599 1600 start_addr += INSN_CACHE_LINE_WIDTH; 1601 } 1602 while ((start_addr % INSN_CACHE_SIZE) != offset); 1603#endif /* just one plane */ 1604#endif /* Cache is large */ 1605#endif /* Cache exists */ 1606#endif /* CLEAR_INSN_CACHE */ 1607} 1608 1609#endif /* L_clear_cache */ 1610 1611#ifdef L_trampoline 1612 1613/* Jump to a trampoline, loading the static chain address. */ 1614 1615#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) 1616 1617long 1618getpagesize (void) 1619{ 1620#ifdef _ALPHA_ 1621 return 8192; 1622#else 1623 return 4096; 1624#endif 1625} 1626 1627#ifdef __i386__ 1628extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); 1629#endif 1630 1631int 1632mprotect (char *addr, int len, int prot) 1633{ 1634 int np, op; 1635 1636 if (prot == 7) 1637 np = 0x40; 1638 else if (prot == 5) 1639 np = 0x20; 1640 else if (prot == 4) 1641 np = 0x10; 1642 else if (prot == 3) 1643 np = 0x04; 1644 else if (prot == 1) 1645 np = 0x02; 1646 else if (prot == 0) 1647 np = 0x01; 1648 1649 if (VirtualProtect (addr, len, np, &op)) 1650 return 0; 1651 else 1652 return -1; 1653} 1654 1655#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ 1656 1657#ifdef TRANSFER_FROM_TRAMPOLINE 1658TRANSFER_FROM_TRAMPOLINE 1659#endif 1660 1661#if defined (NeXT) && defined (__MACH__) 1662 1663/* Make stack executable so we can call trampolines on stack. 1664 This is called from INITIALIZE_TRAMPOLINE in next.h. */ 1665#ifdef NeXTStep21 1666 #include <mach.h> 1667#else 1668 #include <mach/mach.h> 1669#endif 1670 1671void 1672__enable_execute_stack (char *addr) 1673{ 1674 kern_return_t r; 1675 char *eaddr = addr + TRAMPOLINE_SIZE; 1676 vm_address_t a = (vm_address_t) addr; 1677 1678 /* turn on execute access on stack */ 1679 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL); 1680 if (r != KERN_SUCCESS) 1681 { 1682 mach_error("vm_protect VM_PROT_ALL", r); 1683 exit(1); 1684 } 1685 1686 /* We inline the i-cache invalidation for speed */ 1687 1688#ifdef CLEAR_INSN_CACHE 1689 CLEAR_INSN_CACHE (addr, eaddr); 1690#else 1691 __clear_cache ((int) addr, (int) eaddr); 1692#endif 1693} 1694 1695#endif /* defined (NeXT) && defined (__MACH__) */ 1696 1697#ifdef __convex__ 1698 1699/* Make stack executable so we can call trampolines on stack. 1700 This is called from INITIALIZE_TRAMPOLINE in convex.h. */ 1701 1702#include <sys/mman.h> 1703#include <sys/vmparam.h> 1704#include <machine/machparam.h> 1705 1706void 1707__enable_execute_stack (void) 1708{ 1709 int fp; 1710 static unsigned lowest = USRSTACK; 1711 unsigned current = (unsigned) &fp & -NBPG; 1712 1713 if (lowest > current) 1714 { 1715 unsigned len = lowest - current; 1716 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); 1717 lowest = current; 1718 } 1719 1720 /* Clear instruction cache in case an old trampoline is in it. */ 1721 asm ("pich"); 1722} 1723#endif /* __convex__ */ 1724 1725#ifdef __sysV88__ 1726 1727/* Modified from the convex -code above. */ 1728 1729#include <sys/param.h> 1730#include <errno.h> 1731#include <sys/m88kbcs.h> 1732 1733void 1734__enable_execute_stack (void) 1735{ 1736 int save_errno; 1737 static unsigned long lowest = USRSTACK; 1738 unsigned long current = (unsigned long) &save_errno & -NBPC; 1739 1740 /* Ignore errno being set. memctl sets errno to EINVAL whenever the 1741 address is seen as 'negative'. That is the case with the stack. */ 1742 1743 save_errno=errno; 1744 if (lowest > current) 1745 { 1746 unsigned len=lowest-current; 1747 memctl(current,len,MCT_TEXT); 1748 lowest = current; 1749 } 1750 else 1751 memctl(current,NBPC,MCT_TEXT); 1752 errno=save_errno; 1753} 1754 1755#endif /* __sysV88__ */ 1756 1757#ifdef __sysV68__ 1758 1759#include <sys/signal.h> 1760#include <errno.h> 1761 1762/* Motorola forgot to put memctl.o in the libp version of libc881.a, 1763 so define it here, because we need it in __clear_insn_cache below */ 1764/* On older versions of this OS, no memctl or MCT_TEXT are defined; 1765 hence we enable this stuff only if MCT_TEXT is #define'd. */ 1766 1767#ifdef MCT_TEXT 1768asm("\n\ 1769 global memctl\n\ 1770memctl:\n\ 1771 movq &75,%d0\n\ 1772 trap &0\n\ 1773 bcc.b noerror\n\ 1774 jmp cerror%\n\ 1775noerror:\n\ 1776 movq &0,%d0\n\ 1777 rts"); 1778#endif 1779 1780/* Clear instruction cache so we can call trampolines on stack. 1781 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */ 1782 1783void 1784__clear_insn_cache (void) 1785{ 1786#ifdef MCT_TEXT 1787 int save_errno; 1788 1789 /* Preserve errno, because users would be surprised to have 1790 errno changing without explicitly calling any system-call. */ 1791 save_errno = errno; 1792 1793 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 1794 No need to use an address derived from _start or %sp, as 0 works also. */ 1795 memctl(0, 4096, MCT_TEXT); 1796 errno = save_errno; 1797#endif 1798} 1799 1800#endif /* __sysV68__ */ 1801 1802#ifdef __pyr__ 1803 1804#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 1805#include <stdio.h> 1806#include <sys/mman.h> 1807#include <sys/types.h> 1808#include <sys/param.h> 1809#include <sys/vmmac.h> 1810 1811/* Modified from the convex -code above. 1812 mremap promises to clear the i-cache. */ 1813 1814void 1815__enable_execute_stack (void) 1816{ 1817 int fp; 1818 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ, 1819 PROT_READ|PROT_WRITE|PROT_EXEC)) 1820 { 1821 perror ("mprotect in __enable_execute_stack"); 1822 fflush (stderr); 1823 abort (); 1824 } 1825} 1826#endif /* __pyr__ */ 1827 1828#if defined (sony_news) && defined (SYSTYPE_BSD) 1829 1830#include <stdio.h> 1831#include <sys/types.h> 1832#include <sys/param.h> 1833#include <syscall.h> 1834#include <machine/sysnews.h> 1835 1836/* cacheflush function for NEWS-OS 4.2. 1837 This function is called from trampoline-initialize code 1838 defined in config/mips/mips.h. */ 1839 1840void 1841cacheflush (char *beg, int size, int flag) 1842{ 1843 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE)) 1844 { 1845 perror ("cache_flush"); 1846 fflush (stderr); 1847 abort (); 1848 } 1849} 1850 1851#endif /* sony_news */ 1852#endif /* L_trampoline */ 1853 1854#ifndef __CYGWIN__ 1855#ifdef L__main 1856 1857#include "gbl-ctors.h" 1858/* Some systems use __main in a way incompatible with its use in gcc, in these 1859 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 1860 give the same symbol without quotes for an alternative entry point. You 1861 must define both, or neither. */ 1862#ifndef NAME__MAIN 1863#define NAME__MAIN "__main" 1864#define SYMBOL__MAIN __main 1865#endif 1866 1867#ifdef INIT_SECTION_ASM_OP 1868#undef HAS_INIT_SECTION 1869#define HAS_INIT_SECTION 1870#endif 1871 1872#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) 1873 1874/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this 1875 code to run constructors. In that case, we need to handle EH here, too. */ 1876 1877#ifdef EH_FRAME_SECTION_NAME 1878#include "unwind-dw2-fde.h" 1879extern unsigned char __EH_FRAME_BEGIN__[]; 1880#endif 1881 1882/* Run all the global destructors on exit from the program. */ 1883 1884void 1885__do_global_dtors (void) 1886{ 1887#ifdef DO_GLOBAL_DTORS_BODY 1888 DO_GLOBAL_DTORS_BODY; 1889#else 1890 static func_ptr *p = __DTOR_LIST__ + 1; 1891 while (*p) 1892 { 1893 p++; 1894 (*(p-1)) (); 1895 } 1896#endif 1897#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) 1898 { 1899 static int completed = 0; 1900 if (! completed) 1901 { 1902 completed = 1; 1903 __deregister_frame_info (__EH_FRAME_BEGIN__); 1904 } 1905 } 1906#endif 1907} 1908#endif 1909 1910#ifndef HAS_INIT_SECTION 1911/* Run all the global constructors on entry to the program. */ 1912 1913void 1914__do_global_ctors (void) 1915{ 1916#ifdef EH_FRAME_SECTION_NAME 1917 { 1918 static struct object object; 1919 __register_frame_info (__EH_FRAME_BEGIN__, &object); 1920 } 1921#endif 1922 DO_GLOBAL_CTORS_BODY; 1923 atexit (__do_global_dtors); 1924} 1925#endif /* no HAS_INIT_SECTION */ 1926 1927#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) 1928/* Subroutine called automatically by `main'. 1929 Compiling a global function named `main' 1930 produces an automatic call to this function at the beginning. 1931 1932 For many systems, this routine calls __do_global_ctors. 1933 For systems which support a .init section we use the .init section 1934 to run __do_global_ctors, so we need not do anything here. */ 1935 1936void 1937SYMBOL__MAIN () 1938{ 1939 /* Support recursive calls to `main': run initializers just once. */ 1940 static int initialized; 1941 if (! initialized) 1942 { 1943 initialized = 1; 1944 __do_global_ctors (); 1945 } 1946} 1947#endif /* no HAS_INIT_SECTION or INVOKE__main */ 1948 1949#endif /* L__main */ 1950#endif /* __CYGWIN__ */ 1951 1952#ifdef L_ctors 1953 1954#include "gbl-ctors.h" 1955 1956/* Provide default definitions for the lists of constructors and 1957 destructors, so that we don't get linker errors. These symbols are 1958 intentionally bss symbols, so that gld and/or collect will provide 1959 the right values. */ 1960 1961/* We declare the lists here with two elements each, 1962 so that they are valid empty lists if no other definition is loaded. 1963 1964 If we are using the old "set" extensions to have the gnu linker 1965 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ 1966 must be in the bss/common section. 1967 1968 Long term no port should use those extensions. But many still do. */ 1969#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 1970#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) 1971func_ptr __CTOR_LIST__[2] = {0, 0}; 1972func_ptr __DTOR_LIST__[2] = {0, 0}; 1973#else 1974func_ptr __CTOR_LIST__[2]; 1975func_ptr __DTOR_LIST__[2]; 1976#endif 1977#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 1978#endif /* L_ctors */ 1979 1980#ifdef L_exit 1981 1982#include "gbl-ctors.h" 1983 1984#ifdef NEED_ATEXIT 1985 1986#ifndef ON_EXIT 1987 1988# include <errno.h> 1989 1990static func_ptr *atexit_chain = 0; 1991static long atexit_chain_length = 0; 1992static volatile long last_atexit_chain_slot = -1; 1993 1994int 1995atexit (func_ptr func) 1996{ 1997 if (++last_atexit_chain_slot == atexit_chain_length) 1998 { 1999 atexit_chain_length += 32; 2000 if (atexit_chain) 2001 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length 2002 * sizeof (func_ptr)); 2003 else 2004 atexit_chain = (func_ptr *) malloc (atexit_chain_length 2005 * sizeof (func_ptr)); 2006 if (! atexit_chain) 2007 { 2008 atexit_chain_length = 0; 2009 last_atexit_chain_slot = -1; 2010 errno = ENOMEM; 2011 return (-1); 2012 } 2013 } 2014 atexit_chain[last_atexit_chain_slot] = func; 2015 return (0); 2016} 2017 2018extern void _cleanup (void); 2019extern void _exit (int) __attribute__ ((__noreturn__)); 2020 2021void 2022exit (int status) 2023{ 2024 if (atexit_chain) 2025 { 2026 for ( ; last_atexit_chain_slot-- >= 0; ) 2027 { 2028 (*atexit_chain[last_atexit_chain_slot + 1]) (); 2029 atexit_chain[last_atexit_chain_slot + 1] = 0; 2030 } 2031 free (atexit_chain); 2032 atexit_chain = 0; 2033 } 2034#ifdef EXIT_BODY 2035 EXIT_BODY; 2036#else 2037 _cleanup (); 2038#endif 2039 _exit (status); 2040} 2041 2042#else /* ON_EXIT */ 2043 2044/* Simple; we just need a wrapper for ON_EXIT. */ 2045int 2046atexit (func_ptr func) 2047{ 2048 return ON_EXIT (func); 2049} 2050 2051#endif /* ON_EXIT */ 2052#endif /* NEED_ATEXIT */ 2053 2054#endif /* L_exit */ 2055