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, 4169699Skan 2000, 2001, 2002, 2003, 2004, 2005 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 29169699SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 30169699Skan02110-1301, USA. */ 3118334Speter 3218334Speter#include "tconfig.h" 3390280Sobrien#include "tsystem.h" 34132727Skan#include "coretypes.h" 35132727Skan#include "tm.h" 3650600Sobrien 37132727Skan#ifdef HAVE_GAS_HIDDEN 38132727Skan#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) 39132727Skan#else 40132727Skan#define ATTRIBUTE_HIDDEN 41132727Skan#endif 42132727Skan 43169699Skan#ifndef MIN_UNITS_PER_WORD 44169699Skan#define MIN_UNITS_PER_WORD UNITS_PER_WORD 45169699Skan#endif 46169699Skan 47169699Skan/* Work out the largest "word" size that we can deal with on this target. */ 48169699Skan#if MIN_UNITS_PER_WORD > 4 49169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD 8 50169699Skan#elif (MIN_UNITS_PER_WORD > 2 \ 51169699Skan || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)) 52169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD 4 53169699Skan#else 54169699Skan# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD 55169699Skan#endif 56169699Skan 57169699Skan/* Work out what word size we are using for this compilation. 58169699Skan The value can be set on the command line. */ 59169699Skan#ifndef LIBGCC2_UNITS_PER_WORD 60169699Skan#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD 61169699Skan#endif 62169699Skan 63169699Skan#if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD 64169699Skan 6590280Sobrien#include "libgcc2.h" 6690280Sobrien 67117404Skan#ifdef DECLARE_LIBRARY_RENAMES 68117404Skan DECLARE_LIBRARY_RENAMES 6918334Speter#endif 70117404Skan 71117404Skan#if defined (L_negdi2) 7290280SobrienDWtype 7390280Sobrien__negdi2 (DWtype u) 7490280Sobrien{ 75132727Skan const DWunion uu = {.ll = u}; 76132727Skan const DWunion w = { {.low = -uu.s.low, 77132727Skan .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } }; 7818334Speter 7990280Sobrien return w.ll; 8090280Sobrien} 8150600Sobrien#endif 8250600Sobrien 8390280Sobrien#ifdef L_addvsi3 8490280SobrienWtype 85146906Skan__addvSI3 (Wtype a, Wtype b) 8690280Sobrien{ 87132727Skan const Wtype w = a + b; 8818334Speter 8990280Sobrien if (b >= 0 ? w < a : w > a) 9090280Sobrien abort (); 9190280Sobrien 9290280Sobrien return w; 9390280Sobrien} 94146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 95146906SkanSItype 96146906Skan__addvsi3 (SItype a, SItype b) 97146906Skan{ 98146906Skan const SItype w = a + b; 99146906Skan 100146906Skan if (b >= 0 ? w < a : w > a) 101146906Skan abort (); 102146906Skan 103146906Skan return w; 104146906Skan} 105146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 10618334Speter#endif 10790280Sobrien 10890280Sobrien#ifdef L_addvdi3 10990280SobrienDWtype 110146906Skan__addvDI3 (DWtype a, DWtype b) 11190280Sobrien{ 112132727Skan const DWtype w = a + b; 11318334Speter 11490280Sobrien if (b >= 0 ? w < a : w > a) 11590280Sobrien abort (); 11690280Sobrien 11790280Sobrien return w; 11890280Sobrien} 11952561Sobrien#endif 12090280Sobrien 12190280Sobrien#ifdef L_subvsi3 12290280SobrienWtype 123146906Skan__subvSI3 (Wtype a, Wtype b) 12490280Sobrien{ 125146906Skan const Wtype w = a - b; 12652561Sobrien 12790280Sobrien if (b >= 0 ? w > a : w < a) 12890280Sobrien abort (); 12918334Speter 13090280Sobrien return w; 13190280Sobrien} 132146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 133146906SkanSItype 134146906Skan__subvsi3 (SItype a, SItype b) 135146906Skan{ 136146906Skan const SItype w = a - b; 137146906Skan 138146906Skan if (b >= 0 ? w > a : w < a) 139146906Skan abort (); 140146906Skan 141146906Skan return w; 142146906Skan} 143146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 14490280Sobrien#endif 14590280Sobrien 14690280Sobrien#ifdef L_subvdi3 14790280SobrienDWtype 148146906Skan__subvDI3 (DWtype a, DWtype b) 14990280Sobrien{ 150132727Skan const DWtype w = a - b; 15118334Speter 15290280Sobrien if (b >= 0 ? w > a : w < a) 15390280Sobrien abort (); 15490280Sobrien 15590280Sobrien return w; 15690280Sobrien} 15718334Speter#endif 15890280Sobrien 15990280Sobrien#ifdef L_mulvsi3 16090280SobrienWtype 161146906Skan__mulvSI3 (Wtype a, Wtype b) 16290280Sobrien{ 163132727Skan const DWtype w = (DWtype) a * (DWtype) b; 16418334Speter 165169699Skan if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1)) 16690280Sobrien abort (); 16718334Speter 16890280Sobrien return w; 16990280Sobrien} 170146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 171146906Skan#undef WORD_SIZE 172146906Skan#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) 173146906SkanSItype 174146906Skan__mulvsi3 (SItype a, SItype b) 175146906Skan{ 176146906Skan const DItype w = (DItype) a * (DItype) b; 177146906Skan 178146906Skan if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1)) 179146906Skan abort (); 180146906Skan 181146906Skan return w; 182146906Skan} 183146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 18490280Sobrien#endif 18590280Sobrien 18690280Sobrien#ifdef L_negvsi2 18790280SobrienWtype 188146906Skan__negvSI2 (Wtype a) 18990280Sobrien{ 190132727Skan const Wtype w = -a; 19118334Speter 19290280Sobrien if (a >= 0 ? w > 0 : w < 0) 19390280Sobrien abort (); 19418334Speter 19590280Sobrien return w; 19690280Sobrien} 197146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 198146906SkanSItype 199146906Skan__negvsi2 (SItype a) 200146906Skan{ 201146906Skan const SItype w = -a; 202146906Skan 203146906Skan if (a >= 0 ? w > 0 : w < 0) 204146906Skan abort (); 205146906Skan 206146906Skan return w; 207146906Skan} 208146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 20918334Speter#endif 21090280Sobrien 21190280Sobrien#ifdef L_negvdi2 21290280SobrienDWtype 213146906Skan__negvDI2 (DWtype a) 21490280Sobrien{ 215132727Skan const DWtype w = -a; 21618334Speter 21790280Sobrien if (a >= 0 ? w > 0 : w < 0) 21890280Sobrien abort (); 21990280Sobrien 220117404Skan return w; 22190280Sobrien} 22290280Sobrien#endif 22390280Sobrien 22490280Sobrien#ifdef L_absvsi2 22590280SobrienWtype 226146906Skan__absvSI2 (Wtype a) 22718334Speter{ 228117404Skan Wtype w = a; 22918334Speter 230117404Skan if (a < 0) 23190280Sobrien#ifdef L_negvsi2 232146906Skan w = __negvSI2 (a); 233146906Skan#else 234146906Skan w = -a; 235146906Skan 236146906Skan if (w < 0) 237146906Skan abort (); 238146906Skan#endif 239146906Skan 240146906Skan return w; 241146906Skan} 242146906Skan#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC 243146906SkanSItype 244146906Skan__absvsi2 (SItype a) 245146906Skan{ 246146906Skan SItype w = a; 247146906Skan 248146906Skan if (a < 0) 249146906Skan#ifdef L_negvsi2 250117404Skan w = __negvsi2 (a); 25190280Sobrien#else 252117404Skan w = -a; 25318334Speter 254117404Skan if (w < 0) 255117404Skan abort (); 25690280Sobrien#endif 25718334Speter 25890280Sobrien return w; 25990280Sobrien} 260146906Skan#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */ 26190280Sobrien#endif 26290280Sobrien 26390280Sobrien#ifdef L_absvdi2 26490280SobrienDWtype 265146906Skan__absvDI2 (DWtype a) 26690280Sobrien{ 267117404Skan DWtype w = a; 26818334Speter 269117404Skan if (a < 0) 270132727Skan#ifdef L_negvdi2 271146906Skan w = __negvDI2 (a); 27290280Sobrien#else 273117404Skan w = -a; 27490280Sobrien 275117404Skan if (w < 0) 276117404Skan abort (); 27718334Speter#endif 27890280Sobrien 279117404Skan return w; 28090280Sobrien} 28118334Speter#endif 28218334Speter 28390280Sobrien#ifdef L_mulvdi3 28490280SobrienDWtype 285146906Skan__mulvDI3 (DWtype u, DWtype v) 28618334Speter{ 287132727Skan /* The unchecked multiplication needs 3 Wtype x Wtype multiplications, 288132727Skan but the checked multiplication needs only two. */ 289132727Skan const DWunion uu = {.ll = u}; 290132727Skan const DWunion vv = {.ll = v}; 29118334Speter 292169699Skan if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1)) 293132727Skan { 294132727Skan /* u fits in a single Wtype. */ 295169699Skan if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) 296132727Skan { 297132727Skan /* v fits in a single Wtype as well. */ 298132727Skan /* A single multiplication. No overflow risk. */ 299132727Skan return (DWtype) uu.s.low * (DWtype) vv.s.low; 300132727Skan } 301132727Skan else 302132727Skan { 303132727Skan /* Two multiplications. */ 304132727Skan DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low 305132727Skan * (UDWtype) (UWtype) vv.s.low}; 306132727Skan DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low 307132727Skan * (UDWtype) (UWtype) vv.s.high}; 30818334Speter 309132727Skan if (vv.s.high < 0) 310132727Skan w1.s.high -= uu.s.low; 311132727Skan if (uu.s.low < 0) 312132727Skan w1.ll -= vv.ll; 313132727Skan w1.ll += (UWtype) w0.s.high; 314169699Skan if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) 315132727Skan { 316132727Skan w0.s.high = w1.s.low; 317132727Skan return w0.ll; 318132727Skan } 319132727Skan } 320132727Skan } 321132727Skan else 322132727Skan { 323169699Skan if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) 324132727Skan { 325132727Skan /* v fits into a single Wtype. */ 326132727Skan /* Two multiplications. */ 327132727Skan DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low 328132727Skan * (UDWtype) (UWtype) vv.s.low}; 329132727Skan DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high 330132727Skan * (UDWtype) (UWtype) vv.s.low}; 33118334Speter 332132727Skan if (uu.s.high < 0) 333132727Skan w1.s.high -= vv.s.low; 334132727Skan if (vv.s.low < 0) 335132727Skan w1.ll -= uu.ll; 336132727Skan w1.ll += (UWtype) w0.s.high; 337169699Skan if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) 338132727Skan { 339132727Skan w0.s.high = w1.s.low; 340132727Skan return w0.ll; 341132727Skan } 342132727Skan } 343132727Skan else 344132727Skan { 345132727Skan /* A few sign checks and a single multiplication. */ 346132727Skan if (uu.s.high >= 0) 347132727Skan { 348132727Skan if (vv.s.high >= 0) 349132727Skan { 350132727Skan if (uu.s.high == 0 && vv.s.high == 0) 351132727Skan { 352132727Skan const DWtype w = (UDWtype) (UWtype) uu.s.low 353132727Skan * (UDWtype) (UWtype) vv.s.low; 354132727Skan if (__builtin_expect (w >= 0, 1)) 355132727Skan return w; 356132727Skan } 357132727Skan } 358132727Skan else 359132727Skan { 360132727Skan if (uu.s.high == 0 && vv.s.high == (Wtype) -1) 361132727Skan { 362132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 363132727Skan * (UDWtype) (UWtype) vv.s.low}; 364132727Skan 365132727Skan ww.s.high -= uu.s.low; 366132727Skan if (__builtin_expect (ww.s.high < 0, 1)) 367132727Skan return ww.ll; 368132727Skan } 369132727Skan } 370132727Skan } 371132727Skan else 372132727Skan { 373132727Skan if (vv.s.high >= 0) 374132727Skan { 375132727Skan if (uu.s.high == (Wtype) -1 && vv.s.high == 0) 376132727Skan { 377132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 378132727Skan * (UDWtype) (UWtype) vv.s.low}; 379132727Skan 380132727Skan ww.s.high -= vv.s.low; 381132727Skan if (__builtin_expect (ww.s.high < 0, 1)) 382132727Skan return ww.ll; 383132727Skan } 384132727Skan } 385132727Skan else 386132727Skan { 387132727Skan if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1) 388132727Skan { 389132727Skan DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low 390132727Skan * (UDWtype) (UWtype) vv.s.low}; 391132727Skan 392132727Skan ww.s.high -= uu.s.low; 393132727Skan ww.s.high -= vv.s.low; 394132727Skan if (__builtin_expect (ww.s.high >= 0, 1)) 395132727Skan return ww.ll; 396132727Skan } 397132727Skan } 398132727Skan } 399132727Skan } 400132727Skan } 401132727Skan 402132727Skan /* Overflow. */ 403132727Skan abort (); 40418334Speter} 40518334Speter#endif 40618334Speter 40790280Sobrien 408132727Skan/* Unless shift functions are defined with full ANSI prototypes, 40950600Sobrien parameter b will be promoted to int if word_type is smaller than an int. */ 41018334Speter#ifdef L_lshrdi3 41190280SobrienDWtype 41290280Sobrien__lshrdi3 (DWtype u, word_type b) 41318334Speter{ 41418334Speter if (b == 0) 41518334Speter return u; 41618334Speter 417132727Skan const DWunion uu = {.ll = u}; 418132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 419132727Skan DWunion w; 42018334Speter 42118334Speter if (bm <= 0) 42218334Speter { 42318334Speter w.s.high = 0; 42490280Sobrien w.s.low = (UWtype) uu.s.high >> -bm; 42518334Speter } 42618334Speter else 42718334Speter { 428132727Skan const UWtype carries = (UWtype) uu.s.high << bm; 42990280Sobrien 43090280Sobrien w.s.high = (UWtype) uu.s.high >> b; 43190280Sobrien w.s.low = ((UWtype) uu.s.low >> b) | carries; 43218334Speter } 43318334Speter 43418334Speter return w.ll; 43518334Speter} 43618334Speter#endif 43718334Speter 43818334Speter#ifdef L_ashldi3 43990280SobrienDWtype 44090280Sobrien__ashldi3 (DWtype u, word_type b) 44118334Speter{ 44218334Speter if (b == 0) 44318334Speter return u; 44418334Speter 445132727Skan const DWunion uu = {.ll = u}; 446132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 447132727Skan DWunion w; 44818334Speter 44918334Speter if (bm <= 0) 45018334Speter { 45118334Speter w.s.low = 0; 45290280Sobrien w.s.high = (UWtype) uu.s.low << -bm; 45318334Speter } 45418334Speter else 45518334Speter { 456132727Skan const UWtype carries = (UWtype) uu.s.low >> bm; 45790280Sobrien 45890280Sobrien w.s.low = (UWtype) uu.s.low << b; 45990280Sobrien w.s.high = ((UWtype) uu.s.high << b) | carries; 46018334Speter } 46118334Speter 46218334Speter return w.ll; 46318334Speter} 46418334Speter#endif 46518334Speter 46618334Speter#ifdef L_ashrdi3 46790280SobrienDWtype 46890280Sobrien__ashrdi3 (DWtype u, word_type b) 46918334Speter{ 47018334Speter if (b == 0) 47118334Speter return u; 47218334Speter 473132727Skan const DWunion uu = {.ll = u}; 474132727Skan const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; 475132727Skan DWunion w; 47618334Speter 47718334Speter if (bm <= 0) 47818334Speter { 47918334Speter /* w.s.high = 1..1 or 0..0 */ 48090280Sobrien w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1); 48118334Speter w.s.low = uu.s.high >> -bm; 48218334Speter } 48318334Speter else 48418334Speter { 485132727Skan const UWtype carries = (UWtype) uu.s.high << bm; 48690280Sobrien 48718334Speter w.s.high = uu.s.high >> b; 48890280Sobrien w.s.low = ((UWtype) uu.s.low >> b) | carries; 48918334Speter } 49018334Speter 49118334Speter return w.ll; 49218334Speter} 49318334Speter#endif 49418334Speter 495258428Spfg#ifdef L_bswapsi2 496258428SpfgUWtype 497258428Spfg__bswapsi2 (UWtype u) 498258428Spfg{ 499258428Spfg return ((((u) & 0xff000000) >> 24) 500258428Spfg | (((u) & 0x00ff0000) >> 8) 501258428Spfg | (((u) & 0x0000ff00) << 8) 502258428Spfg | (((u) & 0x000000ff) << 24)); 503258428Spfg} 504258428Spfg#endif 505258428Spfg#ifdef L_bswapdi2 506258428SpfgUDWtype 507258428Spfg__bswapdi2 (UDWtype u) 508258428Spfg{ 509258428Spfg return ((((u) & 0xff00000000000000ull) >> 56) 510258428Spfg | (((u) & 0x00ff000000000000ull) >> 40) 511258428Spfg | (((u) & 0x0000ff0000000000ull) >> 24) 512258428Spfg | (((u) & 0x000000ff00000000ull) >> 8) 513258428Spfg | (((u) & 0x00000000ff000000ull) << 8) 514258428Spfg | (((u) & 0x0000000000ff0000ull) << 24) 515258428Spfg | (((u) & 0x000000000000ff00ull) << 40) 516258428Spfg | (((u) & 0x00000000000000ffull) << 56)); 517258428Spfg} 518258428Spfg#endif 519132727Skan#ifdef L_ffssi2 520132727Skan#undef int 521132727Skanint 522132727Skan__ffsSI2 (UWtype u) 523132727Skan{ 524132727Skan UWtype count; 525132727Skan 526132727Skan if (u == 0) 527132727Skan return 0; 528132727Skan 529132727Skan count_trailing_zeros (count, u); 530132727Skan return count + 1; 531132727Skan} 532132727Skan#endif 533132727Skan 53418334Speter#ifdef L_ffsdi2 535132727Skan#undef int 536132727Skanint 537132727Skan__ffsDI2 (DWtype u) 53818334Speter{ 539132727Skan const DWunion uu = {.ll = u}; 54090280Sobrien UWtype word, count, add; 54190280Sobrien 54290280Sobrien if (uu.s.low != 0) 54390280Sobrien word = uu.s.low, add = 0; 54490280Sobrien else if (uu.s.high != 0) 54590280Sobrien word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype); 54690280Sobrien else 54790280Sobrien return 0; 54890280Sobrien 54990280Sobrien count_trailing_zeros (count, word); 55090280Sobrien return count + add + 1; 55118334Speter} 55218334Speter#endif 55318334Speter 55418334Speter#ifdef L_muldi3 55590280SobrienDWtype 55690280Sobrien__muldi3 (DWtype u, DWtype v) 55718334Speter{ 558132727Skan const DWunion uu = {.ll = u}; 559132727Skan const DWunion vv = {.ll = v}; 560132727Skan DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; 56118334Speter 56290280Sobrien w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high 56390280Sobrien + (UWtype) uu.s.high * (UWtype) vv.s.low); 56418334Speter 56518334Speter return w.ll; 56618334Speter} 56718334Speter#endif 56818334Speter 569117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 570117404Skan defined (L_umoddi3) || defined (L_moddi3)) 571117404Skan#if defined (sdiv_qrnnd) 572117404Skan#define L_udiv_w_sdiv 573117404Skan#endif 574117404Skan#endif 575117404Skan 57618334Speter#ifdef L_udiv_w_sdiv 57718334Speter#if defined (sdiv_qrnnd) 578117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 579117404Skan defined (L_umoddi3) || defined (L_moddi3)) 580117404Skanstatic inline __attribute__ ((__always_inline__)) 581117404Skan#endif 58290280SobrienUWtype 58390280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) 58418334Speter{ 58590280Sobrien UWtype q, r; 58690280Sobrien UWtype c0, c1, b1; 58718334Speter 58890280Sobrien if ((Wtype) d >= 0) 58918334Speter { 59090280Sobrien if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) 59118334Speter { 592169699Skan /* Dividend, divisor, and quotient are nonnegative. */ 59318334Speter sdiv_qrnnd (q, r, a1, a0, d); 59418334Speter } 59518334Speter else 59618334Speter { 597169699Skan /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */ 59890280Sobrien sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); 599169699Skan /* Divide (c1*2^32 + c0) by d. */ 60018334Speter sdiv_qrnnd (q, r, c1, c0, d); 601169699Skan /* Add 2^31 to quotient. */ 60290280Sobrien q += (UWtype) 1 << (W_TYPE_SIZE - 1); 60318334Speter } 60418334Speter } 60518334Speter else 60618334Speter { 60718334Speter b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 60818334Speter c1 = a1 >> 1; /* A/2 */ 60990280Sobrien c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); 61018334Speter 61118334Speter if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 61218334Speter { 61318334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 61418334Speter 61518334Speter r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 61618334Speter if ((d & 1) != 0) 61718334Speter { 61818334Speter if (r >= q) 61918334Speter r = r - q; 62018334Speter else if (q - r <= d) 62118334Speter { 62218334Speter r = r - q + d; 62318334Speter q--; 62418334Speter } 62518334Speter else 62618334Speter { 62718334Speter r = r - q + 2*d; 62818334Speter q -= 2; 62918334Speter } 63018334Speter } 63118334Speter } 63218334Speter else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 63318334Speter { 63418334Speter c1 = (b1 - 1) - c1; 63518334Speter c0 = ~c0; /* logical NOT */ 63618334Speter 63718334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 63818334Speter 63918334Speter q = ~q; /* (A/2)/b1 */ 64018334Speter r = (b1 - 1) - r; 64118334Speter 64218334Speter r = 2*r + (a0 & 1); /* A/(2*b1) */ 64318334Speter 64418334Speter if ((d & 1) != 0) 64518334Speter { 64618334Speter if (r >= q) 64718334Speter r = r - q; 64818334Speter else if (q - r <= d) 64918334Speter { 65018334Speter r = r - q + d; 65118334Speter q--; 65218334Speter } 65318334Speter else 65418334Speter { 65518334Speter r = r - q + 2*d; 65618334Speter q -= 2; 65718334Speter } 65818334Speter } 65918334Speter } 66018334Speter else /* Implies c1 = b1 */ 66118334Speter { /* Hence a1 = d - 1 = 2*b1 - 1 */ 66218334Speter if (a0 >= -d) 66318334Speter { 66418334Speter q = -1; 66518334Speter r = a0 + d; 66618334Speter } 66718334Speter else 66818334Speter { 66918334Speter q = -2; 67018334Speter r = a0 + 2*d; 67118334Speter } 67218334Speter } 67318334Speter } 67418334Speter 67518334Speter *rp = r; 67618334Speter return q; 67718334Speter} 67818334Speter#else 67918334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ 68090280SobrienUWtype 68190280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), 68290280Sobrien UWtype a1 __attribute__ ((__unused__)), 68390280Sobrien UWtype a0 __attribute__ ((__unused__)), 68490280Sobrien UWtype d __attribute__ ((__unused__))) 68550600Sobrien{ 68650600Sobrien return 0; 68750600Sobrien} 68818334Speter#endif 68918334Speter#endif 69018334Speter 69118334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 69218334Speter defined (L_umoddi3) || defined (L_moddi3)) 69318334Speter#define L_udivmoddi4 69418334Speter#endif 69518334Speter 69690280Sobrien#ifdef L_clz 697169699Skanconst UQItype __clz_tab[256] = 69818334Speter{ 69918334Speter 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, 70018334Speter 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, 70118334Speter 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, 70218334Speter 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, 70318334Speter 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, 70418334Speter 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, 70518334Speter 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, 706169699Skan 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 70718334Speter}; 70890280Sobrien#endif 709132727Skan 710132727Skan#ifdef L_clzsi2 711132727Skan#undef int 712132727Skanint 713132727Skan__clzSI2 (UWtype x) 714132727Skan{ 715132727Skan Wtype ret; 71618334Speter 717132727Skan count_leading_zeros (ret, x); 718132727Skan 719132727Skan return ret; 720132727Skan} 721132727Skan#endif 722132727Skan 723132727Skan#ifdef L_clzdi2 724132727Skan#undef int 725132727Skanint 726132727Skan__clzDI2 (UDWtype x) 727132727Skan{ 728132727Skan const DWunion uu = {.ll = x}; 729132727Skan UWtype word; 730132727Skan Wtype ret, add; 731132727Skan 732132727Skan if (uu.s.high) 733132727Skan word = uu.s.high, add = 0; 734132727Skan else 735132727Skan word = uu.s.low, add = W_TYPE_SIZE; 736132727Skan 737132727Skan count_leading_zeros (ret, word); 738132727Skan return ret + add; 739132727Skan} 740132727Skan#endif 741132727Skan 742132727Skan#ifdef L_ctzsi2 743132727Skan#undef int 744132727Skanint 745132727Skan__ctzSI2 (UWtype x) 746132727Skan{ 747132727Skan Wtype ret; 748132727Skan 749132727Skan count_trailing_zeros (ret, x); 750132727Skan 751132727Skan return ret; 752132727Skan} 753132727Skan#endif 754132727Skan 755132727Skan#ifdef L_ctzdi2 756132727Skan#undef int 757132727Skanint 758132727Skan__ctzDI2 (UDWtype x) 759132727Skan{ 760132727Skan const DWunion uu = {.ll = x}; 761132727Skan UWtype word; 762132727Skan Wtype ret, add; 763132727Skan 764132727Skan if (uu.s.low) 765132727Skan word = uu.s.low, add = 0; 766132727Skan else 767132727Skan word = uu.s.high, add = W_TYPE_SIZE; 768132727Skan 769132727Skan count_trailing_zeros (ret, word); 770132727Skan return ret + add; 771132727Skan} 772132727Skan#endif 773132727Skan 774132727Skan#ifdef L_popcount_tab 775169699Skanconst UQItype __popcount_tab[256] = 776132727Skan{ 777132727Skan 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, 778132727Skan 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, 779132727Skan 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, 780132727Skan 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, 781132727Skan 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, 782132727Skan 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, 783132727Skan 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, 784169699Skan 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 785132727Skan}; 786132727Skan#endif 787132727Skan 788132727Skan#ifdef L_popcountsi2 789132727Skan#undef int 790132727Skanint 791132727Skan__popcountSI2 (UWtype x) 792132727Skan{ 793169699Skan int i, ret = 0; 794132727Skan 795132727Skan for (i = 0; i < W_TYPE_SIZE; i += 8) 796132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 797132727Skan 798132727Skan return ret; 799132727Skan} 800132727Skan#endif 801132727Skan 802132727Skan#ifdef L_popcountdi2 803132727Skan#undef int 804132727Skanint 805132727Skan__popcountDI2 (UDWtype x) 806132727Skan{ 807169699Skan int i, ret = 0; 808132727Skan 809132727Skan for (i = 0; i < 2*W_TYPE_SIZE; i += 8) 810132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 811132727Skan 812132727Skan return ret; 813132727Skan} 814132727Skan#endif 815132727Skan 816132727Skan#ifdef L_paritysi2 817132727Skan#undef int 818132727Skanint 819132727Skan__paritySI2 (UWtype x) 820132727Skan{ 821132727Skan#if W_TYPE_SIZE > 64 822132727Skan# error "fill out the table" 823132727Skan#endif 824132727Skan#if W_TYPE_SIZE > 32 825132727Skan x ^= x >> 32; 826132727Skan#endif 827132727Skan#if W_TYPE_SIZE > 16 828132727Skan x ^= x >> 16; 829132727Skan#endif 830132727Skan x ^= x >> 8; 831132727Skan x ^= x >> 4; 832132727Skan x &= 0xf; 833132727Skan return (0x6996 >> x) & 1; 834132727Skan} 835132727Skan#endif 836132727Skan 837132727Skan#ifdef L_paritydi2 838132727Skan#undef int 839132727Skanint 840132727Skan__parityDI2 (UDWtype x) 841132727Skan{ 842132727Skan const DWunion uu = {.ll = x}; 843132727Skan UWtype nx = uu.s.low ^ uu.s.high; 844132727Skan 845132727Skan#if W_TYPE_SIZE > 64 846132727Skan# error "fill out the table" 847132727Skan#endif 848132727Skan#if W_TYPE_SIZE > 32 849132727Skan nx ^= nx >> 32; 850132727Skan#endif 851132727Skan#if W_TYPE_SIZE > 16 852132727Skan nx ^= nx >> 16; 853132727Skan#endif 854132727Skan nx ^= nx >> 8; 855132727Skan nx ^= nx >> 4; 856132727Skan nx &= 0xf; 857132727Skan return (0x6996 >> nx) & 1; 858132727Skan} 859132727Skan#endif 860132727Skan 86190280Sobrien#ifdef L_udivmoddi4 86290280Sobrien 86318334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 86418334Speter defined (L_umoddi3) || defined (L_moddi3)) 865117404Skanstatic inline __attribute__ ((__always_inline__)) 86618334Speter#endif 86790280SobrienUDWtype 86890280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) 86918334Speter{ 870132727Skan const DWunion nn = {.ll = n}; 871132727Skan const DWunion dd = {.ll = d}; 87290280Sobrien DWunion rr; 87390280Sobrien UWtype d0, d1, n0, n1, n2; 87490280Sobrien UWtype q0, q1; 87590280Sobrien UWtype b, bm; 87618334Speter 87718334Speter d0 = dd.s.low; 87818334Speter d1 = dd.s.high; 87918334Speter n0 = nn.s.low; 88018334Speter n1 = nn.s.high; 88118334Speter 88218334Speter#if !UDIV_NEEDS_NORMALIZATION 88318334Speter if (d1 == 0) 88418334Speter { 88518334Speter if (d0 > n1) 88618334Speter { 88718334Speter /* 0q = nn / 0D */ 88818334Speter 88918334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 89018334Speter q1 = 0; 89118334Speter 89218334Speter /* Remainder in n0. */ 89318334Speter } 89418334Speter else 89518334Speter { 89618334Speter /* qq = NN / 0d */ 89718334Speter 89818334Speter if (d0 == 0) 89918334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 90018334Speter 90118334Speter udiv_qrnnd (q1, n1, 0, n1, d0); 90218334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 90318334Speter 90418334Speter /* Remainder in n0. */ 90518334Speter } 90618334Speter 90718334Speter if (rp != 0) 90818334Speter { 90918334Speter rr.s.low = n0; 91018334Speter rr.s.high = 0; 91118334Speter *rp = rr.ll; 91218334Speter } 91318334Speter } 91418334Speter 91518334Speter#else /* UDIV_NEEDS_NORMALIZATION */ 91618334Speter 91718334Speter if (d1 == 0) 91818334Speter { 91918334Speter if (d0 > n1) 92018334Speter { 92118334Speter /* 0q = nn / 0D */ 92218334Speter 92318334Speter count_leading_zeros (bm, d0); 92418334Speter 92518334Speter if (bm != 0) 92618334Speter { 92718334Speter /* Normalize, i.e. make the most significant bit of the 92818334Speter denominator set. */ 92918334Speter 93018334Speter d0 = d0 << bm; 93190280Sobrien n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); 93218334Speter n0 = n0 << bm; 93318334Speter } 93418334Speter 93518334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 93618334Speter q1 = 0; 93718334Speter 93818334Speter /* Remainder in n0 >> bm. */ 93918334Speter } 94018334Speter else 94118334Speter { 94218334Speter /* qq = NN / 0d */ 94318334Speter 94418334Speter if (d0 == 0) 94518334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 94618334Speter 94718334Speter count_leading_zeros (bm, d0); 94818334Speter 94918334Speter if (bm == 0) 95018334Speter { 95118334Speter /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 95218334Speter conclude (the most significant bit of n1 is set) /\ (the 95318334Speter leading quotient digit q1 = 1). 95418334Speter 95518334Speter This special case is necessary, not an optimization. 95690280Sobrien (Shifts counts of W_TYPE_SIZE are undefined.) */ 95718334Speter 95818334Speter n1 -= d0; 95918334Speter q1 = 1; 96018334Speter } 96118334Speter else 96218334Speter { 96318334Speter /* Normalize. */ 96418334Speter 96590280Sobrien b = W_TYPE_SIZE - bm; 96618334Speter 96718334Speter d0 = d0 << bm; 96818334Speter n2 = n1 >> b; 96918334Speter n1 = (n1 << bm) | (n0 >> b); 97018334Speter n0 = n0 << bm; 97118334Speter 97218334Speter udiv_qrnnd (q1, n1, n2, n1, d0); 97318334Speter } 97418334Speter 97550600Sobrien /* n1 != d0... */ 97618334Speter 97718334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 97818334Speter 97918334Speter /* Remainder in n0 >> bm. */ 98018334Speter } 98118334Speter 98218334Speter if (rp != 0) 98318334Speter { 98418334Speter rr.s.low = n0 >> bm; 98518334Speter rr.s.high = 0; 98618334Speter *rp = rr.ll; 98718334Speter } 98818334Speter } 98918334Speter#endif /* UDIV_NEEDS_NORMALIZATION */ 99018334Speter 99118334Speter else 99218334Speter { 99318334Speter if (d1 > n1) 99418334Speter { 99518334Speter /* 00 = nn / DD */ 99618334Speter 99718334Speter q0 = 0; 99818334Speter q1 = 0; 99918334Speter 100018334Speter /* Remainder in n1n0. */ 100118334Speter if (rp != 0) 100218334Speter { 100318334Speter rr.s.low = n0; 100418334Speter rr.s.high = n1; 100518334Speter *rp = rr.ll; 100618334Speter } 100718334Speter } 100818334Speter else 100918334Speter { 101018334Speter /* 0q = NN / dd */ 101118334Speter 101218334Speter count_leading_zeros (bm, d1); 101318334Speter if (bm == 0) 101418334Speter { 101518334Speter /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 101618334Speter conclude (the most significant bit of n1 is set) /\ (the 101718334Speter quotient digit q0 = 0 or 1). 101818334Speter 101918334Speter This special case is necessary, not an optimization. */ 102018334Speter 102118334Speter /* The condition on the next line takes advantage of that 102218334Speter n1 >= d1 (true due to program flow). */ 102318334Speter if (n1 > d1 || n0 >= d0) 102418334Speter { 102518334Speter q0 = 1; 102618334Speter sub_ddmmss (n1, n0, n1, n0, d1, d0); 102718334Speter } 102818334Speter else 102918334Speter q0 = 0; 103018334Speter 103118334Speter q1 = 0; 103218334Speter 103318334Speter if (rp != 0) 103418334Speter { 103518334Speter rr.s.low = n0; 103618334Speter rr.s.high = n1; 103718334Speter *rp = rr.ll; 103818334Speter } 103918334Speter } 104018334Speter else 104118334Speter { 104290280Sobrien UWtype m1, m0; 104318334Speter /* Normalize. */ 104418334Speter 104590280Sobrien b = W_TYPE_SIZE - bm; 104618334Speter 104718334Speter d1 = (d1 << bm) | (d0 >> b); 104818334Speter d0 = d0 << bm; 104918334Speter n2 = n1 >> b; 105018334Speter n1 = (n1 << bm) | (n0 >> b); 105118334Speter n0 = n0 << bm; 105218334Speter 105318334Speter udiv_qrnnd (q0, n1, n2, n1, d1); 105418334Speter umul_ppmm (m1, m0, q0, d0); 105518334Speter 105618334Speter if (m1 > n1 || (m1 == n1 && m0 > n0)) 105718334Speter { 105818334Speter q0--; 105918334Speter sub_ddmmss (m1, m0, m1, m0, d1, d0); 106018334Speter } 106118334Speter 106218334Speter q1 = 0; 106318334Speter 106418334Speter /* Remainder in (n1n0 - m1m0) >> bm. */ 106518334Speter if (rp != 0) 106618334Speter { 106718334Speter sub_ddmmss (n1, n0, n1, n0, m1, m0); 106818334Speter rr.s.low = (n1 << b) | (n0 >> bm); 106918334Speter rr.s.high = n1 >> bm; 107018334Speter *rp = rr.ll; 107118334Speter } 107218334Speter } 107318334Speter } 107418334Speter } 107518334Speter 1076132727Skan const DWunion ww = {{.low = q0, .high = q1}}; 107718334Speter return ww.ll; 107818334Speter} 107918334Speter#endif 108018334Speter 108118334Speter#ifdef L_divdi3 108290280SobrienDWtype 108390280Sobrien__divdi3 (DWtype u, DWtype v) 108418334Speter{ 108518334Speter word_type c = 0; 1086132727Skan DWunion uu = {.ll = u}; 1087132727Skan DWunion vv = {.ll = v}; 108890280Sobrien DWtype w; 108918334Speter 109018334Speter if (uu.s.high < 0) 109118334Speter c = ~c, 1092117404Skan uu.ll = -uu.ll; 109318334Speter if (vv.s.high < 0) 109418334Speter c = ~c, 1095117404Skan vv.ll = -vv.ll; 109618334Speter 109790280Sobrien w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); 109818334Speter if (c) 1099117404Skan w = -w; 110018334Speter 110118334Speter return w; 110218334Speter} 110318334Speter#endif 110418334Speter 110518334Speter#ifdef L_moddi3 110690280SobrienDWtype 110790280Sobrien__moddi3 (DWtype u, DWtype v) 110818334Speter{ 110918334Speter word_type c = 0; 1110132727Skan DWunion uu = {.ll = u}; 1111132727Skan DWunion vv = {.ll = v}; 111290280Sobrien DWtype w; 111318334Speter 111418334Speter if (uu.s.high < 0) 111518334Speter c = ~c, 1116117404Skan uu.ll = -uu.ll; 111718334Speter if (vv.s.high < 0) 1118117404Skan vv.ll = -vv.ll; 111918334Speter 1120169699Skan (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); 112118334Speter if (c) 1122117404Skan w = -w; 112318334Speter 112418334Speter return w; 112518334Speter} 112618334Speter#endif 112718334Speter 112818334Speter#ifdef L_umoddi3 112990280SobrienUDWtype 113090280Sobrien__umoddi3 (UDWtype u, UDWtype v) 113118334Speter{ 113290280Sobrien UDWtype w; 113318334Speter 113418334Speter (void) __udivmoddi4 (u, v, &w); 113518334Speter 113618334Speter return w; 113718334Speter} 113818334Speter#endif 113918334Speter 114018334Speter#ifdef L_udivdi3 114190280SobrienUDWtype 114290280Sobrien__udivdi3 (UDWtype n, UDWtype d) 114318334Speter{ 114490280Sobrien return __udivmoddi4 (n, d, (UDWtype *) 0); 114518334Speter} 114618334Speter#endif 114718334Speter 114818334Speter#ifdef L_cmpdi2 114918334Speterword_type 115090280Sobrien__cmpdi2 (DWtype a, DWtype b) 115118334Speter{ 1152132727Skan const DWunion au = {.ll = a}; 1153132727Skan const DWunion bu = {.ll = b}; 115418334Speter 115518334Speter if (au.s.high < bu.s.high) 115618334Speter return 0; 115718334Speter else if (au.s.high > bu.s.high) 115818334Speter return 2; 115990280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 116018334Speter return 0; 116190280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 116218334Speter return 2; 116318334Speter return 1; 116418334Speter} 116518334Speter#endif 116618334Speter 116718334Speter#ifdef L_ucmpdi2 116818334Speterword_type 116990280Sobrien__ucmpdi2 (DWtype a, DWtype b) 117018334Speter{ 1171132727Skan const DWunion au = {.ll = a}; 1172132727Skan const DWunion bu = {.ll = b}; 117318334Speter 117490280Sobrien if ((UWtype) au.s.high < (UWtype) bu.s.high) 117518334Speter return 0; 117690280Sobrien else if ((UWtype) au.s.high > (UWtype) bu.s.high) 117718334Speter return 2; 117890280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 117918334Speter return 0; 118090280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 118118334Speter return 2; 118218334Speter return 1; 118318334Speter} 118418334Speter#endif 118518334Speter 1186169699Skan#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE 118790280SobrienDWtype 118890280Sobrien__fixunstfDI (TFtype a) 118918334Speter{ 119018334Speter if (a < 0) 119118334Speter return 0; 119218334Speter 119318334Speter /* Compute high word of result, as a flonum. */ 1194169699Skan const TFtype b = (a / Wtype_MAXp1_F); 119590280Sobrien /* Convert that to fixed (but not to DWtype!), 119618334Speter and shift it into the high word. */ 1197132727Skan UDWtype v = (UWtype) b; 1198169699Skan v <<= W_TYPE_SIZE; 119918334Speter /* Remove high part from the TFtype, leaving the low part as flonum. */ 120018334Speter a -= (TFtype)v; 120190280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 120218334Speter Sometimes A comes out negative. This is significant, since 120318334Speter A has more bits than a long int does. */ 120418334Speter if (a < 0) 120590280Sobrien v -= (UWtype) (- a); 120618334Speter else 120790280Sobrien v += (UWtype) a; 120818334Speter return v; 120918334Speter} 121018334Speter#endif 121118334Speter 1212169699Skan#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE 121390280SobrienDWtype 121450600Sobrien__fixtfdi (TFtype a) 121518334Speter{ 121618334Speter if (a < 0) 121790280Sobrien return - __fixunstfDI (-a); 121890280Sobrien return __fixunstfDI (a); 121918334Speter} 122018334Speter#endif 122118334Speter 1222169699Skan#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE 122390280SobrienDWtype 122490280Sobrien__fixunsxfDI (XFtype a) 122518334Speter{ 122618334Speter if (a < 0) 122718334Speter return 0; 122818334Speter 122918334Speter /* Compute high word of result, as a flonum. */ 1230169699Skan const XFtype b = (a / Wtype_MAXp1_F); 123190280Sobrien /* Convert that to fixed (but not to DWtype!), 123218334Speter and shift it into the high word. */ 1233132727Skan UDWtype v = (UWtype) b; 1234169699Skan v <<= W_TYPE_SIZE; 123518334Speter /* Remove high part from the XFtype, leaving the low part as flonum. */ 123618334Speter a -= (XFtype)v; 123790280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 123818334Speter Sometimes A comes out negative. This is significant, since 123918334Speter A has more bits than a long int does. */ 124018334Speter if (a < 0) 124190280Sobrien v -= (UWtype) (- a); 124218334Speter else 124390280Sobrien v += (UWtype) a; 124418334Speter return v; 124518334Speter} 124618334Speter#endif 124718334Speter 1248169699Skan#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE 124990280SobrienDWtype 125050600Sobrien__fixxfdi (XFtype a) 125118334Speter{ 125218334Speter if (a < 0) 125390280Sobrien return - __fixunsxfDI (-a); 125490280Sobrien return __fixunsxfDI (a); 125518334Speter} 125618334Speter#endif 125718334Speter 1258169699Skan#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE 125990280SobrienDWtype 126090280Sobrien__fixunsdfDI (DFtype a) 126118334Speter{ 1262132727Skan /* Get high part of result. The division here will just moves the radix 1263132727Skan point and will not cause any rounding. Then the conversion to integral 1264132727Skan type chops result as desired. */ 1265169699Skan const UWtype hi = a / Wtype_MAXp1_F; 126618334Speter 1267132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1268132727Skan then subtract this from the number being converted. This leaves the low 1269132727Skan part. Convert that to integral type. */ 1270169699Skan const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F; 127118334Speter 1272132727Skan /* Assemble result from the two parts. */ 1273169699Skan return ((UDWtype) hi << W_TYPE_SIZE) | lo; 127418334Speter} 127518334Speter#endif 127618334Speter 1277169699Skan#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE 127890280SobrienDWtype 127950600Sobrien__fixdfdi (DFtype a) 128018334Speter{ 128118334Speter if (a < 0) 128290280Sobrien return - __fixunsdfDI (-a); 128390280Sobrien return __fixunsdfDI (a); 128418334Speter} 128518334Speter#endif 128618334Speter 1287169699Skan#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE 128890280SobrienDWtype 1289169699Skan__fixunssfDI (SFtype a) 129018334Speter{ 1291169699Skan#if LIBGCC2_HAS_DF_MODE 129218334Speter /* Convert the SFtype to a DFtype, because that is surely not going 129318334Speter to lose any bits. Some day someone else can write a faster version 129418334Speter that avoids converting to DFtype, and verify it really works right. */ 1295169699Skan const DFtype dfa = a; 129618334Speter 1297132727Skan /* Get high part of result. The division here will just moves the radix 1298132727Skan point and will not cause any rounding. Then the conversion to integral 1299132727Skan type chops result as desired. */ 1300169699Skan const UWtype hi = dfa / Wtype_MAXp1_F; 130118334Speter 1302132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1303132727Skan then subtract this from the number being converted. This leaves the low 1304132727Skan part. Convert that to integral type. */ 1305169699Skan const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F; 1306132727Skan 1307132727Skan /* Assemble result from the two parts. */ 1308169699Skan return ((UDWtype) hi << W_TYPE_SIZE) | lo; 1309169699Skan#elif FLT_MANT_DIG < W_TYPE_SIZE 1310169699Skan if (a < 1) 1311169699Skan return 0; 1312169699Skan if (a < Wtype_MAXp1_F) 1313169699Skan return (UWtype)a; 1314169699Skan if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) 1315169699Skan { 1316169699Skan /* Since we know that there are fewer significant bits in the SFmode 1317169699Skan quantity than in a word, we know that we can convert out all the 1318169699Skan significant bits in one step, and thus avoid losing bits. */ 1319169699Skan 1320169699Skan /* ??? This following loop essentially performs frexpf. If we could 1321169699Skan use the real libm function, or poke at the actual bits of the fp 1322169699Skan format, it would be significantly faster. */ 1323169699Skan 1324169699Skan UWtype shift = 0, counter; 1325169699Skan SFtype msb; 1326169699Skan 1327169699Skan a /= Wtype_MAXp1_F; 1328169699Skan for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) 1329169699Skan { 1330169699Skan SFtype counterf = (UWtype)1 << counter; 1331169699Skan if (a >= counterf) 1332169699Skan { 1333169699Skan shift |= counter; 1334169699Skan a /= counterf; 1335169699Skan } 1336169699Skan } 1337169699Skan 1338169699Skan /* Rescale into the range of one word, extract the bits of that 1339169699Skan one word, and shift the result into position. */ 1340169699Skan a *= Wtype_MAXp1_F; 1341169699Skan counter = a; 1342169699Skan return (DWtype)counter << shift; 1343169699Skan } 1344169699Skan return -1; 1345169699Skan#else 1346169699Skan# error 1347169699Skan#endif 134818334Speter} 134918334Speter#endif 135018334Speter 1351169699Skan#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE 135290280SobrienDWtype 135318334Speter__fixsfdi (SFtype a) 135418334Speter{ 135518334Speter if (a < 0) 135690280Sobrien return - __fixunssfDI (-a); 135790280Sobrien return __fixunssfDI (a); 135818334Speter} 135918334Speter#endif 136018334Speter 1361169699Skan#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE 136218334SpeterXFtype 136390280Sobrien__floatdixf (DWtype u) 136418334Speter{ 1365169699Skan#if W_TYPE_SIZE > XF_SIZE 1366169699Skan# error 1367169699Skan#endif 1368169699Skan XFtype d = (Wtype) (u >> W_TYPE_SIZE); 1369169699Skan d *= Wtype_MAXp1_F; 1370169699Skan d += (UWtype)u; 1371169699Skan return d; 1372169699Skan} 1373169699Skan#endif 137418334Speter 1375169699Skan#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE 1376169699SkanXFtype 1377169699Skan__floatundixf (UDWtype u) 1378169699Skan{ 1379169699Skan#if W_TYPE_SIZE > XF_SIZE 1380169699Skan# error 1381169699Skan#endif 1382169699Skan XFtype d = (UWtype) (u >> W_TYPE_SIZE); 1383169699Skan d *= Wtype_MAXp1_F; 1384169699Skan d += (UWtype)u; 138550600Sobrien return d; 138618334Speter} 138718334Speter#endif 138818334Speter 1389169699Skan#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE 139018334SpeterTFtype 139190280Sobrien__floatditf (DWtype u) 139218334Speter{ 1393169699Skan#if W_TYPE_SIZE > TF_SIZE 1394169699Skan# error 1395169699Skan#endif 1396169699Skan TFtype d = (Wtype) (u >> W_TYPE_SIZE); 1397169699Skan d *= Wtype_MAXp1_F; 1398169699Skan d += (UWtype)u; 1399169699Skan return d; 1400169699Skan} 1401169699Skan#endif 140218334Speter 1403169699Skan#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE 1404169699SkanTFtype 1405169699Skan__floatunditf (UDWtype u) 1406169699Skan{ 1407169699Skan#if W_TYPE_SIZE > TF_SIZE 1408169699Skan# error 1409169699Skan#endif 1410169699Skan TFtype d = (UWtype) (u >> W_TYPE_SIZE); 1411169699Skan d *= Wtype_MAXp1_F; 1412169699Skan d += (UWtype)u; 141350600Sobrien return d; 141418334Speter} 141518334Speter#endif 141618334Speter 1417169699Skan#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \ 1418169699Skan || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE) 1419169699Skan#define DI_SIZE (W_TYPE_SIZE * 2) 1420169699Skan#define F_MODE_OK(SIZE) \ 1421169699Skan (SIZE < DI_SIZE \ 1422169699Skan && SIZE > (DI_SIZE - SIZE + FSSIZE) \ 1423260194Spfg /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ 1424260194Spfg The conversion from long double to float suffers from double \ 1425260194Spfg rounding, because we convert via double. In any case, the \ 1426260194Spfg fallback code is faster. */ \ 1427260194Spfg && !IS_IBM_EXTENDED (SIZE)) 1428169699Skan#if defined(L_floatdisf) 1429169699Skan#define FUNC __floatdisf 1430169699Skan#define FSTYPE SFtype 1431169699Skan#define FSSIZE SF_SIZE 1432169699Skan#else 1433169699Skan#define FUNC __floatdidf 1434169699Skan#define FSTYPE DFtype 1435169699Skan#define FSSIZE DF_SIZE 1436169699Skan#endif 143718334Speter 1438169699SkanFSTYPE 1439169699SkanFUNC (DWtype u) 144018334Speter{ 1441169699Skan#if FSSIZE >= W_TYPE_SIZE 1442169699Skan /* When the word size is small, we never get any rounding error. */ 1443169699Skan FSTYPE f = (Wtype) (u >> W_TYPE_SIZE); 1444169699Skan f *= Wtype_MAXp1_F; 1445169699Skan f += (UWtype)u; 1446169699Skan return f; 1447169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ 1448169699Skan || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ 1449169699Skan || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 145018334Speter 1451169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) 1452169699Skan# define FSIZE DF_SIZE 1453169699Skan# define FTYPE DFtype 1454169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) 1455169699Skan# define FSIZE XF_SIZE 1456169699Skan# define FTYPE XFtype 1457169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 1458169699Skan# define FSIZE TF_SIZE 1459169699Skan# define FTYPE TFtype 1460169699Skan#else 1461169699Skan# error 1462169699Skan#endif 1463169699Skan 1464169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) 1465169699Skan 1466169699Skan /* Protect against double-rounding error. 1467169699Skan Represent any low-order bits, that might be truncated by a bit that 1468169699Skan won't be lost. The bit can go in anywhere below the rounding position 1469169699Skan of the FSTYPE. A fixed mask and bit position handles all usual 1470169699Skan configurations. */ 1471169699Skan if (! (- ((DWtype) 1 << FSIZE) < u 1472169699Skan && u < ((DWtype) 1 << FSIZE))) 1473169699Skan { 1474169699Skan if ((UDWtype) u & (REP_BIT - 1)) 1475169699Skan { 1476169699Skan u &= ~ (REP_BIT - 1); 1477169699Skan u |= REP_BIT; 1478169699Skan } 1479169699Skan } 1480169699Skan 1481169699Skan /* Do the calculation in a wider type so that we don't lose any of 1482169699Skan the precision of the high word while multiplying it. */ 1483169699Skan FTYPE f = (Wtype) (u >> W_TYPE_SIZE); 1484169699Skan f *= Wtype_MAXp1_F; 1485169699Skan f += (UWtype)u; 1486169699Skan return (FSTYPE) f; 1487169699Skan#else 1488169699Skan#if FSSIZE >= W_TYPE_SIZE - 2 1489169699Skan# error 1490169699Skan#endif 1491169699Skan /* Finally, the word size is larger than the number of bits in the 1492169699Skan required FSTYPE, and we've got no suitable wider type. The only 1493169699Skan way to avoid double rounding is to special case the 1494169699Skan extraction. */ 1495169699Skan 1496169699Skan /* If there are no high bits set, fall back to one conversion. */ 1497169699Skan if ((Wtype)u == u) 1498169699Skan return (FSTYPE)(Wtype)u; 1499169699Skan 1500169699Skan /* Otherwise, find the power of two. */ 1501169699Skan Wtype hi = u >> W_TYPE_SIZE; 1502169699Skan if (hi < 0) 1503169699Skan hi = -hi; 1504169699Skan 1505169699Skan UWtype count, shift; 1506169699Skan count_leading_zeros (count, hi); 1507169699Skan 1508169699Skan /* No leading bits means u == minimum. */ 1509169699Skan if (count == 0) 1510169699Skan return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2)); 1511169699Skan 1512169699Skan shift = 1 + W_TYPE_SIZE - count; 1513169699Skan 1514169699Skan /* Shift down the most significant bits. */ 1515169699Skan hi = u >> shift; 1516169699Skan 1517169699Skan /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ 1518260194Spfg if (u & (((DWtype)1 << shift) - 1)) 1519169699Skan hi |= 1; 1520169699Skan 1521169699Skan /* Convert the one word of data, and rescale. */ 1522260194Spfg FSTYPE f = hi; 1523260194Spfg f *= (UDWtype)1 << shift; 1524260194Spfg return f; 1525169699Skan#endif 152618334Speter} 152718334Speter#endif 152818334Speter 1529169699Skan#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \ 1530169699Skan || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE) 1531169699Skan#define DI_SIZE (W_TYPE_SIZE * 2) 1532169699Skan#define F_MODE_OK(SIZE) \ 1533169699Skan (SIZE < DI_SIZE \ 1534169699Skan && SIZE > (DI_SIZE - SIZE + FSSIZE) \ 1535260194Spfg /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ 1536260194Spfg The conversion from long double to float suffers from double \ 1537260194Spfg rounding, because we convert via double. In any case, the \ 1538260194Spfg fallback code is faster. */ \ 1539260194Spfg && !IS_IBM_EXTENDED (SIZE)) 1540169699Skan#if defined(L_floatundisf) 1541169699Skan#define FUNC __floatundisf 1542169699Skan#define FSTYPE SFtype 1543169699Skan#define FSSIZE SF_SIZE 1544169699Skan#else 1545169699Skan#define FUNC __floatundidf 1546169699Skan#define FSTYPE DFtype 1547169699Skan#define FSSIZE DF_SIZE 1548169699Skan#endif 1549117404Skan 1550169699SkanFSTYPE 1551169699SkanFUNC (UDWtype u) 1552169699Skan{ 1553169699Skan#if FSSIZE >= W_TYPE_SIZE 1554169699Skan /* When the word size is small, we never get any rounding error. */ 1555169699Skan FSTYPE f = (UWtype) (u >> W_TYPE_SIZE); 1556169699Skan f *= Wtype_MAXp1_F; 1557169699Skan f += (UWtype)u; 1558169699Skan return f; 1559169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ 1560169699Skan || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ 1561169699Skan || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 156218334Speter 1563169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) 1564169699Skan# define FSIZE DF_SIZE 1565169699Skan# define FTYPE DFtype 1566169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) 1567169699Skan# define FSIZE XF_SIZE 1568169699Skan# define FTYPE XFtype 1569169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 1570169699Skan# define FSIZE TF_SIZE 1571169699Skan# define FTYPE TFtype 1572169699Skan#else 1573169699Skan# error 1574169699Skan#endif 1575169699Skan 1576169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) 1577169699Skan 157818334Speter /* Protect against double-rounding error. 1579169699Skan Represent any low-order bits, that might be truncated by a bit that 1580169699Skan won't be lost. The bit can go in anywhere below the rounding position 1581169699Skan of the FSTYPE. A fixed mask and bit position handles all usual 1582169699Skan configurations. */ 1583169699Skan if (u >= ((UDWtype) 1 << FSIZE)) 158418334Speter { 1585169699Skan if ((UDWtype) u & (REP_BIT - 1)) 158618334Speter { 1587169699Skan u &= ~ (REP_BIT - 1); 1588169699Skan u |= REP_BIT; 158918334Speter } 159018334Speter } 159118334Speter 1592169699Skan /* Do the calculation in a wider type so that we don't lose any of 1593169699Skan the precision of the high word while multiplying it. */ 1594169699Skan FTYPE f = (UWtype) (u >> W_TYPE_SIZE); 1595169699Skan f *= Wtype_MAXp1_F; 1596169699Skan f += (UWtype)u; 1597169699Skan return (FSTYPE) f; 1598169699Skan#else 1599169699Skan#if FSSIZE == W_TYPE_SIZE - 1 1600169699Skan# error 1601169699Skan#endif 1602169699Skan /* Finally, the word size is larger than the number of bits in the 1603169699Skan required FSTYPE, and we've got no suitable wider type. The only 1604169699Skan way to avoid double rounding is to special case the 1605169699Skan extraction. */ 1606169699Skan 1607169699Skan /* If there are no high bits set, fall back to one conversion. */ 1608169699Skan if ((UWtype)u == u) 1609169699Skan return (FSTYPE)(UWtype)u; 1610169699Skan 1611169699Skan /* Otherwise, find the power of two. */ 1612169699Skan UWtype hi = u >> W_TYPE_SIZE; 1613169699Skan 1614169699Skan UWtype count, shift; 1615169699Skan count_leading_zeros (count, hi); 1616169699Skan 1617169699Skan shift = W_TYPE_SIZE - count; 1618169699Skan 1619169699Skan /* Shift down the most significant bits. */ 1620169699Skan hi = u >> shift; 1621169699Skan 1622169699Skan /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ 1623260194Spfg if (u & (((UDWtype)1 << shift) - 1)) 1624169699Skan hi |= 1; 1625169699Skan 1626169699Skan /* Convert the one word of data, and rescale. */ 1627260194Spfg FSTYPE f = hi; 1628260194Spfg f *= (UDWtype)1 << shift; 1629260194Spfg return f; 1630169699Skan#endif 163118334Speter} 163218334Speter#endif 163318334Speter 1634169699Skan#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE 163518334Speter/* Reenable the normal types, in case limits.h needs them. */ 163618334Speter#undef char 163718334Speter#undef short 163818334Speter#undef int 163918334Speter#undef long 164018334Speter#undef unsigned 164118334Speter#undef float 164218334Speter#undef double 164318334Speter#undef MIN 164418334Speter#undef MAX 164518334Speter#include <limits.h> 164618334Speter 164790280SobrienUWtype 164890280Sobrien__fixunsxfSI (XFtype a) 164918334Speter{ 165090280Sobrien if (a >= - (DFtype) Wtype_MIN) 165190280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 165290280Sobrien return (Wtype) a; 165318334Speter} 165418334Speter#endif 165518334Speter 1656169699Skan#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE 165718334Speter/* Reenable the normal types, in case limits.h needs them. */ 165818334Speter#undef char 165918334Speter#undef short 166018334Speter#undef int 166118334Speter#undef long 166218334Speter#undef unsigned 166318334Speter#undef float 166418334Speter#undef double 166518334Speter#undef MIN 166618334Speter#undef MAX 166718334Speter#include <limits.h> 166818334Speter 166990280SobrienUWtype 167090280Sobrien__fixunsdfSI (DFtype a) 167118334Speter{ 167290280Sobrien if (a >= - (DFtype) Wtype_MIN) 167390280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 167490280Sobrien return (Wtype) a; 167518334Speter} 167618334Speter#endif 167718334Speter 1678169699Skan#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE 167918334Speter/* Reenable the normal types, in case limits.h needs them. */ 168018334Speter#undef char 168118334Speter#undef short 168218334Speter#undef int 168318334Speter#undef long 168418334Speter#undef unsigned 168518334Speter#undef float 168618334Speter#undef double 168718334Speter#undef MIN 168818334Speter#undef MAX 168918334Speter#include <limits.h> 169018334Speter 169190280SobrienUWtype 169290280Sobrien__fixunssfSI (SFtype a) 169318334Speter{ 169490280Sobrien if (a >= - (SFtype) Wtype_MIN) 169590280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 169690280Sobrien return (Wtype) a; 169718334Speter} 169818334Speter#endif 169918334Speter 1700169699Skan/* Integer power helper used from __builtin_powi for non-constant 1701169699Skan exponents. */ 1702169699Skan 1703169699Skan#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \ 1704169699Skan || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \ 1705169699Skan || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \ 1706169699Skan || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE) 1707169699Skan# if defined(L_powisf2) 1708169699Skan# define TYPE SFtype 1709169699Skan# define NAME __powisf2 1710169699Skan# elif defined(L_powidf2) 1711169699Skan# define TYPE DFtype 1712169699Skan# define NAME __powidf2 1713169699Skan# elif defined(L_powixf2) 1714169699Skan# define TYPE XFtype 1715169699Skan# define NAME __powixf2 1716169699Skan# elif defined(L_powitf2) 1717169699Skan# define TYPE TFtype 1718169699Skan# define NAME __powitf2 1719169699Skan# endif 1720169699Skan 1721169699Skan#undef int 1722169699Skan#undef unsigned 1723169699SkanTYPE 1724169699SkanNAME (TYPE x, int m) 1725169699Skan{ 1726169699Skan unsigned int n = m < 0 ? -m : m; 1727169699Skan TYPE y = n % 2 ? x : 1; 1728169699Skan while (n >>= 1) 1729169699Skan { 1730169699Skan x = x * x; 1731169699Skan if (n % 2) 1732169699Skan y = y * x; 1733169699Skan } 1734169699Skan return m < 0 ? 1/y : y; 1735169699Skan} 1736169699Skan 1737169699Skan#endif 1738169699Skan 1739169699Skan#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ 1740169699Skan || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \ 1741169699Skan || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \ 1742169699Skan || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE) 1743169699Skan 1744169699Skan#undef float 1745169699Skan#undef double 1746169699Skan#undef long 1747169699Skan 1748169699Skan#if defined(L_mulsc3) || defined(L_divsc3) 1749169699Skan# define MTYPE SFtype 1750169699Skan# define CTYPE SCtype 1751169699Skan# define MODE sc 1752169699Skan# define CEXT f 1753169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0 1754169699Skan#elif defined(L_muldc3) || defined(L_divdc3) 1755169699Skan# define MTYPE DFtype 1756169699Skan# define CTYPE DCtype 1757169699Skan# define MODE dc 1758169699Skan# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64 1759169699Skan# define CEXT l 1760169699Skan# define NOTRUNC 1 1761169699Skan# else 1762169699Skan# define CEXT 1763169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1 1764169699Skan# endif 1765169699Skan#elif defined(L_mulxc3) || defined(L_divxc3) 1766169699Skan# define MTYPE XFtype 1767169699Skan# define CTYPE XCtype 1768169699Skan# define MODE xc 1769169699Skan# define CEXT l 1770169699Skan# define NOTRUNC 1 1771169699Skan#elif defined(L_multc3) || defined(L_divtc3) 1772169699Skan# define MTYPE TFtype 1773169699Skan# define CTYPE TCtype 1774169699Skan# define MODE tc 1775169699Skan# define CEXT l 1776169699Skan# define NOTRUNC 1 1777169699Skan#else 1778169699Skan# error 1779169699Skan#endif 1780169699Skan 1781169699Skan#define CONCAT3(A,B,C) _CONCAT3(A,B,C) 1782169699Skan#define _CONCAT3(A,B,C) A##B##C 1783169699Skan 1784169699Skan#define CONCAT2(A,B) _CONCAT2(A,B) 1785169699Skan#define _CONCAT2(A,B) A##B 1786169699Skan 1787169699Skan/* All of these would be present in a full C99 implementation of <math.h> 1788169699Skan and <complex.h>. Our problem is that only a few systems have such full 1789169699Skan implementations. Further, libgcc_s.so isn't currently linked against 1790169699Skan libm.so, and even for systems that do provide full C99, the extra overhead 1791169699Skan of all programs using libgcc having to link against libm. So avoid it. */ 1792169699Skan 1793169699Skan#define isnan(x) __builtin_expect ((x) != (x), 0) 1794169699Skan#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1) 1795169699Skan#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0) 1796169699Skan 1797169699Skan#define INFINITY CONCAT2(__builtin_inf, CEXT) () 1798169699Skan#define I 1i 1799169699Skan 1800169699Skan/* Helpers to make the following code slightly less gross. */ 1801169699Skan#define COPYSIGN CONCAT2(__builtin_copysign, CEXT) 1802169699Skan#define FABS CONCAT2(__builtin_fabs, CEXT) 1803169699Skan 1804169699Skan/* Verify that MTYPE matches up with CEXT. */ 1805169699Skanextern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1]; 1806169699Skan 1807169699Skan/* Ensure that we've lost any extra precision. */ 1808169699Skan#if NOTRUNC 1809169699Skan# define TRUNC(x) 1810169699Skan#else 1811169699Skan# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x)) 1812169699Skan#endif 1813169699Skan 1814169699Skan#if defined(L_mulsc3) || defined(L_muldc3) \ 1815169699Skan || defined(L_mulxc3) || defined(L_multc3) 1816169699Skan 1817169699SkanCTYPE 1818169699SkanCONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) 1819169699Skan{ 1820169699Skan MTYPE ac, bd, ad, bc, x, y; 1821169699Skan 1822169699Skan ac = a * c; 1823169699Skan bd = b * d; 1824169699Skan ad = a * d; 1825169699Skan bc = b * c; 1826169699Skan 1827169699Skan TRUNC (ac); 1828169699Skan TRUNC (bd); 1829169699Skan TRUNC (ad); 1830169699Skan TRUNC (bc); 1831169699Skan 1832169699Skan x = ac - bd; 1833169699Skan y = ad + bc; 1834169699Skan 1835169699Skan if (isnan (x) && isnan (y)) 1836169699Skan { 1837169699Skan /* Recover infinities that computed as NaN + iNaN. */ 1838169699Skan _Bool recalc = 0; 1839169699Skan if (isinf (a) || isinf (b)) 1840169699Skan { 1841169699Skan /* z is infinite. "Box" the infinity and change NaNs in 1842169699Skan the other factor to 0. */ 1843169699Skan a = COPYSIGN (isinf (a) ? 1 : 0, a); 1844169699Skan b = COPYSIGN (isinf (b) ? 1 : 0, b); 1845169699Skan if (isnan (c)) c = COPYSIGN (0, c); 1846169699Skan if (isnan (d)) d = COPYSIGN (0, d); 1847169699Skan recalc = 1; 1848169699Skan } 1849169699Skan if (isinf (c) || isinf (d)) 1850169699Skan { 1851169699Skan /* w is infinite. "Box" the infinity and change NaNs in 1852169699Skan the other factor to 0. */ 1853169699Skan c = COPYSIGN (isinf (c) ? 1 : 0, c); 1854169699Skan d = COPYSIGN (isinf (d) ? 1 : 0, d); 1855169699Skan if (isnan (a)) a = COPYSIGN (0, a); 1856169699Skan if (isnan (b)) b = COPYSIGN (0, b); 1857169699Skan recalc = 1; 1858169699Skan } 1859169699Skan if (!recalc 1860169699Skan && (isinf (ac) || isinf (bd) 1861169699Skan || isinf (ad) || isinf (bc))) 1862169699Skan { 1863169699Skan /* Recover infinities from overflow by changing NaNs to 0. */ 1864169699Skan if (isnan (a)) a = COPYSIGN (0, a); 1865169699Skan if (isnan (b)) b = COPYSIGN (0, b); 1866169699Skan if (isnan (c)) c = COPYSIGN (0, c); 1867169699Skan if (isnan (d)) d = COPYSIGN (0, d); 1868169699Skan recalc = 1; 1869169699Skan } 1870169699Skan if (recalc) 1871169699Skan { 1872169699Skan x = INFINITY * (a * c - b * d); 1873169699Skan y = INFINITY * (a * d + b * c); 1874169699Skan } 1875169699Skan } 1876169699Skan 1877169699Skan return x + I * y; 1878169699Skan} 1879169699Skan#endif /* complex multiply */ 1880169699Skan 1881169699Skan#if defined(L_divsc3) || defined(L_divdc3) \ 1882169699Skan || defined(L_divxc3) || defined(L_divtc3) 1883169699Skan 1884169699SkanCTYPE 1885169699SkanCONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) 1886169699Skan{ 1887169699Skan MTYPE denom, ratio, x, y; 1888169699Skan 1889258428Spfg /* ??? We can get better behavior from logarithmic scaling instead of 1890169699Skan the division. But that would mean starting to link libgcc against 1891169699Skan libm. We could implement something akin to ldexp/frexp as gcc builtins 1892169699Skan fairly easily... */ 1893169699Skan if (FABS (c) < FABS (d)) 1894169699Skan { 1895169699Skan ratio = c / d; 1896169699Skan denom = (c * ratio) + d; 1897169699Skan x = ((a * ratio) + b) / denom; 1898169699Skan y = ((b * ratio) - a) / denom; 1899169699Skan } 1900169699Skan else 1901169699Skan { 1902169699Skan ratio = d / c; 1903169699Skan denom = (d * ratio) + c; 1904169699Skan x = ((b * ratio) + a) / denom; 1905169699Skan y = (b - (a * ratio)) / denom; 1906169699Skan } 1907169699Skan 1908169699Skan /* Recover infinities and zeros that computed as NaN+iNaN; the only cases 1909169699Skan are nonzero/zero, infinite/finite, and finite/infinite. */ 1910169699Skan if (isnan (x) && isnan (y)) 1911169699Skan { 1912169699Skan if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) 1913169699Skan { 1914169699Skan x = COPYSIGN (INFINITY, c) * a; 1915169699Skan y = COPYSIGN (INFINITY, c) * b; 1916169699Skan } 1917169699Skan else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) 1918169699Skan { 1919169699Skan a = COPYSIGN (isinf (a) ? 1 : 0, a); 1920169699Skan b = COPYSIGN (isinf (b) ? 1 : 0, b); 1921169699Skan x = INFINITY * (a * c + b * d); 1922169699Skan y = INFINITY * (b * c - a * d); 1923169699Skan } 1924169699Skan else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) 1925169699Skan { 1926169699Skan c = COPYSIGN (isinf (c) ? 1 : 0, c); 1927169699Skan d = COPYSIGN (isinf (d) ? 1 : 0, d); 1928169699Skan x = 0.0 * (a * c + b * d); 1929169699Skan y = 0.0 * (b * c - a * d); 1930169699Skan } 1931169699Skan } 1932169699Skan 1933169699Skan return x + I * y; 1934169699Skan} 1935169699Skan#endif /* complex divide */ 1936169699Skan 1937169699Skan#endif /* all complex float routines */ 1938169699Skan 193918334Speter/* From here on down, the routines use normal data types. */ 194018334Speter 194118334Speter#define SItype bogus_type 194218334Speter#define USItype bogus_type 194318334Speter#define DItype bogus_type 194418334Speter#define UDItype bogus_type 194518334Speter#define SFtype bogus_type 194618334Speter#define DFtype bogus_type 194790280Sobrien#undef Wtype 194890280Sobrien#undef UWtype 194990280Sobrien#undef HWtype 195090280Sobrien#undef UHWtype 195190280Sobrien#undef DWtype 195290280Sobrien#undef UDWtype 195318334Speter 195418334Speter#undef char 195518334Speter#undef short 195618334Speter#undef int 195718334Speter#undef long 195818334Speter#undef unsigned 195918334Speter#undef float 196018334Speter#undef double 196118334Speter 196218334Speter#ifdef L__gcc_bcmp 196318334Speter 196418334Speter/* Like bcmp except the sign is meaningful. 196518334Speter Result is negative if S1 is less than S2, 196618334Speter positive if S1 is greater, 0 if S1 and S2 are equal. */ 196718334Speter 196818334Speterint 196990280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) 197018334Speter{ 197118334Speter while (size > 0) 197218334Speter { 1973132727Skan const unsigned char c1 = *s1++, c2 = *s2++; 197418334Speter if (c1 != c2) 197518334Speter return c1 - c2; 197618334Speter size--; 197718334Speter } 197818334Speter return 0; 197918334Speter} 198018334Speter 198118334Speter#endif 198218334Speter 198390280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>. 198490280Sobrien We no longer provide that header, but this routine remains in libgcc.a 198590280Sobrien for binary backward compatibility. Note that it is not included in 198690280Sobrien the shared version of libgcc. */ 198718334Speter#ifdef L_eprintf 198818334Speter#ifndef inhibit_libc 198918334Speter 199018334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 199118334Speter#include <stdio.h> 199252561Sobrien 199318334Spetervoid 199450600Sobrien__eprintf (const char *string, const char *expression, 199550600Sobrien unsigned int line, const char *filename) 199618334Speter{ 199718334Speter fprintf (stderr, string, expression, line, filename); 199818334Speter fflush (stderr); 199918334Speter abort (); 200018334Speter} 200118334Speter 200218334Speter#endif 200318334Speter#endif 200418334Speter 200518334Speter 200618334Speter#ifdef L_clear_cache 200718334Speter/* Clear part of an instruction cache. */ 200818334Speter 200918334Spetervoid 2010261991Sdim__clear_cache (void *beg __attribute__((__unused__)), 2011261991Sdim void *end __attribute__((__unused__))) 201218334Speter{ 201390280Sobrien#ifdef CLEAR_INSN_CACHE 201418334Speter CLEAR_INSN_CACHE (beg, end); 201518334Speter#endif /* CLEAR_INSN_CACHE */ 201618334Speter} 201718334Speter 201818334Speter#endif /* L_clear_cache */ 201918334Speter 2020132727Skan#ifdef L_enable_execute_stack 2021132727Skan/* Attempt to turn on execute permission for the stack. */ 2022132727Skan 2023132727Skan#ifdef ENABLE_EXECUTE_STACK 2024132727Skan ENABLE_EXECUTE_STACK 2025132727Skan#else 2026132727Skanvoid 2027132727Skan__enable_execute_stack (void *addr __attribute__((__unused__))) 2028132727Skan{} 2029132727Skan#endif /* ENABLE_EXECUTE_STACK */ 2030132727Skan 2031132727Skan#endif /* L_enable_execute_stack */ 2032132727Skan 203318334Speter#ifdef L_trampoline 203418334Speter 203518334Speter/* Jump to a trampoline, loading the static chain address. */ 203618334Speter 203752561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) 203818334Speter 2039169699Skanint 204090280Sobriengetpagesize (void) 204118334Speter{ 204218334Speter#ifdef _ALPHA_ 204318334Speter return 8192; 204418334Speter#else 204518334Speter return 4096; 204618334Speter#endif 204718334Speter} 204818334Speter 204990280Sobrien#ifdef __i386__ 205050600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); 205150600Sobrien#endif 205250600Sobrien 205350600Sobrienint 205450600Sobrienmprotect (char *addr, int len, int prot) 205518334Speter{ 205618334Speter int np, op; 205718334Speter 205850600Sobrien if (prot == 7) 205950600Sobrien np = 0x40; 206050600Sobrien else if (prot == 5) 206150600Sobrien np = 0x20; 206250600Sobrien else if (prot == 4) 206350600Sobrien np = 0x10; 206450600Sobrien else if (prot == 3) 206550600Sobrien np = 0x04; 206650600Sobrien else if (prot == 1) 206750600Sobrien np = 0x02; 206850600Sobrien else if (prot == 0) 206950600Sobrien np = 0x01; 207018334Speter 207118334Speter if (VirtualProtect (addr, len, np, &op)) 207218334Speter return 0; 207318334Speter else 207418334Speter return -1; 207518334Speter} 207618334Speter 207752561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ 207818334Speter 207990280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE 208090280SobrienTRANSFER_FROM_TRAMPOLINE 208118334Speter#endif 208218334Speter#endif /* L_trampoline */ 208318334Speter 208452561Sobrien#ifndef __CYGWIN__ 208518334Speter#ifdef L__main 208618334Speter 208718334Speter#include "gbl-ctors.h" 2088169699Skan 208918334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these 209018334Speter cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 209118334Speter give the same symbol without quotes for an alternative entry point. You 209250600Sobrien must define both, or neither. */ 209318334Speter#ifndef NAME__MAIN 209418334Speter#define NAME__MAIN "__main" 209518334Speter#define SYMBOL__MAIN __main 209618334Speter#endif 209718334Speter 2098169699Skan#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP) 209950600Sobrien#undef HAS_INIT_SECTION 210050600Sobrien#define HAS_INIT_SECTION 210150600Sobrien#endif 210250600Sobrien 210350600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) 210490280Sobrien 210590280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this 210690280Sobrien code to run constructors. In that case, we need to handle EH here, too. */ 210790280Sobrien 210890280Sobrien#ifdef EH_FRAME_SECTION_NAME 210990280Sobrien#include "unwind-dw2-fde.h" 211090280Sobrienextern unsigned char __EH_FRAME_BEGIN__[]; 211190280Sobrien#endif 211290280Sobrien 211318334Speter/* Run all the global destructors on exit from the program. */ 211418334Speter 211518334Spetervoid 211690280Sobrien__do_global_dtors (void) 211718334Speter{ 211818334Speter#ifdef DO_GLOBAL_DTORS_BODY 211918334Speter DO_GLOBAL_DTORS_BODY; 212018334Speter#else 212150600Sobrien static func_ptr *p = __DTOR_LIST__ + 1; 212250600Sobrien while (*p) 212350600Sobrien { 212450600Sobrien p++; 212550600Sobrien (*(p-1)) (); 212650600Sobrien } 212718334Speter#endif 212890280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) 212990280Sobrien { 213090280Sobrien static int completed = 0; 213190280Sobrien if (! completed) 213290280Sobrien { 213390280Sobrien completed = 1; 213490280Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 213590280Sobrien } 213690280Sobrien } 213790280Sobrien#endif 213818334Speter} 213950600Sobrien#endif 214018334Speter 214150600Sobrien#ifndef HAS_INIT_SECTION 214218334Speter/* Run all the global constructors on entry to the program. */ 214318334Speter 214418334Spetervoid 214590280Sobrien__do_global_ctors (void) 214618334Speter{ 214790280Sobrien#ifdef EH_FRAME_SECTION_NAME 214890280Sobrien { 214990280Sobrien static struct object object; 215090280Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 215190280Sobrien } 215290280Sobrien#endif 215318334Speter DO_GLOBAL_CTORS_BODY; 215490280Sobrien atexit (__do_global_dtors); 215518334Speter} 215650600Sobrien#endif /* no HAS_INIT_SECTION */ 215718334Speter 215850600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) 215918334Speter/* Subroutine called automatically by `main'. 216018334Speter Compiling a global function named `main' 216118334Speter produces an automatic call to this function at the beginning. 216218334Speter 216318334Speter For many systems, this routine calls __do_global_ctors. 216418334Speter For systems which support a .init section we use the .init section 216518334Speter to run __do_global_ctors, so we need not do anything here. */ 216618334Speter 2167132727Skanextern void SYMBOL__MAIN (void); 216818334Spetervoid 2169132727SkanSYMBOL__MAIN (void) 217018334Speter{ 217118334Speter /* Support recursive calls to `main': run initializers just once. */ 217218334Speter static int initialized; 217318334Speter if (! initialized) 217418334Speter { 217518334Speter initialized = 1; 217618334Speter __do_global_ctors (); 217718334Speter } 217818334Speter} 217950600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */ 218018334Speter 218118334Speter#endif /* L__main */ 218252561Sobrien#endif /* __CYGWIN__ */ 218318334Speter 218418334Speter#ifdef L_ctors 218518334Speter 218618334Speter#include "gbl-ctors.h" 218718334Speter 218818334Speter/* Provide default definitions for the lists of constructors and 218918334Speter destructors, so that we don't get linker errors. These symbols are 219018334Speter intentionally bss symbols, so that gld and/or collect will provide 219118334Speter the right values. */ 219218334Speter 219318334Speter/* We declare the lists here with two elements each, 219452561Sobrien so that they are valid empty lists if no other definition is loaded. 219552561Sobrien 219652561Sobrien If we are using the old "set" extensions to have the gnu linker 219752561Sobrien collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ 219852561Sobrien must be in the bss/common section. 219952561Sobrien 220052561Sobrien Long term no port should use those extensions. But many still do. */ 220150600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 220290280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) 220318334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0}; 220418334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0}; 220518334Speter#else 220618334Speterfunc_ptr __CTOR_LIST__[2]; 220718334Speterfunc_ptr __DTOR_LIST__[2]; 220818334Speter#endif 220918334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 221018334Speter#endif /* L_ctors */ 2211169699Skan#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */ 2212