libgcc2.c revision 146906
118334Speter/* More subroutines needed by GCC output code on some machines. */ 218334Speter/* Compile this one with gcc. */ 390280Sobrien/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 4132727Skan 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 518334Speter 690280SobrienThis file is part of GCC. 718334Speter 890280SobrienGCC is free software; you can redistribute it and/or modify it under 990280Sobrienthe terms of the GNU General Public License as published by the Free 1090280SobrienSoftware Foundation; either version 2, or (at your option) any later 1190280Sobrienversion. 1218334Speter 1390280SobrienIn addition to the permissions in the GNU General Public License, the 1490280SobrienFree Software Foundation gives you unlimited permission to link the 1590280Sobriencompiled version of this file into combinations with other programs, 1690280Sobrienand to distribute those combinations without any restriction coming 1790280Sobrienfrom the use of this file. (The General Public License restrictions 1890280Sobriendo apply in other respects; for example, they cover modification of 1990280Sobrienthe file, and distribution when not linked into a combine 2090280Sobrienexecutable.) 2118334Speter 2290280SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 2390280SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 2490280SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2590280Sobrienfor more details. 2690280Sobrien 2718334SpeterYou should have received a copy of the GNU General Public License 2890280Sobrienalong with GCC; see the file COPYING. If not, write to the Free 2990280SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 3090280Sobrien02111-1307, USA. */ 3118334Speter 32132727Skan 33132727Skan/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is 34132727Skan supposedly valid even though this is a "target" file. */ 35132727Skan#include "auto-host.h" 36132727Skan 3718334Speter/* It is incorrect to include config.h here, because this file is being 3818334Speter compiled for the target, and hence definitions concerning only the host 3918334Speter do not apply. */ 4018334Speter#include "tconfig.h" 4190280Sobrien#include "tsystem.h" 42132727Skan#include "coretypes.h" 43132727Skan#include "tm.h" 4450600Sobrien 4518334Speter/* Don't use `fancy_abort' here even if config.h says to use it. */ 4618334Speter#ifdef abort 4718334Speter#undef abort 4818334Speter#endif 4918334Speter 50132727Skan#ifdef HAVE_GAS_HIDDEN 51132727Skan#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) 52132727Skan#else 53132727Skan#define ATTRIBUTE_HIDDEN 54132727Skan#endif 55132727Skan 5690280Sobrien#include "libgcc2.h" 5790280Sobrien 58117404Skan#ifdef DECLARE_LIBRARY_RENAMES 59117404Skan DECLARE_LIBRARY_RENAMES 6018334Speter#endif 61117404Skan 62117404Skan#if defined (L_negdi2) 6390280SobrienDWtype 6490280Sobrien__negdi2 (DWtype u) 6590280Sobrien{ 66132727Skan const DWunion uu = {.ll = u}; 67132727Skan const DWunion w = { {.low = -uu.s.low, 68132727Skan .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } }; 6918334Speter 7090280Sobrien return w.ll; 7190280Sobrien} 7250600Sobrien#endif 7350600Sobrien 7490280Sobrien#ifdef L_addvsi3 7590280SobrienWtype 76146906Skan__addvSI3 (Wtype a, Wtype b) 7790280Sobrien{ 78132727Skan const Wtype w = a + b; 7918334Speter 8090280Sobrien if (b >= 0 ? w < a : w > a) 8190280Sobrien abort (); 8290280Sobrien 8390280Sobrien return w; 8490280Sobrien} 85146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 86146906SkanSItype 87146906Skan__addvsi3 (SItype a, SItype b) 88146906Skan{ 89146906Skan const SItype w = a + b; 90146906Skan 91146906Skan if (b >= 0 ? w < a : w > a) 92146906Skan abort (); 93146906Skan 94146906Skan return w; 95146906Skan} 96146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 9718334Speter#endif 9890280Sobrien 9990280Sobrien#ifdef L_addvdi3 10090280SobrienDWtype 101146906Skan__addvDI3 (DWtype a, DWtype b) 10290280Sobrien{ 103132727Skan const DWtype w = a + b; 10418334Speter 10590280Sobrien if (b >= 0 ? w < a : w > a) 10690280Sobrien abort (); 10790280Sobrien 10890280Sobrien return w; 10990280Sobrien} 11052561Sobrien#endif 11190280Sobrien 11290280Sobrien#ifdef L_subvsi3 11390280SobrienWtype 114146906Skan__subvSI3 (Wtype a, Wtype b) 11590280Sobrien{ 116146906Skan const Wtype w = a - b; 11752561Sobrien 11890280Sobrien if (b >= 0 ? w > a : w < a) 11990280Sobrien abort (); 12018334Speter 12190280Sobrien return w; 12290280Sobrien} 123146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 124146906SkanSItype 125146906Skan__subvsi3 (SItype a, SItype b) 126146906Skan{ 127146906Skan const SItype w = a - b; 128146906Skan 129146906Skan if (b >= 0 ? w > a : w < a) 130146906Skan abort (); 131146906Skan 132146906Skan return w; 133146906Skan} 134146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 13590280Sobrien#endif 13690280Sobrien 13790280Sobrien#ifdef L_subvdi3 13890280SobrienDWtype 139146906Skan__subvDI3 (DWtype a, DWtype b) 14090280Sobrien{ 141132727Skan const DWtype w = a - b; 14218334Speter 14390280Sobrien if (b >= 0 ? w > a : w < a) 14490280Sobrien abort (); 14590280Sobrien 14690280Sobrien return w; 14790280Sobrien} 14818334Speter#endif 14990280Sobrien 15090280Sobrien#ifdef L_mulvsi3 151132727Skan#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 15290280SobrienWtype 153146906Skan__mulvSI3 (Wtype a, Wtype b) 15490280Sobrien{ 155132727Skan const DWtype w = (DWtype) a * (DWtype) b; 15618334Speter 157146906Skan if ((Wtype) (w >> WORD_SIZE) != (Wtype) w >> (WORD_SIZE - 1)) 15890280Sobrien abort (); 15918334Speter 16090280Sobrien return w; 16190280Sobrien} 162146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 163146906Skan#undef WORD_SIZE 164146906Skan#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 165146906SkanSItype 166146906Skan__mulvsi3 (SItype a, SItype b) 167146906Skan{ 168146906Skan const DItype w = (DItype) a * (DItype) b; 169146906Skan 170146906Skan if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1)) 171146906Skan abort (); 172146906Skan 173146906Skan return w; 174146906Skan} 175146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 17690280Sobrien#endif 17790280Sobrien 17890280Sobrien#ifdef L_negvsi2 17990280SobrienWtype 180146906Skan__negvSI2 (Wtype a) 18190280Sobrien{ 182132727Skan const Wtype w = -a; 18318334Speter 18490280Sobrien if (a >= 0 ? w > 0 : w < 0) 18590280Sobrien abort (); 18618334Speter 18790280Sobrien return w; 18890280Sobrien} 189146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 190146906SkanSItype 191146906Skan__negvsi2 (SItype a) 192146906Skan{ 193146906Skan const SItype w = -a; 194146906Skan 195146906Skan if (a >= 0 ? w > 0 : w < 0) 196146906Skan abort (); 197146906Skan 198146906Skan return w; 199146906Skan} 200146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 20118334Speter#endif 20290280Sobrien 20390280Sobrien#ifdef L_negvdi2 20490280SobrienDWtype 205146906Skan__negvDI2 (DWtype a) 20690280Sobrien{ 207132727Skan const DWtype w = -a; 20818334Speter 20990280Sobrien if (a >= 0 ? w > 0 : w < 0) 21090280Sobrien abort (); 21190280Sobrien 212117404Skan return w; 21390280Sobrien} 21490280Sobrien#endif 21590280Sobrien 21690280Sobrien#ifdef L_absvsi2 21790280SobrienWtype 218146906Skan__absvSI2 (Wtype a) 21918334Speter{ 220117404Skan Wtype w = a; 22118334Speter 222117404Skan if (a < 0) 22390280Sobrien#ifdef L_negvsi2 224146906Skan w = __negvSI2 (a); 225146906Skan#else 226146906Skan w = -a; 227146906Skan 228146906Skan if (w < 0) 229146906Skan abort (); 230146906Skan#endif 231146906Skan 232146906Skan return w; 233146906Skan} 234146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 235146906SkanSItype 236146906Skan__absvsi2 (SItype a) 237146906Skan{ 238146906Skan SItype w = a; 239146906Skan 240146906Skan if (a < 0) 241146906Skan#ifdef L_negvsi2 242117404Skan w = __negvsi2 (a); 24390280Sobrien#else 244117404Skan w = -a; 24518334Speter 246117404Skan if (w < 0) 247117404Skan abort (); 24890280Sobrien#endif 24918334Speter 25090280Sobrien return w; 25190280Sobrien} 252146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 25390280Sobrien#endif 25490280Sobrien 25590280Sobrien#ifdef L_absvdi2 25690280SobrienDWtype 257146906Skan__absvDI2 (DWtype a) 25890280Sobrien{ 259117404Skan DWtype w = a; 26018334Speter 261117404Skan if (a < 0) 262132727Skan#ifdef L_negvdi2 263146906Skan w = __negvDI2 (a); 26490280Sobrien#else 265117404Skan w = -a; 26690280Sobrien 267117404Skan if (w < 0) 268117404Skan abort (); 26918334Speter#endif 27090280Sobrien 271117404Skan return w; 27290280Sobrien} 27318334Speter#endif 27418334Speter 27590280Sobrien#ifdef L_mulvdi3 276132727Skan#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 27790280SobrienDWtype 278146906Skan__mulvDI3 (DWtype u, DWtype v) 27918334Speter{ 280132727Skan /* The unchecked multiplication needs 3 Wtype x Wtype multiplications, 281132727Skan but the checked multiplication needs only two. */ 282132727Skan const DWunion uu = {.ll = u}; 283132727Skan const DWunion vv = {.ll = v}; 28418334Speter 285132727Skan if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1)) 286132727Skan { 287132727Skan /* u fits in a single Wtype. */ 288132727Skan if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) 289132727Skan { 290132727Skan /* v fits in a single Wtype as well. */ 291132727Skan /* A single multiplication. No overflow risk. */ 292132727Skan return (DWtype) uu.s.low * (DWtype) vv.s.low; 293132727Skan } 294132727Skan else 295132727Skan { 296132727Skan /* Two multiplications. */ 297132727Skan DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low 298132727Skan * (UDWtype) (UWtype) vv.s.low}; 299132727Skan DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low 300132727Skan * (UDWtype) (UWtype) vv.s.high}; 30118334Speter 302132727Skan if (vv.s.high < 0) 303132727Skan w1.s.high -= uu.s.low; 304132727Skan if (uu.s.low < 0) 305132727Skan w1.ll -= vv.ll; 306132727Skan w1.ll += (UWtype) w0.s.high; 307132727Skan if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) 308132727Skan { 309132727Skan w0.s.high = w1.s.low; 310132727Skan return w0.ll; 311132727Skan } 312132727Skan } 313132727Skan } 314132727Skan else 315132727Skan { 316132727Skan if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) 317132727Skan { 318132727Skan /* v fits into a single Wtype. */ 319132727Skan /* Two multiplications. */ 320132727Skan DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low 321132727Skan * (UDWtype) (UWtype) vv.s.low}; 322132727Skan DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high 323132727Skan * (UDWtype) (UWtype) vv.s.low}; 32418334Speter 325132727Skan if (uu.s.high < 0) 326132727Skan w1.s.high -= vv.s.low; 327132727Skan if (vv.s.low < 0) 328132727Skan w1.ll -= uu.ll; 329132727Skan w1.ll += (UWtype) w0.s.high; 330132727Skan if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) 331132727Skan { 332132727Skan w0.s.high = w1.s.low; 333132727Skan return w0.ll; 334132727Skan } 335132727Skan } 336132727Skan else 337132727Skan { 338132727Skan /* A few sign checks and a single multiplication. */ 339132727Skan if (uu.s.high >= 0) 340132727Skan { 341132727Skan if (vv.s.high >= 0) 342132727Skan { 343132727Skan if (uu.s.high == 0 && vv.s.high == 0) 344132727Skan { 345132727Skan const DWtype w = (UDWtype) (UWtype) uu.s.low 346132727Skan * (UDWtype) (UWtype) vv.s.low; 347132727Skan if (__builtin_expect (w >= 0, 1)) 348132727Skan return w; 349132727Skan } 350132727Skan } 351132727Skan else 352132727Skan { 353132727Skan if (uu.s.high == 0 && vv.s.high == (Wtype) -1) 354132727Skan { 355132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 356132727Skan * (UDWtype) (UWtype) vv.s.low}; 357132727Skan 358132727Skan ww.s.high -= uu.s.low; 359132727Skan if (__builtin_expect (ww.s.high < 0, 1)) 360132727Skan return ww.ll; 361132727Skan } 362132727Skan } 363132727Skan } 364132727Skan else 365132727Skan { 366132727Skan if (vv.s.high >= 0) 367132727Skan { 368132727Skan if (uu.s.high == (Wtype) -1 && vv.s.high == 0) 369132727Skan { 370132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 371132727Skan * (UDWtype) (UWtype) vv.s.low}; 372132727Skan 373132727Skan ww.s.high -= vv.s.low; 374132727Skan if (__builtin_expect (ww.s.high < 0, 1)) 375132727Skan return ww.ll; 376132727Skan } 377132727Skan } 378132727Skan else 379132727Skan { 380132727Skan if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1) 381132727Skan { 382132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 383132727Skan * (UDWtype) (UWtype) vv.s.low}; 384132727Skan 385132727Skan ww.s.high -= uu.s.low; 386132727Skan ww.s.high -= vv.s.low; 387132727Skan if (__builtin_expect (ww.s.high >= 0, 1)) 388132727Skan return ww.ll; 389132727Skan } 390132727Skan } 391132727Skan } 392132727Skan } 393132727Skan } 394132727Skan 395132727Skan /* Overflow. */ 396132727Skan abort (); 39718334Speter} 39818334Speter#endif 39918334Speter 40090280Sobrien 401132727Skan/* Unless shift functions are defined with full ANSI prototypes, 40250600Sobrien parameter b will be promoted to int if word_type is smaller than an int. */ 40318334Speter#ifdef L_lshrdi3 40490280SobrienDWtype 40590280Sobrien__lshrdi3 (DWtype u, word_type b) 40618334Speter{ 40718334Speter if (b == 0) 40818334Speter return u; 40918334Speter 410132727Skan const DWunion uu = {.ll = u}; 411132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 412132727Skan DWunion w; 41318334Speter 41418334Speter if (bm <= 0) 41518334Speter { 41618334Speter w.s.high = 0; 41790280Sobrien w.s.low = (UWtype) uu.s.high >> -bm; 41818334Speter } 41918334Speter else 42018334Speter { 421132727Skan const UWtype carries = (UWtype) uu.s.high << bm; 42290280Sobrien 42390280Sobrien w.s.high = (UWtype) uu.s.high >> b; 42490280Sobrien w.s.low = ((UWtype) uu.s.low >> b) | carries; 42518334Speter } 42618334Speter 42718334Speter return w.ll; 42818334Speter} 42918334Speter#endif 43018334Speter 43118334Speter#ifdef L_ashldi3 43290280SobrienDWtype 43390280Sobrien__ashldi3 (DWtype u, word_type b) 43418334Speter{ 43518334Speter if (b == 0) 43618334Speter return u; 43718334Speter 438132727Skan const DWunion uu = {.ll = u}; 439132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 440132727Skan DWunion w; 44118334Speter 44218334Speter if (bm <= 0) 44318334Speter { 44418334Speter w.s.low = 0; 44590280Sobrien w.s.high = (UWtype) uu.s.low << -bm; 44618334Speter } 44718334Speter else 44818334Speter { 449132727Skan const UWtype carries = (UWtype) uu.s.low >> bm; 45090280Sobrien 45190280Sobrien w.s.low = (UWtype) uu.s.low << b; 45290280Sobrien w.s.high = ((UWtype) uu.s.high << b) | carries; 45318334Speter } 45418334Speter 45518334Speter return w.ll; 45618334Speter} 45718334Speter#endif 45818334Speter 45918334Speter#ifdef L_ashrdi3 46090280SobrienDWtype 46190280Sobrien__ashrdi3 (DWtype u, word_type b) 46218334Speter{ 46318334Speter if (b == 0) 46418334Speter return u; 46518334Speter 466132727Skan const DWunion uu = {.ll = u}; 467132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 468132727Skan DWunion w; 46918334Speter 47018334Speter if (bm <= 0) 47118334Speter { 47218334Speter /* w.s.high = 1..1 or 0..0 */ 47390280Sobrien w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1); 47418334Speter w.s.low = uu.s.high >> -bm; 47518334Speter } 47618334Speter else 47718334Speter { 478132727Skan const UWtype carries = (UWtype) uu.s.high << bm; 47990280Sobrien 48018334Speter w.s.high = uu.s.high >> b; 48190280Sobrien w.s.low = ((UWtype) uu.s.low >> b) | carries; 48218334Speter } 48318334Speter 48418334Speter return w.ll; 48518334Speter} 48618334Speter#endif 48718334Speter 488132727Skan#ifdef L_ffssi2 489132727Skan#undef int 490132727Skanextern int __ffsSI2 (UWtype u); 491132727Skanint 492132727Skan__ffsSI2 (UWtype u) 493132727Skan{ 494132727Skan UWtype count; 495132727Skan 496132727Skan if (u == 0) 497132727Skan return 0; 498132727Skan 499132727Skan count_trailing_zeros (count, u); 500132727Skan return count + 1; 501132727Skan} 502132727Skan#endif 503132727Skan 50418334Speter#ifdef L_ffsdi2 505132727Skan#undef int 506132727Skanextern int __ffsDI2 (DWtype u); 507132727Skanint 508132727Skan__ffsDI2 (DWtype u) 50918334Speter{ 510132727Skan const DWunion uu = {.ll = u}; 51190280Sobrien UWtype word, count, add; 51290280Sobrien 51390280Sobrien if (uu.s.low != 0) 51490280Sobrien word = uu.s.low, add = 0; 51590280Sobrien else if (uu.s.high != 0) 51690280Sobrien word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype); 51790280Sobrien else 51890280Sobrien return 0; 51990280Sobrien 52090280Sobrien count_trailing_zeros (count, word); 52190280Sobrien return count + add + 1; 52218334Speter} 52318334Speter#endif 52418334Speter 52518334Speter#ifdef L_muldi3 52690280SobrienDWtype 52790280Sobrien__muldi3 (DWtype u, DWtype v) 52818334Speter{ 529132727Skan const DWunion uu = {.ll = u}; 530132727Skan const DWunion vv = {.ll = v}; 531132727Skan DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; 53218334Speter 53390280Sobrien w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high 53490280Sobrien + (UWtype) uu.s.high * (UWtype) vv.s.low); 53518334Speter 53618334Speter return w.ll; 53718334Speter} 53818334Speter#endif 53918334Speter 540117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 541117404Skan defined (L_umoddi3) || defined (L_moddi3)) 542117404Skan#if defined (sdiv_qrnnd) 543117404Skan#define L_udiv_w_sdiv 544117404Skan#endif 545117404Skan#endif 546117404Skan 54718334Speter#ifdef L_udiv_w_sdiv 54818334Speter#if defined (sdiv_qrnnd) 549117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 550117404Skan defined (L_umoddi3) || defined (L_moddi3)) 551117404Skanstatic inline __attribute__ ((__always_inline__)) 552117404Skan#endif 55390280SobrienUWtype 55490280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) 55518334Speter{ 55690280Sobrien UWtype q, r; 55790280Sobrien UWtype c0, c1, b1; 55818334Speter 55990280Sobrien if ((Wtype) d >= 0) 56018334Speter { 56190280Sobrien if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) 56218334Speter { 56318334Speter /* dividend, divisor, and quotient are nonnegative */ 56418334Speter sdiv_qrnnd (q, r, a1, a0, d); 56518334Speter } 56618334Speter else 56718334Speter { 56818334Speter /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ 56990280Sobrien sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); 57018334Speter /* Divide (c1*2^32 + c0) by d */ 57118334Speter sdiv_qrnnd (q, r, c1, c0, d); 57218334Speter /* Add 2^31 to quotient */ 57390280Sobrien q += (UWtype) 1 << (W_TYPE_SIZE - 1); 57418334Speter } 57518334Speter } 57618334Speter else 57718334Speter { 57818334Speter b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 57918334Speter c1 = a1 >> 1; /* A/2 */ 58090280Sobrien c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); 58118334Speter 58218334Speter if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 58318334Speter { 58418334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 58518334Speter 58618334Speter r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 58718334Speter if ((d & 1) != 0) 58818334Speter { 58918334Speter if (r >= q) 59018334Speter r = r - q; 59118334Speter else if (q - r <= d) 59218334Speter { 59318334Speter r = r - q + d; 59418334Speter q--; 59518334Speter } 59618334Speter else 59718334Speter { 59818334Speter r = r - q + 2*d; 59918334Speter q -= 2; 60018334Speter } 60118334Speter } 60218334Speter } 60318334Speter else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 60418334Speter { 60518334Speter c1 = (b1 - 1) - c1; 60618334Speter c0 = ~c0; /* logical NOT */ 60718334Speter 60818334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 60918334Speter 61018334Speter q = ~q; /* (A/2)/b1 */ 61118334Speter r = (b1 - 1) - r; 61218334Speter 61318334Speter r = 2*r + (a0 & 1); /* A/(2*b1) */ 61418334Speter 61518334Speter if ((d & 1) != 0) 61618334Speter { 61718334Speter if (r >= q) 61818334Speter r = r - q; 61918334Speter else if (q - r <= d) 62018334Speter { 62118334Speter r = r - q + d; 62218334Speter q--; 62318334Speter } 62418334Speter else 62518334Speter { 62618334Speter r = r - q + 2*d; 62718334Speter q -= 2; 62818334Speter } 62918334Speter } 63018334Speter } 63118334Speter else /* Implies c1 = b1 */ 63218334Speter { /* Hence a1 = d - 1 = 2*b1 - 1 */ 63318334Speter if (a0 >= -d) 63418334Speter { 63518334Speter q = -1; 63618334Speter r = a0 + d; 63718334Speter } 63818334Speter else 63918334Speter { 64018334Speter q = -2; 64118334Speter r = a0 + 2*d; 64218334Speter } 64318334Speter } 64418334Speter } 64518334Speter 64618334Speter *rp = r; 64718334Speter return q; 64818334Speter} 64918334Speter#else 65018334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ 65190280SobrienUWtype 65290280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), 65390280Sobrien UWtype a1 __attribute__ ((__unused__)), 65490280Sobrien UWtype a0 __attribute__ ((__unused__)), 65590280Sobrien UWtype d __attribute__ ((__unused__))) 65650600Sobrien{ 65750600Sobrien return 0; 65850600Sobrien} 65918334Speter#endif 66018334Speter#endif 66118334Speter 66218334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 66318334Speter defined (L_umoddi3) || defined (L_moddi3)) 66418334Speter#define L_udivmoddi4 66518334Speter#endif 66618334Speter 66790280Sobrien#ifdef L_clz 66890280Sobrienconst UQItype __clz_tab[] = 66918334Speter{ 67018334Speter 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, 67118334Speter 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, 67218334Speter 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, 67318334Speter 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, 67418334Speter 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, 67518334Speter 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, 67618334Speter 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, 67718334Speter 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, 67818334Speter}; 67990280Sobrien#endif 680132727Skan 681132727Skan#ifdef L_clzsi2 682132727Skan#undef int 683132727Skanextern int __clzSI2 (UWtype x); 684132727Skanint 685132727Skan__clzSI2 (UWtype x) 686132727Skan{ 687132727Skan Wtype ret; 68818334Speter 689132727Skan count_leading_zeros (ret, x); 690132727Skan 691132727Skan return ret; 692132727Skan} 693132727Skan#endif 694132727Skan 695132727Skan#ifdef L_clzdi2 696132727Skan#undef int 697132727Skanextern int __clzDI2 (UDWtype x); 698132727Skanint 699132727Skan__clzDI2 (UDWtype x) 700132727Skan{ 701132727Skan const DWunion uu = {.ll = x}; 702132727Skan UWtype word; 703132727Skan Wtype ret, add; 704132727Skan 705132727Skan if (uu.s.high) 706132727Skan word = uu.s.high, add = 0; 707132727Skan else 708132727Skan word = uu.s.low, add = W_TYPE_SIZE; 709132727Skan 710132727Skan count_leading_zeros (ret, word); 711132727Skan return ret + add; 712132727Skan} 713132727Skan#endif 714132727Skan 715132727Skan#ifdef L_ctzsi2 716132727Skan#undef int 717132727Skanextern int __ctzSI2 (UWtype x); 718132727Skanint 719132727Skan__ctzSI2 (UWtype x) 720132727Skan{ 721132727Skan Wtype ret; 722132727Skan 723132727Skan count_trailing_zeros (ret, x); 724132727Skan 725132727Skan return ret; 726132727Skan} 727132727Skan#endif 728132727Skan 729132727Skan#ifdef L_ctzdi2 730132727Skan#undef int 731132727Skanextern int __ctzDI2 (UDWtype x); 732132727Skanint 733132727Skan__ctzDI2 (UDWtype x) 734132727Skan{ 735132727Skan const DWunion uu = {.ll = x}; 736132727Skan UWtype word; 737132727Skan Wtype ret, add; 738132727Skan 739132727Skan if (uu.s.low) 740132727Skan word = uu.s.low, add = 0; 741132727Skan else 742132727Skan word = uu.s.high, add = W_TYPE_SIZE; 743132727Skan 744132727Skan count_trailing_zeros (ret, word); 745132727Skan return ret + add; 746132727Skan} 747132727Skan#endif 748132727Skan 749132727Skan#if (defined (L_popcountsi2) || defined (L_popcountdi2) \ 750132727Skan || defined (L_popcount_tab)) 751132727Skanextern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN; 752132727Skan#endif 753132727Skan 754132727Skan#ifdef L_popcount_tab 755132727Skanconst UQItype __popcount_tab[] = 756132727Skan{ 757132727Skan 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 758132727Skan 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 759132727Skan 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 760132727Skan 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 761132727Skan 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 762132727Skan 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 763132727Skan 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 764132727Skan 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 765132727Skan}; 766132727Skan#endif 767132727Skan 768132727Skan#ifdef L_popcountsi2 769132727Skan#undef int 770132727Skanextern int __popcountSI2 (UWtype x); 771132727Skanint 772132727Skan__popcountSI2 (UWtype x) 773132727Skan{ 774132727Skan UWtype i, ret = 0; 775132727Skan 776132727Skan for (i = 0; i < W_TYPE_SIZE; i += 8) 777132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 778132727Skan 779132727Skan return ret; 780132727Skan} 781132727Skan#endif 782132727Skan 783132727Skan#ifdef L_popcountdi2 784132727Skan#undef int 785132727Skanextern int __popcountDI2 (UDWtype x); 786132727Skanint 787132727Skan__popcountDI2 (UDWtype x) 788132727Skan{ 789132727Skan UWtype i, ret = 0; 790132727Skan 791132727Skan for (i = 0; i < 2*W_TYPE_SIZE; i += 8) 792132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 793132727Skan 794132727Skan return ret; 795132727Skan} 796132727Skan#endif 797132727Skan 798132727Skan#ifdef L_paritysi2 799132727Skan#undef int 800132727Skanextern int __paritySI2 (UWtype x); 801132727Skanint 802132727Skan__paritySI2 (UWtype x) 803132727Skan{ 804132727Skan#if W_TYPE_SIZE > 64 805132727Skan# error "fill out the table" 806132727Skan#endif 807132727Skan#if W_TYPE_SIZE > 32 808132727Skan x ^= x >> 32; 809132727Skan#endif 810132727Skan#if W_TYPE_SIZE > 16 811132727Skan x ^= x >> 16; 812132727Skan#endif 813132727Skan x ^= x >> 8; 814132727Skan x ^= x >> 4; 815132727Skan x &= 0xf; 816132727Skan return (0x6996 >> x) & 1; 817132727Skan} 818132727Skan#endif 819132727Skan 820132727Skan#ifdef L_paritydi2 821132727Skan#undef int 822132727Skanextern int __parityDI2 (UDWtype x); 823132727Skanint 824132727Skan__parityDI2 (UDWtype x) 825132727Skan{ 826132727Skan const DWunion uu = {.ll = x}; 827132727Skan UWtype nx = uu.s.low ^ uu.s.high; 828132727Skan 829132727Skan#if W_TYPE_SIZE > 64 830132727Skan# error "fill out the table" 831132727Skan#endif 832132727Skan#if W_TYPE_SIZE > 32 833132727Skan nx ^= nx >> 32; 834132727Skan#endif 835132727Skan#if W_TYPE_SIZE > 16 836132727Skan nx ^= nx >> 16; 837132727Skan#endif 838132727Skan nx ^= nx >> 8; 839132727Skan nx ^= nx >> 4; 840132727Skan nx &= 0xf; 841132727Skan return (0x6996 >> nx) & 1; 842132727Skan} 843132727Skan#endif 844132727Skan 84590280Sobrien#ifdef L_udivmoddi4 84690280Sobrien 84718334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 84818334Speter defined (L_umoddi3) || defined (L_moddi3)) 849117404Skanstatic inline __attribute__ ((__always_inline__)) 85018334Speter#endif 85190280SobrienUDWtype 85290280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) 85318334Speter{ 854132727Skan const DWunion nn = {.ll = n}; 855132727Skan const DWunion dd = {.ll = d}; 85690280Sobrien DWunion rr; 85790280Sobrien UWtype d0, d1, n0, n1, n2; 85890280Sobrien UWtype q0, q1; 85990280Sobrien UWtype b, bm; 86018334Speter 86118334Speter d0 = dd.s.low; 86218334Speter d1 = dd.s.high; 86318334Speter n0 = nn.s.low; 86418334Speter n1 = nn.s.high; 86518334Speter 86618334Speter#if !UDIV_NEEDS_NORMALIZATION 86718334Speter if (d1 == 0) 86818334Speter { 86918334Speter if (d0 > n1) 87018334Speter { 87118334Speter /* 0q = nn / 0D */ 87218334Speter 87318334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 87418334Speter q1 = 0; 87518334Speter 87618334Speter /* Remainder in n0. */ 87718334Speter } 87818334Speter else 87918334Speter { 88018334Speter /* qq = NN / 0d */ 88118334Speter 88218334Speter if (d0 == 0) 88318334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 88418334Speter 88518334Speter udiv_qrnnd (q1, n1, 0, n1, d0); 88618334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 88718334Speter 88818334Speter /* Remainder in n0. */ 88918334Speter } 89018334Speter 89118334Speter if (rp != 0) 89218334Speter { 89318334Speter rr.s.low = n0; 89418334Speter rr.s.high = 0; 89518334Speter *rp = rr.ll; 89618334Speter } 89718334Speter } 89818334Speter 89918334Speter#else /* UDIV_NEEDS_NORMALIZATION */ 90018334Speter 90118334Speter if (d1 == 0) 90218334Speter { 90318334Speter if (d0 > n1) 90418334Speter { 90518334Speter /* 0q = nn / 0D */ 90618334Speter 90718334Speter count_leading_zeros (bm, d0); 90818334Speter 90918334Speter if (bm != 0) 91018334Speter { 91118334Speter /* Normalize, i.e. make the most significant bit of the 91218334Speter denominator set. */ 91318334Speter 91418334Speter d0 = d0 << bm; 91590280Sobrien n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); 91618334Speter n0 = n0 << bm; 91718334Speter } 91818334Speter 91918334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 92018334Speter q1 = 0; 92118334Speter 92218334Speter /* Remainder in n0 >> bm. */ 92318334Speter } 92418334Speter else 92518334Speter { 92618334Speter /* qq = NN / 0d */ 92718334Speter 92818334Speter if (d0 == 0) 92918334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 93018334Speter 93118334Speter count_leading_zeros (bm, d0); 93218334Speter 93318334Speter if (bm == 0) 93418334Speter { 93518334Speter /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 93618334Speter conclude (the most significant bit of n1 is set) /\ (the 93718334Speter leading quotient digit q1 = 1). 93818334Speter 93918334Speter This special case is necessary, not an optimization. 94090280Sobrien (Shifts counts of W_TYPE_SIZE are undefined.) */ 94118334Speter 94218334Speter n1 -= d0; 94318334Speter q1 = 1; 94418334Speter } 94518334Speter else 94618334Speter { 94718334Speter /* Normalize. */ 94818334Speter 94990280Sobrien b = W_TYPE_SIZE - bm; 95018334Speter 95118334Speter d0 = d0 << bm; 95218334Speter n2 = n1 >> b; 95318334Speter n1 = (n1 << bm) | (n0 >> b); 95418334Speter n0 = n0 << bm; 95518334Speter 95618334Speter udiv_qrnnd (q1, n1, n2, n1, d0); 95718334Speter } 95818334Speter 95950600Sobrien /* n1 != d0... */ 96018334Speter 96118334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 96218334Speter 96318334Speter /* Remainder in n0 >> bm. */ 96418334Speter } 96518334Speter 96618334Speter if (rp != 0) 96718334Speter { 96818334Speter rr.s.low = n0 >> bm; 96918334Speter rr.s.high = 0; 97018334Speter *rp = rr.ll; 97118334Speter } 97218334Speter } 97318334Speter#endif /* UDIV_NEEDS_NORMALIZATION */ 97418334Speter 97518334Speter else 97618334Speter { 97718334Speter if (d1 > n1) 97818334Speter { 97918334Speter /* 00 = nn / DD */ 98018334Speter 98118334Speter q0 = 0; 98218334Speter q1 = 0; 98318334Speter 98418334Speter /* Remainder in n1n0. */ 98518334Speter if (rp != 0) 98618334Speter { 98718334Speter rr.s.low = n0; 98818334Speter rr.s.high = n1; 98918334Speter *rp = rr.ll; 99018334Speter } 99118334Speter } 99218334Speter else 99318334Speter { 99418334Speter /* 0q = NN / dd */ 99518334Speter 99618334Speter count_leading_zeros (bm, d1); 99718334Speter if (bm == 0) 99818334Speter { 99918334Speter /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 100018334Speter conclude (the most significant bit of n1 is set) /\ (the 100118334Speter quotient digit q0 = 0 or 1). 100218334Speter 100318334Speter This special case is necessary, not an optimization. */ 100418334Speter 100518334Speter /* The condition on the next line takes advantage of that 100618334Speter n1 >= d1 (true due to program flow). */ 100718334Speter if (n1 > d1 || n0 >= d0) 100818334Speter { 100918334Speter q0 = 1; 101018334Speter sub_ddmmss (n1, n0, n1, n0, d1, d0); 101118334Speter } 101218334Speter else 101318334Speter q0 = 0; 101418334Speter 101518334Speter q1 = 0; 101618334Speter 101718334Speter if (rp != 0) 101818334Speter { 101918334Speter rr.s.low = n0; 102018334Speter rr.s.high = n1; 102118334Speter *rp = rr.ll; 102218334Speter } 102318334Speter } 102418334Speter else 102518334Speter { 102690280Sobrien UWtype m1, m0; 102718334Speter /* Normalize. */ 102818334Speter 102990280Sobrien b = W_TYPE_SIZE - bm; 103018334Speter 103118334Speter d1 = (d1 << bm) | (d0 >> b); 103218334Speter d0 = d0 << bm; 103318334Speter n2 = n1 >> b; 103418334Speter n1 = (n1 << bm) | (n0 >> b); 103518334Speter n0 = n0 << bm; 103618334Speter 103718334Speter udiv_qrnnd (q0, n1, n2, n1, d1); 103818334Speter umul_ppmm (m1, m0, q0, d0); 103918334Speter 104018334Speter if (m1 > n1 || (m1 == n1 && m0 > n0)) 104118334Speter { 104218334Speter q0--; 104318334Speter sub_ddmmss (m1, m0, m1, m0, d1, d0); 104418334Speter } 104518334Speter 104618334Speter q1 = 0; 104718334Speter 104818334Speter /* Remainder in (n1n0 - m1m0) >> bm. */ 104918334Speter if (rp != 0) 105018334Speter { 105118334Speter sub_ddmmss (n1, n0, n1, n0, m1, m0); 105218334Speter rr.s.low = (n1 << b) | (n0 >> bm); 105318334Speter rr.s.high = n1 >> bm; 105418334Speter *rp = rr.ll; 105518334Speter } 105618334Speter } 105718334Speter } 105818334Speter } 105918334Speter 1060132727Skan const DWunion ww = {{.low = q0, .high = q1}}; 106118334Speter return ww.ll; 106218334Speter} 106318334Speter#endif 106418334Speter 106518334Speter#ifdef L_divdi3 106690280SobrienDWtype 106790280Sobrien__divdi3 (DWtype u, DWtype v) 106818334Speter{ 106918334Speter word_type c = 0; 1070132727Skan DWunion uu = {.ll = u}; 1071132727Skan DWunion vv = {.ll = v}; 107290280Sobrien DWtype w; 107318334Speter 107418334Speter if (uu.s.high < 0) 107518334Speter c = ~c, 1076117404Skan uu.ll = -uu.ll; 107718334Speter if (vv.s.high < 0) 107818334Speter c = ~c, 1079117404Skan vv.ll = -vv.ll; 108018334Speter 108190280Sobrien w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); 108218334Speter if (c) 1083117404Skan w = -w; 108418334Speter 108518334Speter return w; 108618334Speter} 108718334Speter#endif 108818334Speter 108918334Speter#ifdef L_moddi3 109090280SobrienDWtype 109190280Sobrien__moddi3 (DWtype u, DWtype v) 109218334Speter{ 109318334Speter word_type c = 0; 1094132727Skan DWunion uu = {.ll = u}; 1095132727Skan DWunion vv = {.ll = v}; 109690280Sobrien DWtype w; 109718334Speter 109818334Speter if (uu.s.high < 0) 109918334Speter c = ~c, 1100117404Skan uu.ll = -uu.ll; 110118334Speter if (vv.s.high < 0) 1102117404Skan vv.ll = -vv.ll; 110318334Speter 110418334Speter (void) __udivmoddi4 (uu.ll, vv.ll, &w); 110518334Speter if (c) 1106117404Skan w = -w; 110718334Speter 110818334Speter return w; 110918334Speter} 111018334Speter#endif 111118334Speter 111218334Speter#ifdef L_umoddi3 111390280SobrienUDWtype 111490280Sobrien__umoddi3 (UDWtype u, UDWtype v) 111518334Speter{ 111690280Sobrien UDWtype w; 111718334Speter 111818334Speter (void) __udivmoddi4 (u, v, &w); 111918334Speter 112018334Speter return w; 112118334Speter} 112218334Speter#endif 112318334Speter 112418334Speter#ifdef L_udivdi3 112590280SobrienUDWtype 112690280Sobrien__udivdi3 (UDWtype n, UDWtype d) 112718334Speter{ 112890280Sobrien return __udivmoddi4 (n, d, (UDWtype *) 0); 112918334Speter} 113018334Speter#endif 113118334Speter 113218334Speter#ifdef L_cmpdi2 113318334Speterword_type 113490280Sobrien__cmpdi2 (DWtype a, DWtype b) 113518334Speter{ 1136132727Skan const DWunion au = {.ll = a}; 1137132727Skan const DWunion bu = {.ll = b}; 113818334Speter 113918334Speter if (au.s.high < bu.s.high) 114018334Speter return 0; 114118334Speter else if (au.s.high > bu.s.high) 114218334Speter return 2; 114390280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 114418334Speter return 0; 114590280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 114618334Speter return 2; 114718334Speter return 1; 114818334Speter} 114918334Speter#endif 115018334Speter 115118334Speter#ifdef L_ucmpdi2 115218334Speterword_type 115390280Sobrien__ucmpdi2 (DWtype a, DWtype b) 115418334Speter{ 1155132727Skan const DWunion au = {.ll = a}; 1156132727Skan const DWunion bu = {.ll = b}; 115718334Speter 115890280Sobrien if ((UWtype) au.s.high < (UWtype) bu.s.high) 115918334Speter return 0; 116090280Sobrien else if ((UWtype) au.s.high > (UWtype) bu.s.high) 116118334Speter return 2; 116290280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 116318334Speter return 0; 116490280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 116518334Speter return 2; 116618334Speter return 1; 116718334Speter} 116818334Speter#endif 116918334Speter 117052561Sobrien#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 117190280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 117290280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 117318334Speter 117490280SobrienDWtype 117590280Sobrien__fixunstfDI (TFtype a) 117618334Speter{ 117718334Speter if (a < 0) 117818334Speter return 0; 117918334Speter 118018334Speter /* Compute high word of result, as a flonum. */ 1181132727Skan const TFtype b = (a / HIGH_WORD_COEFF); 118290280Sobrien /* Convert that to fixed (but not to DWtype!), 118318334Speter and shift it into the high word. */ 1184132727Skan UDWtype v = (UWtype) b; 118518334Speter v <<= WORD_SIZE; 118618334Speter /* Remove high part from the TFtype, leaving the low part as flonum. */ 118718334Speter a -= (TFtype)v; 118890280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 118918334Speter Sometimes A comes out negative. This is significant, since 119018334Speter A has more bits than a long int does. */ 119118334Speter if (a < 0) 119290280Sobrien v -= (UWtype) (- a); 119318334Speter else 119490280Sobrien v += (UWtype) a; 119518334Speter return v; 119618334Speter} 119718334Speter#endif 119818334Speter 119952561Sobrien#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 120090280SobrienDWtype 120150600Sobrien__fixtfdi (TFtype a) 120218334Speter{ 120318334Speter if (a < 0) 120490280Sobrien return - __fixunstfDI (-a); 120590280Sobrien return __fixunstfDI (a); 120618334Speter} 120718334Speter#endif 120818334Speter 120952561Sobrien#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 121090280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 121190280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 121218334Speter 121390280SobrienDWtype 121490280Sobrien__fixunsxfDI (XFtype a) 121518334Speter{ 121618334Speter if (a < 0) 121718334Speter return 0; 121818334Speter 121918334Speter /* Compute high word of result, as a flonum. */ 1220132727Skan const XFtype b = (a / HIGH_WORD_COEFF); 122190280Sobrien /* Convert that to fixed (but not to DWtype!), 122218334Speter and shift it into the high word. */ 1223132727Skan UDWtype v = (UWtype) b; 122418334Speter v <<= WORD_SIZE; 122518334Speter /* Remove high part from the XFtype, leaving the low part as flonum. */ 122618334Speter a -= (XFtype)v; 122790280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 122818334Speter Sometimes A comes out negative. This is significant, since 122918334Speter A has more bits than a long int does. */ 123018334Speter if (a < 0) 123190280Sobrien v -= (UWtype) (- a); 123218334Speter else 123390280Sobrien v += (UWtype) a; 123418334Speter return v; 123518334Speter} 123618334Speter#endif 123718334Speter 123852561Sobrien#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 123990280SobrienDWtype 124050600Sobrien__fixxfdi (XFtype a) 124118334Speter{ 124218334Speter if (a < 0) 124390280Sobrien return - __fixunsxfDI (-a); 124490280Sobrien return __fixunsxfDI (a); 124518334Speter} 124618334Speter#endif 124718334Speter 124818334Speter#ifdef L_fixunsdfdi 124990280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 125090280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 125118334Speter 125290280SobrienDWtype 125390280Sobrien__fixunsdfDI (DFtype a) 125418334Speter{ 1255132727Skan /* Get high part of result. The division here will just moves the radix 1256132727Skan point and will not cause any rounding. Then the conversion to integral 1257132727Skan type chops result as desired. */ 1258132727Skan const UWtype hi = a / HIGH_WORD_COEFF; 125918334Speter 1260132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1261132727Skan then subtract this from the number being converted. This leaves the low 1262132727Skan part. Convert that to integral type. */ 1263132727Skan const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); 126418334Speter 1265132727Skan /* Assemble result from the two parts. */ 1266132727Skan return ((UDWtype) hi << WORD_SIZE) | lo; 126718334Speter} 126818334Speter#endif 126918334Speter 127018334Speter#ifdef L_fixdfdi 127190280SobrienDWtype 127250600Sobrien__fixdfdi (DFtype a) 127318334Speter{ 127418334Speter if (a < 0) 127590280Sobrien return - __fixunsdfDI (-a); 127690280Sobrien return __fixunsdfDI (a); 127718334Speter} 127818334Speter#endif 127918334Speter 128018334Speter#ifdef L_fixunssfdi 128190280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 128290280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 128318334Speter 128490280SobrienDWtype 128590280Sobrien__fixunssfDI (SFtype original_a) 128618334Speter{ 128718334Speter /* Convert the SFtype to a DFtype, because that is surely not going 128818334Speter to lose any bits. Some day someone else can write a faster version 128918334Speter that avoids converting to DFtype, and verify it really works right. */ 1290132727Skan const DFtype a = original_a; 129118334Speter 1292132727Skan /* Get high part of result. The division here will just moves the radix 1293132727Skan point and will not cause any rounding. Then the conversion to integral 1294132727Skan type chops result as desired. */ 1295132727Skan const UWtype hi = a / HIGH_WORD_COEFF; 129618334Speter 1297132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1298132727Skan then subtract this from the number being converted. This leaves the low 1299132727Skan part. Convert that to integral type. */ 1300132727Skan const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); 1301132727Skan 1302132727Skan /* Assemble result from the two parts. */ 1303132727Skan return ((UDWtype) hi << WORD_SIZE) | lo; 130418334Speter} 130518334Speter#endif 130618334Speter 130718334Speter#ifdef L_fixsfdi 130890280SobrienDWtype 130918334Speter__fixsfdi (SFtype a) 131018334Speter{ 131118334Speter if (a < 0) 131290280Sobrien return - __fixunssfDI (-a); 131390280Sobrien return __fixunssfDI (a); 131418334Speter} 131518334Speter#endif 131618334Speter 131752561Sobrien#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) 131890280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 131990280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 132090280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 132118334Speter 132218334SpeterXFtype 132390280Sobrien__floatdixf (DWtype u) 132418334Speter{ 1325132727Skan XFtype d = (Wtype) (u >> WORD_SIZE); 132618334Speter d *= HIGH_HALFWORD_COEFF; 132718334Speter d *= HIGH_HALFWORD_COEFF; 132890280Sobrien d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 132918334Speter 133050600Sobrien return d; 133118334Speter} 133218334Speter#endif 133318334Speter 133452561Sobrien#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) 133590280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 133690280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 133790280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 133818334Speter 133918334SpeterTFtype 134090280Sobrien__floatditf (DWtype u) 134118334Speter{ 1342132727Skan TFtype d = (Wtype) (u >> WORD_SIZE); 134318334Speter d *= HIGH_HALFWORD_COEFF; 134418334Speter d *= HIGH_HALFWORD_COEFF; 134590280Sobrien d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 134618334Speter 134750600Sobrien return d; 134818334Speter} 134918334Speter#endif 135018334Speter 135118334Speter#ifdef L_floatdidf 135290280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 135390280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 135490280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 135518334Speter 135618334SpeterDFtype 135790280Sobrien__floatdidf (DWtype u) 135818334Speter{ 1359132727Skan DFtype d = (Wtype) (u >> WORD_SIZE); 136018334Speter d *= HIGH_HALFWORD_COEFF; 136118334Speter d *= HIGH_HALFWORD_COEFF; 136290280Sobrien d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 136318334Speter 136450600Sobrien return d; 136518334Speter} 136618334Speter#endif 136718334Speter 136818334Speter#ifdef L_floatdisf 136990280Sobrien#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) 137090280Sobrien#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) 137190280Sobrien#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) 1372117404Skan 137390280Sobrien#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT) 1374117404Skan#define DF_SIZE DBL_MANT_DIG 1375117404Skan#define SF_SIZE FLT_MANT_DIG 137618334Speter 137718334SpeterSFtype 137890280Sobrien__floatdisf (DWtype u) 137918334Speter{ 138018334Speter /* Protect against double-rounding error. 138118334Speter Represent any low-order bits, that might be truncated in DFmode, 138218334Speter by a bit that won't be lost. The bit can go in anywhere below the 138318334Speter rounding position of the SFmode. A fixed mask and bit position 138418334Speter handles all usual configurations. It doesn't handle the case 138518334Speter of 128-bit DImode, however. */ 138618334Speter if (DF_SIZE < DI_SIZE 138718334Speter && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) 138818334Speter { 138990280Sobrien#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE)) 139090280Sobrien if (! (- ((DWtype) 1 << DF_SIZE) < u 139190280Sobrien && u < ((DWtype) 1 << DF_SIZE))) 139218334Speter { 139390280Sobrien if ((UDWtype) u & (REP_BIT - 1)) 1394104764Skan { 1395104764Skan u &= ~ (REP_BIT - 1); 1396104764Skan u |= REP_BIT; 1397104764Skan } 139818334Speter } 139918334Speter } 1400132727Skan /* Do the calculation in DFmode 1401132727Skan so that we don't lose any of the precision of the high word 1402132727Skan while multiplying it. */ 1403132727Skan DFtype f = (Wtype) (u >> WORD_SIZE); 140418334Speter f *= HIGH_HALFWORD_COEFF; 140518334Speter f *= HIGH_HALFWORD_COEFF; 140690280Sobrien f += (UWtype) (u & (HIGH_WORD_COEFF - 1)); 140718334Speter 140850600Sobrien return (SFtype) f; 140918334Speter} 141018334Speter#endif 141118334Speter 141252561Sobrien#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96 141318334Speter/* Reenable the normal types, in case limits.h needs them. */ 141418334Speter#undef char 141518334Speter#undef short 141618334Speter#undef int 141718334Speter#undef long 141818334Speter#undef unsigned 141918334Speter#undef float 142018334Speter#undef double 142118334Speter#undef MIN 142218334Speter#undef MAX 142318334Speter#include <limits.h> 142418334Speter 142590280SobrienUWtype 142690280Sobrien__fixunsxfSI (XFtype a) 142718334Speter{ 142890280Sobrien if (a >= - (DFtype) Wtype_MIN) 142990280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 143090280Sobrien return (Wtype) a; 143118334Speter} 143218334Speter#endif 143318334Speter 143418334Speter#ifdef L_fixunsdfsi 143518334Speter/* Reenable the normal types, in case limits.h needs them. */ 143618334Speter#undef char 143718334Speter#undef short 143818334Speter#undef int 143918334Speter#undef long 144018334Speter#undef unsigned 144118334Speter#undef float 144218334Speter#undef double 144318334Speter#undef MIN 144418334Speter#undef MAX 144518334Speter#include <limits.h> 144618334Speter 144790280SobrienUWtype 144890280Sobrien__fixunsdfSI (DFtype a) 144918334Speter{ 145090280Sobrien if (a >= - (DFtype) Wtype_MIN) 145190280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 145290280Sobrien return (Wtype) a; 145318334Speter} 145418334Speter#endif 145518334Speter 145618334Speter#ifdef L_fixunssfsi 145718334Speter/* Reenable the normal types, in case limits.h needs them. */ 145818334Speter#undef char 145918334Speter#undef short 146018334Speter#undef int 146118334Speter#undef long 146218334Speter#undef unsigned 146318334Speter#undef float 146418334Speter#undef double 146518334Speter#undef MIN 146618334Speter#undef MAX 146718334Speter#include <limits.h> 146818334Speter 146990280SobrienUWtype 147090280Sobrien__fixunssfSI (SFtype a) 147118334Speter{ 147290280Sobrien if (a >= - (SFtype) Wtype_MIN) 147390280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 147490280Sobrien return (Wtype) a; 147518334Speter} 147618334Speter#endif 147718334Speter 147818334Speter/* From here on down, the routines use normal data types. */ 147918334Speter 148018334Speter#define SItype bogus_type 148118334Speter#define USItype bogus_type 148218334Speter#define DItype bogus_type 148318334Speter#define UDItype bogus_type 148418334Speter#define SFtype bogus_type 148518334Speter#define DFtype bogus_type 148690280Sobrien#undef Wtype 148790280Sobrien#undef UWtype 148890280Sobrien#undef HWtype 148990280Sobrien#undef UHWtype 149090280Sobrien#undef DWtype 149190280Sobrien#undef UDWtype 149218334Speter 149318334Speter#undef char 149418334Speter#undef short 149518334Speter#undef int 149618334Speter#undef long 149718334Speter#undef unsigned 149818334Speter#undef float 149918334Speter#undef double 150018334Speter 150118334Speter#ifdef L__gcc_bcmp 150218334Speter 150318334Speter/* Like bcmp except the sign is meaningful. 150418334Speter Result is negative if S1 is less than S2, 150518334Speter positive if S1 is greater, 0 if S1 and S2 are equal. */ 150618334Speter 150718334Speterint 150890280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) 150918334Speter{ 151018334Speter while (size > 0) 151118334Speter { 1512132727Skan const unsigned char c1 = *s1++, c2 = *s2++; 151318334Speter if (c1 != c2) 151418334Speter return c1 - c2; 151518334Speter size--; 151618334Speter } 151718334Speter return 0; 151818334Speter} 151918334Speter 152018334Speter#endif 152118334Speter 152290280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>. 152390280Sobrien We no longer provide that header, but this routine remains in libgcc.a 152490280Sobrien for binary backward compatibility. Note that it is not included in 152590280Sobrien the shared version of libgcc. */ 152618334Speter#ifdef L_eprintf 152718334Speter#ifndef inhibit_libc 152818334Speter 152918334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 153018334Speter#include <stdio.h> 153152561Sobrien 153218334Spetervoid 153350600Sobrien__eprintf (const char *string, const char *expression, 153450600Sobrien unsigned int line, const char *filename) 153518334Speter{ 153618334Speter fprintf (stderr, string, expression, line, filename); 153718334Speter fflush (stderr); 153818334Speter abort (); 153918334Speter} 154018334Speter 154118334Speter#endif 154218334Speter#endif 154318334Speter 154418334Speter 154518334Speter#ifdef L_clear_cache 154618334Speter/* Clear part of an instruction cache. */ 154718334Speter 154818334Spetervoid 154990280Sobrien__clear_cache (char *beg __attribute__((__unused__)), 155090280Sobrien char *end __attribute__((__unused__))) 155118334Speter{ 155290280Sobrien#ifdef CLEAR_INSN_CACHE 155318334Speter CLEAR_INSN_CACHE (beg, end); 155418334Speter#endif /* CLEAR_INSN_CACHE */ 155518334Speter} 155618334Speter 155718334Speter#endif /* L_clear_cache */ 155818334Speter 1559132727Skan#ifdef L_enable_execute_stack 1560132727Skan/* Attempt to turn on execute permission for the stack. */ 1561132727Skan 1562132727Skan#ifdef ENABLE_EXECUTE_STACK 1563132727Skan ENABLE_EXECUTE_STACK 1564132727Skan#else 1565132727Skanvoid 1566132727Skan__enable_execute_stack (void *addr __attribute__((__unused__))) 1567132727Skan{} 1568132727Skan#endif /* ENABLE_EXECUTE_STACK */ 1569132727Skan 1570132727Skan#endif /* L_enable_execute_stack */ 1571132727Skan 157218334Speter#ifdef L_trampoline 157318334Speter 157418334Speter/* Jump to a trampoline, loading the static chain address. */ 157518334Speter 157652561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) 157718334Speter 157890280Sobrienlong 157990280Sobriengetpagesize (void) 158018334Speter{ 158118334Speter#ifdef _ALPHA_ 158218334Speter return 8192; 158318334Speter#else 158418334Speter return 4096; 158518334Speter#endif 158618334Speter} 158718334Speter 158890280Sobrien#ifdef __i386__ 158950600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); 159050600Sobrien#endif 159150600Sobrien 159250600Sobrienint 159350600Sobrienmprotect (char *addr, int len, int prot) 159418334Speter{ 159518334Speter int np, op; 159618334Speter 159750600Sobrien if (prot == 7) 159850600Sobrien np = 0x40; 159950600Sobrien else if (prot == 5) 160050600Sobrien np = 0x20; 160150600Sobrien else if (prot == 4) 160250600Sobrien np = 0x10; 160350600Sobrien else if (prot == 3) 160450600Sobrien np = 0x04; 160550600Sobrien else if (prot == 1) 160650600Sobrien np = 0x02; 160750600Sobrien else if (prot == 0) 160850600Sobrien np = 0x01; 160918334Speter 161018334Speter if (VirtualProtect (addr, len, np, &op)) 161118334Speter return 0; 161218334Speter else 161318334Speter return -1; 161418334Speter} 161518334Speter 161652561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ 161718334Speter 161890280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE 161990280SobrienTRANSFER_FROM_TRAMPOLINE 162018334Speter#endif 162118334Speter#endif /* L_trampoline */ 162218334Speter 162352561Sobrien#ifndef __CYGWIN__ 162418334Speter#ifdef L__main 162518334Speter 162618334Speter#include "gbl-ctors.h" 162718334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these 162818334Speter cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 162918334Speter give the same symbol without quotes for an alternative entry point. You 163050600Sobrien must define both, or neither. */ 163118334Speter#ifndef NAME__MAIN 163218334Speter#define NAME__MAIN "__main" 163318334Speter#define SYMBOL__MAIN __main 163418334Speter#endif 163518334Speter 163650600Sobrien#ifdef INIT_SECTION_ASM_OP 163750600Sobrien#undef HAS_INIT_SECTION 163850600Sobrien#define HAS_INIT_SECTION 163950600Sobrien#endif 164050600Sobrien 164150600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) 164290280Sobrien 164390280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this 164490280Sobrien code to run constructors. In that case, we need to handle EH here, too. */ 164590280Sobrien 164690280Sobrien#ifdef EH_FRAME_SECTION_NAME 164790280Sobrien#include "unwind-dw2-fde.h" 164890280Sobrienextern unsigned char __EH_FRAME_BEGIN__[]; 164990280Sobrien#endif 165090280Sobrien 165118334Speter/* Run all the global destructors on exit from the program. */ 165218334Speter 165318334Spetervoid 165490280Sobrien__do_global_dtors (void) 165518334Speter{ 165618334Speter#ifdef DO_GLOBAL_DTORS_BODY 165718334Speter DO_GLOBAL_DTORS_BODY; 165818334Speter#else 165950600Sobrien static func_ptr *p = __DTOR_LIST__ + 1; 166050600Sobrien while (*p) 166150600Sobrien { 166250600Sobrien p++; 166350600Sobrien (*(p-1)) (); 166450600Sobrien } 166518334Speter#endif 166690280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) 166790280Sobrien { 166890280Sobrien static int completed = 0; 166990280Sobrien if (! completed) 167090280Sobrien { 167190280Sobrien completed = 1; 167290280Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 167390280Sobrien } 167490280Sobrien } 167590280Sobrien#endif 167618334Speter} 167750600Sobrien#endif 167818334Speter 167950600Sobrien#ifndef HAS_INIT_SECTION 168018334Speter/* Run all the global constructors on entry to the program. */ 168118334Speter 168218334Spetervoid 168390280Sobrien__do_global_ctors (void) 168418334Speter{ 168590280Sobrien#ifdef EH_FRAME_SECTION_NAME 168690280Sobrien { 168790280Sobrien static struct object object; 168890280Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 168990280Sobrien } 169090280Sobrien#endif 169118334Speter DO_GLOBAL_CTORS_BODY; 169290280Sobrien atexit (__do_global_dtors); 169318334Speter} 169450600Sobrien#endif /* no HAS_INIT_SECTION */ 169518334Speter 169650600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) 169718334Speter/* Subroutine called automatically by `main'. 169818334Speter Compiling a global function named `main' 169918334Speter produces an automatic call to this function at the beginning. 170018334Speter 170118334Speter For many systems, this routine calls __do_global_ctors. 170218334Speter For systems which support a .init section we use the .init section 170318334Speter to run __do_global_ctors, so we need not do anything here. */ 170418334Speter 1705132727Skanextern void SYMBOL__MAIN (void); 170618334Spetervoid 1707132727SkanSYMBOL__MAIN (void) 170818334Speter{ 170918334Speter /* Support recursive calls to `main': run initializers just once. */ 171018334Speter static int initialized; 171118334Speter if (! initialized) 171218334Speter { 171318334Speter initialized = 1; 171418334Speter __do_global_ctors (); 171518334Speter } 171618334Speter} 171750600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */ 171818334Speter 171918334Speter#endif /* L__main */ 172052561Sobrien#endif /* __CYGWIN__ */ 172118334Speter 172218334Speter#ifdef L_ctors 172318334Speter 172418334Speter#include "gbl-ctors.h" 172518334Speter 172618334Speter/* Provide default definitions for the lists of constructors and 172718334Speter destructors, so that we don't get linker errors. These symbols are 172818334Speter intentionally bss symbols, so that gld and/or collect will provide 172918334Speter the right values. */ 173018334Speter 173118334Speter/* We declare the lists here with two elements each, 173252561Sobrien so that they are valid empty lists if no other definition is loaded. 173352561Sobrien 173452561Sobrien If we are using the old "set" extensions to have the gnu linker 173552561Sobrien collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ 173652561Sobrien must be in the bss/common section. 173752561Sobrien 173852561Sobrien Long term no port should use those extensions. But many still do. */ 173950600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 174090280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) 174118334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0}; 174218334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0}; 174318334Speter#else 174418334Speterfunc_ptr __CTOR_LIST__[2]; 174518334Speterfunc_ptr __DTOR_LIST__[2]; 174618334Speter#endif 174718334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 174818334Speter#endif /* L_ctors */ 174918334Speter 1750