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 495132727Skan#ifdef L_ffssi2 496132727Skan#undef int 497132727Skanint 498132727Skan__ffsSI2 (UWtype u) 499132727Skan{ 500132727Skan UWtype count; 501132727Skan 502132727Skan if (u == 0) 503132727Skan return 0; 504132727Skan 505132727Skan count_trailing_zeros (count, u); 506132727Skan return count + 1; 507132727Skan} 508132727Skan#endif 509132727Skan 51018334Speter#ifdef L_ffsdi2 511132727Skan#undef int 512132727Skanint 513132727Skan__ffsDI2 (DWtype u) 51418334Speter{ 515132727Skan const DWunion uu = {.ll = u}; 51690280Sobrien UWtype word, count, add; 51790280Sobrien 51890280Sobrien if (uu.s.low != 0) 51990280Sobrien word = uu.s.low, add = 0; 52090280Sobrien else if (uu.s.high != 0) 52190280Sobrien word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype); 52290280Sobrien else 52390280Sobrien return 0; 52490280Sobrien 52590280Sobrien count_trailing_zeros (count, word); 52690280Sobrien return count + add + 1; 52718334Speter} 52818334Speter#endif 52918334Speter 53018334Speter#ifdef L_muldi3 53190280SobrienDWtype 53290280Sobrien__muldi3 (DWtype u, DWtype v) 53318334Speter{ 534132727Skan const DWunion uu = {.ll = u}; 535132727Skan const DWunion vv = {.ll = v}; 536132727Skan DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)}; 53718334Speter 53890280Sobrien w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high 53990280Sobrien + (UWtype) uu.s.high * (UWtype) vv.s.low); 54018334Speter 54118334Speter return w.ll; 54218334Speter} 54318334Speter#endif 54418334Speter 545117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 546117404Skan defined (L_umoddi3) || defined (L_moddi3)) 547117404Skan#if defined (sdiv_qrnnd) 548117404Skan#define L_udiv_w_sdiv 549117404Skan#endif 550117404Skan#endif 551117404Skan 55218334Speter#ifdef L_udiv_w_sdiv 55318334Speter#if defined (sdiv_qrnnd) 554117404Skan#if (defined (L_udivdi3) || defined (L_divdi3) || \ 555117404Skan defined (L_umoddi3) || defined (L_moddi3)) 556117404Skanstatic inline __attribute__ ((__always_inline__)) 557117404Skan#endif 55890280SobrienUWtype 55990280Sobrien__udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) 56018334Speter{ 56190280Sobrien UWtype q, r; 56290280Sobrien UWtype c0, c1, b1; 56318334Speter 56490280Sobrien if ((Wtype) d >= 0) 56518334Speter { 56690280Sobrien if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) 56718334Speter { 568169699Skan /* Dividend, divisor, and quotient are nonnegative. */ 56918334Speter sdiv_qrnnd (q, r, a1, a0, d); 57018334Speter } 57118334Speter else 57218334Speter { 573169699Skan /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */ 57490280Sobrien sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); 575169699Skan /* Divide (c1*2^32 + c0) by d. */ 57618334Speter sdiv_qrnnd (q, r, c1, c0, d); 577169699Skan /* Add 2^31 to quotient. */ 57890280Sobrien q += (UWtype) 1 << (W_TYPE_SIZE - 1); 57918334Speter } 58018334Speter } 58118334Speter else 58218334Speter { 58318334Speter b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ 58418334Speter c1 = a1 >> 1; /* A/2 */ 58590280Sobrien c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1); 58618334Speter 58718334Speter if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ 58818334Speter { 58918334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 59018334Speter 59118334Speter r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ 59218334Speter if ((d & 1) != 0) 59318334Speter { 59418334Speter if (r >= q) 59518334Speter r = r - q; 59618334Speter else if (q - r <= d) 59718334Speter { 59818334Speter r = r - q + d; 59918334Speter q--; 60018334Speter } 60118334Speter else 60218334Speter { 60318334Speter r = r - q + 2*d; 60418334Speter q -= 2; 60518334Speter } 60618334Speter } 60718334Speter } 60818334Speter else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ 60918334Speter { 61018334Speter c1 = (b1 - 1) - c1; 61118334Speter c0 = ~c0; /* logical NOT */ 61218334Speter 61318334Speter sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ 61418334Speter 61518334Speter q = ~q; /* (A/2)/b1 */ 61618334Speter r = (b1 - 1) - r; 61718334Speter 61818334Speter r = 2*r + (a0 & 1); /* A/(2*b1) */ 61918334Speter 62018334Speter if ((d & 1) != 0) 62118334Speter { 62218334Speter if (r >= q) 62318334Speter r = r - q; 62418334Speter else if (q - r <= d) 62518334Speter { 62618334Speter r = r - q + d; 62718334Speter q--; 62818334Speter } 62918334Speter else 63018334Speter { 63118334Speter r = r - q + 2*d; 63218334Speter q -= 2; 63318334Speter } 63418334Speter } 63518334Speter } 63618334Speter else /* Implies c1 = b1 */ 63718334Speter { /* Hence a1 = d - 1 = 2*b1 - 1 */ 63818334Speter if (a0 >= -d) 63918334Speter { 64018334Speter q = -1; 64118334Speter r = a0 + d; 64218334Speter } 64318334Speter else 64418334Speter { 64518334Speter q = -2; 64618334Speter r = a0 + 2*d; 64718334Speter } 64818334Speter } 64918334Speter } 65018334Speter 65118334Speter *rp = r; 65218334Speter return q; 65318334Speter} 65418334Speter#else 65518334Speter/* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */ 65690280SobrienUWtype 65790280Sobrien__udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), 65890280Sobrien UWtype a1 __attribute__ ((__unused__)), 65990280Sobrien UWtype a0 __attribute__ ((__unused__)), 66090280Sobrien UWtype d __attribute__ ((__unused__))) 66150600Sobrien{ 66250600Sobrien return 0; 66350600Sobrien} 66418334Speter#endif 66518334Speter#endif 66618334Speter 66718334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 66818334Speter defined (L_umoddi3) || defined (L_moddi3)) 66918334Speter#define L_udivmoddi4 67018334Speter#endif 67118334Speter 67290280Sobrien#ifdef L_clz 673169699Skanconst UQItype __clz_tab[256] = 67418334Speter{ 67518334Speter 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, 67618334Speter 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, 67718334Speter 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, 67818334Speter 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, 67918334Speter 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, 68018334Speter 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, 68118334Speter 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, 682169699Skan 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 68318334Speter}; 68490280Sobrien#endif 685132727Skan 686132727Skan#ifdef L_clzsi2 687132727Skan#undef int 688132727Skanint 689132727Skan__clzSI2 (UWtype x) 690132727Skan{ 691132727Skan Wtype ret; 69218334Speter 693132727Skan count_leading_zeros (ret, x); 694132727Skan 695132727Skan return ret; 696132727Skan} 697132727Skan#endif 698132727Skan 699132727Skan#ifdef L_clzdi2 700132727Skan#undef int 701132727Skanint 702132727Skan__clzDI2 (UDWtype x) 703132727Skan{ 704132727Skan const DWunion uu = {.ll = x}; 705132727Skan UWtype word; 706132727Skan Wtype ret, add; 707132727Skan 708132727Skan if (uu.s.high) 709132727Skan word = uu.s.high, add = 0; 710132727Skan else 711132727Skan word = uu.s.low, add = W_TYPE_SIZE; 712132727Skan 713132727Skan count_leading_zeros (ret, word); 714132727Skan return ret + add; 715132727Skan} 716132727Skan#endif 717132727Skan 718132727Skan#ifdef L_ctzsi2 719132727Skan#undef int 720132727Skanint 721132727Skan__ctzSI2 (UWtype x) 722132727Skan{ 723132727Skan Wtype ret; 724132727Skan 725132727Skan count_trailing_zeros (ret, x); 726132727Skan 727132727Skan return ret; 728132727Skan} 729132727Skan#endif 730132727Skan 731132727Skan#ifdef L_ctzdi2 732132727Skan#undef int 733132727Skanint 734132727Skan__ctzDI2 (UDWtype x) 735132727Skan{ 736132727Skan const DWunion uu = {.ll = x}; 737132727Skan UWtype word; 738132727Skan Wtype ret, add; 739132727Skan 740132727Skan if (uu.s.low) 741132727Skan word = uu.s.low, add = 0; 742132727Skan else 743132727Skan word = uu.s.high, add = W_TYPE_SIZE; 744132727Skan 745132727Skan count_trailing_zeros (ret, word); 746132727Skan return ret + add; 747132727Skan} 748132727Skan#endif 749132727Skan 750132727Skan#ifdef L_popcount_tab 751169699Skanconst UQItype __popcount_tab[256] = 752132727Skan{ 753132727Skan 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, 754132727Skan 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, 755132727Skan 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, 756132727Skan 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, 757132727Skan 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, 758132727Skan 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, 759132727Skan 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, 760169699Skan 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 761132727Skan}; 762132727Skan#endif 763132727Skan 764132727Skan#ifdef L_popcountsi2 765132727Skan#undef int 766132727Skanint 767132727Skan__popcountSI2 (UWtype x) 768132727Skan{ 769169699Skan int i, ret = 0; 770132727Skan 771132727Skan for (i = 0; i < W_TYPE_SIZE; i += 8) 772132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 773132727Skan 774132727Skan return ret; 775132727Skan} 776132727Skan#endif 777132727Skan 778132727Skan#ifdef L_popcountdi2 779132727Skan#undef int 780132727Skanint 781132727Skan__popcountDI2 (UDWtype x) 782132727Skan{ 783169699Skan int i, ret = 0; 784132727Skan 785132727Skan for (i = 0; i < 2*W_TYPE_SIZE; i += 8) 786132727Skan ret += __popcount_tab[(x >> i) & 0xff]; 787132727Skan 788132727Skan return ret; 789132727Skan} 790132727Skan#endif 791132727Skan 792132727Skan#ifdef L_paritysi2 793132727Skan#undef int 794132727Skanint 795132727Skan__paritySI2 (UWtype x) 796132727Skan{ 797132727Skan#if W_TYPE_SIZE > 64 798132727Skan# error "fill out the table" 799132727Skan#endif 800132727Skan#if W_TYPE_SIZE > 32 801132727Skan x ^= x >> 32; 802132727Skan#endif 803132727Skan#if W_TYPE_SIZE > 16 804132727Skan x ^= x >> 16; 805132727Skan#endif 806132727Skan x ^= x >> 8; 807132727Skan x ^= x >> 4; 808132727Skan x &= 0xf; 809132727Skan return (0x6996 >> x) & 1; 810132727Skan} 811132727Skan#endif 812132727Skan 813132727Skan#ifdef L_paritydi2 814132727Skan#undef int 815132727Skanint 816132727Skan__parityDI2 (UDWtype x) 817132727Skan{ 818132727Skan const DWunion uu = {.ll = x}; 819132727Skan UWtype nx = uu.s.low ^ uu.s.high; 820132727Skan 821132727Skan#if W_TYPE_SIZE > 64 822132727Skan# error "fill out the table" 823132727Skan#endif 824132727Skan#if W_TYPE_SIZE > 32 825132727Skan nx ^= nx >> 32; 826132727Skan#endif 827132727Skan#if W_TYPE_SIZE > 16 828132727Skan nx ^= nx >> 16; 829132727Skan#endif 830132727Skan nx ^= nx >> 8; 831132727Skan nx ^= nx >> 4; 832132727Skan nx &= 0xf; 833132727Skan return (0x6996 >> nx) & 1; 834132727Skan} 835132727Skan#endif 836132727Skan 83790280Sobrien#ifdef L_udivmoddi4 83890280Sobrien 83918334Speter#if (defined (L_udivdi3) || defined (L_divdi3) || \ 84018334Speter defined (L_umoddi3) || defined (L_moddi3)) 841117404Skanstatic inline __attribute__ ((__always_inline__)) 84218334Speter#endif 84390280SobrienUDWtype 84490280Sobrien__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) 84518334Speter{ 846132727Skan const DWunion nn = {.ll = n}; 847132727Skan const DWunion dd = {.ll = d}; 84890280Sobrien DWunion rr; 84990280Sobrien UWtype d0, d1, n0, n1, n2; 85090280Sobrien UWtype q0, q1; 85190280Sobrien UWtype b, bm; 85218334Speter 85318334Speter d0 = dd.s.low; 85418334Speter d1 = dd.s.high; 85518334Speter n0 = nn.s.low; 85618334Speter n1 = nn.s.high; 85718334Speter 85818334Speter#if !UDIV_NEEDS_NORMALIZATION 85918334Speter if (d1 == 0) 86018334Speter { 86118334Speter if (d0 > n1) 86218334Speter { 86318334Speter /* 0q = nn / 0D */ 86418334Speter 86518334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 86618334Speter q1 = 0; 86718334Speter 86818334Speter /* Remainder in n0. */ 86918334Speter } 87018334Speter else 87118334Speter { 87218334Speter /* qq = NN / 0d */ 87318334Speter 87418334Speter if (d0 == 0) 87518334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 87618334Speter 87718334Speter udiv_qrnnd (q1, n1, 0, n1, d0); 87818334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 87918334Speter 88018334Speter /* Remainder in n0. */ 88118334Speter } 88218334Speter 88318334Speter if (rp != 0) 88418334Speter { 88518334Speter rr.s.low = n0; 88618334Speter rr.s.high = 0; 88718334Speter *rp = rr.ll; 88818334Speter } 88918334Speter } 89018334Speter 89118334Speter#else /* UDIV_NEEDS_NORMALIZATION */ 89218334Speter 89318334Speter if (d1 == 0) 89418334Speter { 89518334Speter if (d0 > n1) 89618334Speter { 89718334Speter /* 0q = nn / 0D */ 89818334Speter 89918334Speter count_leading_zeros (bm, d0); 90018334Speter 90118334Speter if (bm != 0) 90218334Speter { 90318334Speter /* Normalize, i.e. make the most significant bit of the 90418334Speter denominator set. */ 90518334Speter 90618334Speter d0 = d0 << bm; 90790280Sobrien n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); 90818334Speter n0 = n0 << bm; 90918334Speter } 91018334Speter 91118334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 91218334Speter q1 = 0; 91318334Speter 91418334Speter /* Remainder in n0 >> bm. */ 91518334Speter } 91618334Speter else 91718334Speter { 91818334Speter /* qq = NN / 0d */ 91918334Speter 92018334Speter if (d0 == 0) 92118334Speter d0 = 1 / d0; /* Divide intentionally by zero. */ 92218334Speter 92318334Speter count_leading_zeros (bm, d0); 92418334Speter 92518334Speter if (bm == 0) 92618334Speter { 92718334Speter /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 92818334Speter conclude (the most significant bit of n1 is set) /\ (the 92918334Speter leading quotient digit q1 = 1). 93018334Speter 93118334Speter This special case is necessary, not an optimization. 93290280Sobrien (Shifts counts of W_TYPE_SIZE are undefined.) */ 93318334Speter 93418334Speter n1 -= d0; 93518334Speter q1 = 1; 93618334Speter } 93718334Speter else 93818334Speter { 93918334Speter /* Normalize. */ 94018334Speter 94190280Sobrien b = W_TYPE_SIZE - bm; 94218334Speter 94318334Speter d0 = d0 << bm; 94418334Speter n2 = n1 >> b; 94518334Speter n1 = (n1 << bm) | (n0 >> b); 94618334Speter n0 = n0 << bm; 94718334Speter 94818334Speter udiv_qrnnd (q1, n1, n2, n1, d0); 94918334Speter } 95018334Speter 95150600Sobrien /* n1 != d0... */ 95218334Speter 95318334Speter udiv_qrnnd (q0, n0, n1, n0, d0); 95418334Speter 95518334Speter /* Remainder in n0 >> bm. */ 95618334Speter } 95718334Speter 95818334Speter if (rp != 0) 95918334Speter { 96018334Speter rr.s.low = n0 >> bm; 96118334Speter rr.s.high = 0; 96218334Speter *rp = rr.ll; 96318334Speter } 96418334Speter } 96518334Speter#endif /* UDIV_NEEDS_NORMALIZATION */ 96618334Speter 96718334Speter else 96818334Speter { 96918334Speter if (d1 > n1) 97018334Speter { 97118334Speter /* 00 = nn / DD */ 97218334Speter 97318334Speter q0 = 0; 97418334Speter q1 = 0; 97518334Speter 97618334Speter /* Remainder in n1n0. */ 97718334Speter if (rp != 0) 97818334Speter { 97918334Speter rr.s.low = n0; 98018334Speter rr.s.high = n1; 98118334Speter *rp = rr.ll; 98218334Speter } 98318334Speter } 98418334Speter else 98518334Speter { 98618334Speter /* 0q = NN / dd */ 98718334Speter 98818334Speter count_leading_zeros (bm, d1); 98918334Speter if (bm == 0) 99018334Speter { 99118334Speter /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 99218334Speter conclude (the most significant bit of n1 is set) /\ (the 99318334Speter quotient digit q0 = 0 or 1). 99418334Speter 99518334Speter This special case is necessary, not an optimization. */ 99618334Speter 99718334Speter /* The condition on the next line takes advantage of that 99818334Speter n1 >= d1 (true due to program flow). */ 99918334Speter if (n1 > d1 || n0 >= d0) 100018334Speter { 100118334Speter q0 = 1; 100218334Speter sub_ddmmss (n1, n0, n1, n0, d1, d0); 100318334Speter } 100418334Speter else 100518334Speter q0 = 0; 100618334Speter 100718334Speter q1 = 0; 100818334Speter 100918334Speter if (rp != 0) 101018334Speter { 101118334Speter rr.s.low = n0; 101218334Speter rr.s.high = n1; 101318334Speter *rp = rr.ll; 101418334Speter } 101518334Speter } 101618334Speter else 101718334Speter { 101890280Sobrien UWtype m1, m0; 101918334Speter /* Normalize. */ 102018334Speter 102190280Sobrien b = W_TYPE_SIZE - bm; 102218334Speter 102318334Speter d1 = (d1 << bm) | (d0 >> b); 102418334Speter d0 = d0 << bm; 102518334Speter n2 = n1 >> b; 102618334Speter n1 = (n1 << bm) | (n0 >> b); 102718334Speter n0 = n0 << bm; 102818334Speter 102918334Speter udiv_qrnnd (q0, n1, n2, n1, d1); 103018334Speter umul_ppmm (m1, m0, q0, d0); 103118334Speter 103218334Speter if (m1 > n1 || (m1 == n1 && m0 > n0)) 103318334Speter { 103418334Speter q0--; 103518334Speter sub_ddmmss (m1, m0, m1, m0, d1, d0); 103618334Speter } 103718334Speter 103818334Speter q1 = 0; 103918334Speter 104018334Speter /* Remainder in (n1n0 - m1m0) >> bm. */ 104118334Speter if (rp != 0) 104218334Speter { 104318334Speter sub_ddmmss (n1, n0, n1, n0, m1, m0); 104418334Speter rr.s.low = (n1 << b) | (n0 >> bm); 104518334Speter rr.s.high = n1 >> bm; 104618334Speter *rp = rr.ll; 104718334Speter } 104818334Speter } 104918334Speter } 105018334Speter } 105118334Speter 1052132727Skan const DWunion ww = {{.low = q0, .high = q1}}; 105318334Speter return ww.ll; 105418334Speter} 105518334Speter#endif 105618334Speter 105718334Speter#ifdef L_divdi3 105890280SobrienDWtype 105990280Sobrien__divdi3 (DWtype u, DWtype v) 106018334Speter{ 106118334Speter word_type c = 0; 1062132727Skan DWunion uu = {.ll = u}; 1063132727Skan DWunion vv = {.ll = v}; 106490280Sobrien DWtype w; 106518334Speter 106618334Speter if (uu.s.high < 0) 106718334Speter c = ~c, 1068117404Skan uu.ll = -uu.ll; 106918334Speter if (vv.s.high < 0) 107018334Speter c = ~c, 1071117404Skan vv.ll = -vv.ll; 107218334Speter 107390280Sobrien w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); 107418334Speter if (c) 1075117404Skan w = -w; 107618334Speter 107718334Speter return w; 107818334Speter} 107918334Speter#endif 108018334Speter 108118334Speter#ifdef L_moddi3 108290280SobrienDWtype 108390280Sobrien__moddi3 (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) 1094117404Skan vv.ll = -vv.ll; 109518334Speter 1096169699Skan (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); 109718334Speter if (c) 1098117404Skan w = -w; 109918334Speter 110018334Speter return w; 110118334Speter} 110218334Speter#endif 110318334Speter 110418334Speter#ifdef L_umoddi3 110590280SobrienUDWtype 110690280Sobrien__umoddi3 (UDWtype u, UDWtype v) 110718334Speter{ 110890280Sobrien UDWtype w; 110918334Speter 111018334Speter (void) __udivmoddi4 (u, v, &w); 111118334Speter 111218334Speter return w; 111318334Speter} 111418334Speter#endif 111518334Speter 111618334Speter#ifdef L_udivdi3 111790280SobrienUDWtype 111890280Sobrien__udivdi3 (UDWtype n, UDWtype d) 111918334Speter{ 112090280Sobrien return __udivmoddi4 (n, d, (UDWtype *) 0); 112118334Speter} 112218334Speter#endif 112318334Speter 112418334Speter#ifdef L_cmpdi2 112518334Speterword_type 112690280Sobrien__cmpdi2 (DWtype a, DWtype b) 112718334Speter{ 1128132727Skan const DWunion au = {.ll = a}; 1129132727Skan const DWunion bu = {.ll = b}; 113018334Speter 113118334Speter if (au.s.high < bu.s.high) 113218334Speter return 0; 113318334Speter else if (au.s.high > bu.s.high) 113418334Speter return 2; 113590280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 113618334Speter return 0; 113790280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 113818334Speter return 2; 113918334Speter return 1; 114018334Speter} 114118334Speter#endif 114218334Speter 114318334Speter#ifdef L_ucmpdi2 114418334Speterword_type 114590280Sobrien__ucmpdi2 (DWtype a, DWtype b) 114618334Speter{ 1147132727Skan const DWunion au = {.ll = a}; 1148132727Skan const DWunion bu = {.ll = b}; 114918334Speter 115090280Sobrien if ((UWtype) au.s.high < (UWtype) bu.s.high) 115118334Speter return 0; 115290280Sobrien else if ((UWtype) au.s.high > (UWtype) bu.s.high) 115318334Speter return 2; 115490280Sobrien if ((UWtype) au.s.low < (UWtype) bu.s.low) 115518334Speter return 0; 115690280Sobrien else if ((UWtype) au.s.low > (UWtype) bu.s.low) 115718334Speter return 2; 115818334Speter return 1; 115918334Speter} 116018334Speter#endif 116118334Speter 1162169699Skan#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE 116390280SobrienDWtype 116490280Sobrien__fixunstfDI (TFtype a) 116518334Speter{ 116618334Speter if (a < 0) 116718334Speter return 0; 116818334Speter 116918334Speter /* Compute high word of result, as a flonum. */ 1170169699Skan const TFtype b = (a / Wtype_MAXp1_F); 117190280Sobrien /* Convert that to fixed (but not to DWtype!), 117218334Speter and shift it into the high word. */ 1173132727Skan UDWtype v = (UWtype) b; 1174169699Skan v <<= W_TYPE_SIZE; 117518334Speter /* Remove high part from the TFtype, leaving the low part as flonum. */ 117618334Speter a -= (TFtype)v; 117790280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 117818334Speter Sometimes A comes out negative. This is significant, since 117918334Speter A has more bits than a long int does. */ 118018334Speter if (a < 0) 118190280Sobrien v -= (UWtype) (- a); 118218334Speter else 118390280Sobrien v += (UWtype) a; 118418334Speter return v; 118518334Speter} 118618334Speter#endif 118718334Speter 1188169699Skan#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE 118990280SobrienDWtype 119050600Sobrien__fixtfdi (TFtype a) 119118334Speter{ 119218334Speter if (a < 0) 119390280Sobrien return - __fixunstfDI (-a); 119490280Sobrien return __fixunstfDI (a); 119518334Speter} 119618334Speter#endif 119718334Speter 1198169699Skan#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE 119990280SobrienDWtype 120090280Sobrien__fixunsxfDI (XFtype a) 120118334Speter{ 120218334Speter if (a < 0) 120318334Speter return 0; 120418334Speter 120518334Speter /* Compute high word of result, as a flonum. */ 1206169699Skan const XFtype b = (a / Wtype_MAXp1_F); 120790280Sobrien /* Convert that to fixed (but not to DWtype!), 120818334Speter and shift it into the high word. */ 1209132727Skan UDWtype v = (UWtype) b; 1210169699Skan v <<= W_TYPE_SIZE; 121118334Speter /* Remove high part from the XFtype, leaving the low part as flonum. */ 121218334Speter a -= (XFtype)v; 121390280Sobrien /* Convert that to fixed (but not to DWtype!) and add it in. 121418334Speter Sometimes A comes out negative. This is significant, since 121518334Speter A has more bits than a long int does. */ 121618334Speter if (a < 0) 121790280Sobrien v -= (UWtype) (- a); 121818334Speter else 121990280Sobrien v += (UWtype) a; 122018334Speter return v; 122118334Speter} 122218334Speter#endif 122318334Speter 1224169699Skan#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE 122590280SobrienDWtype 122650600Sobrien__fixxfdi (XFtype a) 122718334Speter{ 122818334Speter if (a < 0) 122990280Sobrien return - __fixunsxfDI (-a); 123090280Sobrien return __fixunsxfDI (a); 123118334Speter} 123218334Speter#endif 123318334Speter 1234169699Skan#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE 123590280SobrienDWtype 123690280Sobrien__fixunsdfDI (DFtype a) 123718334Speter{ 1238132727Skan /* Get high part of result. The division here will just moves the radix 1239132727Skan point and will not cause any rounding. Then the conversion to integral 1240132727Skan type chops result as desired. */ 1241169699Skan const UWtype hi = a / Wtype_MAXp1_F; 124218334Speter 1243132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1244132727Skan then subtract this from the number being converted. This leaves the low 1245132727Skan part. Convert that to integral type. */ 1246169699Skan const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F; 124718334Speter 1248132727Skan /* Assemble result from the two parts. */ 1249169699Skan return ((UDWtype) hi << W_TYPE_SIZE) | lo; 125018334Speter} 125118334Speter#endif 125218334Speter 1253169699Skan#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE 125490280SobrienDWtype 125550600Sobrien__fixdfdi (DFtype a) 125618334Speter{ 125718334Speter if (a < 0) 125890280Sobrien return - __fixunsdfDI (-a); 125990280Sobrien return __fixunsdfDI (a); 126018334Speter} 126118334Speter#endif 126218334Speter 1263169699Skan#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE 126490280SobrienDWtype 1265169699Skan__fixunssfDI (SFtype a) 126618334Speter{ 1267169699Skan#if LIBGCC2_HAS_DF_MODE 126818334Speter /* Convert the SFtype to a DFtype, because that is surely not going 126918334Speter to lose any bits. Some day someone else can write a faster version 127018334Speter that avoids converting to DFtype, and verify it really works right. */ 1271169699Skan const DFtype dfa = a; 127218334Speter 1273132727Skan /* Get high part of result. The division here will just moves the radix 1274132727Skan point and will not cause any rounding. Then the conversion to integral 1275132727Skan type chops result as desired. */ 1276169699Skan const UWtype hi = dfa / Wtype_MAXp1_F; 127718334Speter 1278132727Skan /* Get low part of result. Convert `hi' to floating type and scale it back, 1279132727Skan then subtract this from the number being converted. This leaves the low 1280132727Skan part. Convert that to integral type. */ 1281169699Skan const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F; 1282132727Skan 1283132727Skan /* Assemble result from the two parts. */ 1284169699Skan return ((UDWtype) hi << W_TYPE_SIZE) | lo; 1285169699Skan#elif FLT_MANT_DIG < W_TYPE_SIZE 1286169699Skan if (a < 1) 1287169699Skan return 0; 1288169699Skan if (a < Wtype_MAXp1_F) 1289169699Skan return (UWtype)a; 1290169699Skan if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) 1291169699Skan { 1292169699Skan /* Since we know that there are fewer significant bits in the SFmode 1293169699Skan quantity than in a word, we know that we can convert out all the 1294169699Skan significant bits in one step, and thus avoid losing bits. */ 1295169699Skan 1296169699Skan /* ??? This following loop essentially performs frexpf. If we could 1297169699Skan use the real libm function, or poke at the actual bits of the fp 1298169699Skan format, it would be significantly faster. */ 1299169699Skan 1300169699Skan UWtype shift = 0, counter; 1301169699Skan SFtype msb; 1302169699Skan 1303169699Skan a /= Wtype_MAXp1_F; 1304169699Skan for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) 1305169699Skan { 1306169699Skan SFtype counterf = (UWtype)1 << counter; 1307169699Skan if (a >= counterf) 1308169699Skan { 1309169699Skan shift |= counter; 1310169699Skan a /= counterf; 1311169699Skan } 1312169699Skan } 1313169699Skan 1314169699Skan /* Rescale into the range of one word, extract the bits of that 1315169699Skan one word, and shift the result into position. */ 1316169699Skan a *= Wtype_MAXp1_F; 1317169699Skan counter = a; 1318169699Skan return (DWtype)counter << shift; 1319169699Skan } 1320169699Skan return -1; 1321169699Skan#else 1322169699Skan# error 1323169699Skan#endif 132418334Speter} 132518334Speter#endif 132618334Speter 1327169699Skan#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE 132890280SobrienDWtype 132918334Speter__fixsfdi (SFtype a) 133018334Speter{ 133118334Speter if (a < 0) 133290280Sobrien return - __fixunssfDI (-a); 133390280Sobrien return __fixunssfDI (a); 133418334Speter} 133518334Speter#endif 133618334Speter 1337169699Skan#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE 133818334SpeterXFtype 133990280Sobrien__floatdixf (DWtype u) 134018334Speter{ 1341169699Skan#if W_TYPE_SIZE > XF_SIZE 1342169699Skan# error 1343169699Skan#endif 1344169699Skan XFtype d = (Wtype) (u >> W_TYPE_SIZE); 1345169699Skan d *= Wtype_MAXp1_F; 1346169699Skan d += (UWtype)u; 1347169699Skan return d; 1348169699Skan} 1349169699Skan#endif 135018334Speter 1351169699Skan#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE 1352169699SkanXFtype 1353169699Skan__floatundixf (UDWtype u) 1354169699Skan{ 1355169699Skan#if W_TYPE_SIZE > XF_SIZE 1356169699Skan# error 1357169699Skan#endif 1358169699Skan XFtype d = (UWtype) (u >> W_TYPE_SIZE); 1359169699Skan d *= Wtype_MAXp1_F; 1360169699Skan d += (UWtype)u; 136150600Sobrien return d; 136218334Speter} 136318334Speter#endif 136418334Speter 1365169699Skan#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE 136618334SpeterTFtype 136790280Sobrien__floatditf (DWtype u) 136818334Speter{ 1369169699Skan#if W_TYPE_SIZE > TF_SIZE 1370169699Skan# error 1371169699Skan#endif 1372169699Skan TFtype d = (Wtype) (u >> W_TYPE_SIZE); 1373169699Skan d *= Wtype_MAXp1_F; 1374169699Skan d += (UWtype)u; 1375169699Skan return d; 1376169699Skan} 1377169699Skan#endif 137818334Speter 1379169699Skan#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE 1380169699SkanTFtype 1381169699Skan__floatunditf (UDWtype u) 1382169699Skan{ 1383169699Skan#if W_TYPE_SIZE > TF_SIZE 1384169699Skan# error 1385169699Skan#endif 1386169699Skan TFtype d = (UWtype) (u >> W_TYPE_SIZE); 1387169699Skan d *= Wtype_MAXp1_F; 1388169699Skan d += (UWtype)u; 138950600Sobrien return d; 139018334Speter} 139118334Speter#endif 139218334Speter 1393169699Skan#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \ 1394169699Skan || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE) 1395169699Skan#define DI_SIZE (W_TYPE_SIZE * 2) 1396169699Skan#define F_MODE_OK(SIZE) \ 1397169699Skan (SIZE < DI_SIZE \ 1398169699Skan && SIZE > (DI_SIZE - SIZE + FSSIZE) \ 1399169699Skan /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ 1400169699Skan The conversion from long double to float suffers from double \ 1401169699Skan rounding, because we convert via double. In any case, the \ 1402169699Skan fallback code is faster. */ \ 1403169699Skan && !IS_IBM_EXTENDED (SIZE)) 1404169699Skan#if defined(L_floatdisf) 1405169699Skan#define FUNC __floatdisf 1406169699Skan#define FSTYPE SFtype 1407169699Skan#define FSSIZE SF_SIZE 1408169699Skan#else 1409169699Skan#define FUNC __floatdidf 1410169699Skan#define FSTYPE DFtype 1411169699Skan#define FSSIZE DF_SIZE 1412169699Skan#endif 141318334Speter 1414169699SkanFSTYPE 1415169699SkanFUNC (DWtype u) 141618334Speter{ 1417169699Skan#if FSSIZE >= W_TYPE_SIZE 1418169699Skan /* When the word size is small, we never get any rounding error. */ 1419169699Skan FSTYPE f = (Wtype) (u >> W_TYPE_SIZE); 1420169699Skan f *= Wtype_MAXp1_F; 1421169699Skan f += (UWtype)u; 1422169699Skan return f; 1423169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ 1424169699Skan || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ 1425169699Skan || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 142618334Speter 1427169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) 1428169699Skan# define FSIZE DF_SIZE 1429169699Skan# define FTYPE DFtype 1430169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) 1431169699Skan# define FSIZE XF_SIZE 1432169699Skan# define FTYPE XFtype 1433169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 1434169699Skan# define FSIZE TF_SIZE 1435169699Skan# define FTYPE TFtype 1436169699Skan#else 1437169699Skan# error 1438169699Skan#endif 1439169699Skan 1440169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) 1441169699Skan 1442169699Skan /* Protect against double-rounding error. 1443169699Skan Represent any low-order bits, that might be truncated by a bit that 1444169699Skan won't be lost. The bit can go in anywhere below the rounding position 1445169699Skan of the FSTYPE. A fixed mask and bit position handles all usual 1446169699Skan configurations. */ 1447169699Skan if (! (- ((DWtype) 1 << FSIZE) < u 1448169699Skan && u < ((DWtype) 1 << FSIZE))) 1449169699Skan { 1450169699Skan if ((UDWtype) u & (REP_BIT - 1)) 1451169699Skan { 1452169699Skan u &= ~ (REP_BIT - 1); 1453169699Skan u |= REP_BIT; 1454169699Skan } 1455169699Skan } 1456169699Skan 1457169699Skan /* Do the calculation in a wider type so that we don't lose any of 1458169699Skan the precision of the high word while multiplying it. */ 1459169699Skan FTYPE f = (Wtype) (u >> W_TYPE_SIZE); 1460169699Skan f *= Wtype_MAXp1_F; 1461169699Skan f += (UWtype)u; 1462169699Skan return (FSTYPE) f; 1463169699Skan#else 1464169699Skan#if FSSIZE >= W_TYPE_SIZE - 2 1465169699Skan# error 1466169699Skan#endif 1467169699Skan /* Finally, the word size is larger than the number of bits in the 1468169699Skan required FSTYPE, and we've got no suitable wider type. The only 1469169699Skan way to avoid double rounding is to special case the 1470169699Skan extraction. */ 1471169699Skan 1472169699Skan /* If there are no high bits set, fall back to one conversion. */ 1473169699Skan if ((Wtype)u == u) 1474169699Skan return (FSTYPE)(Wtype)u; 1475169699Skan 1476169699Skan /* Otherwise, find the power of two. */ 1477169699Skan Wtype hi = u >> W_TYPE_SIZE; 1478169699Skan if (hi < 0) 1479169699Skan hi = -hi; 1480169699Skan 1481169699Skan UWtype count, shift; 1482169699Skan count_leading_zeros (count, hi); 1483169699Skan 1484169699Skan /* No leading bits means u == minimum. */ 1485169699Skan if (count == 0) 1486169699Skan return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2)); 1487169699Skan 1488169699Skan shift = 1 + W_TYPE_SIZE - count; 1489169699Skan 1490169699Skan /* Shift down the most significant bits. */ 1491169699Skan hi = u >> shift; 1492169699Skan 1493169699Skan /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ 1494169699Skan if (u & (((DWtype)1 << shift) - 1)) 1495169699Skan hi |= 1; 1496169699Skan 1497169699Skan /* Convert the one word of data, and rescale. */ 1498169699Skan FSTYPE f = hi; 1499169699Skan f *= (UDWtype)1 << shift; 1500169699Skan return f; 1501169699Skan#endif 150218334Speter} 150318334Speter#endif 150418334Speter 1505169699Skan#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \ 1506169699Skan || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE) 1507169699Skan#define DI_SIZE (W_TYPE_SIZE * 2) 1508169699Skan#define F_MODE_OK(SIZE) \ 1509169699Skan (SIZE < DI_SIZE \ 1510169699Skan && SIZE > (DI_SIZE - SIZE + FSSIZE) \ 1511169699Skan /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ 1512169699Skan The conversion from long double to float suffers from double \ 1513169699Skan rounding, because we convert via double. In any case, the \ 1514169699Skan fallback code is faster. */ \ 1515169699Skan && !IS_IBM_EXTENDED (SIZE)) 1516169699Skan#if defined(L_floatundisf) 1517169699Skan#define FUNC __floatundisf 1518169699Skan#define FSTYPE SFtype 1519169699Skan#define FSSIZE SF_SIZE 1520169699Skan#else 1521169699Skan#define FUNC __floatundidf 1522169699Skan#define FSTYPE DFtype 1523169699Skan#define FSSIZE DF_SIZE 1524169699Skan#endif 1525117404Skan 1526169699SkanFSTYPE 1527169699SkanFUNC (UDWtype u) 1528169699Skan{ 1529169699Skan#if FSSIZE >= W_TYPE_SIZE 1530169699Skan /* When the word size is small, we never get any rounding error. */ 1531169699Skan FSTYPE f = (UWtype) (u >> W_TYPE_SIZE); 1532169699Skan f *= Wtype_MAXp1_F; 1533169699Skan f += (UWtype)u; 1534169699Skan return f; 1535169699Skan#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ 1536169699Skan || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ 1537169699Skan || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 153818334Speter 1539169699Skan#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) 1540169699Skan# define FSIZE DF_SIZE 1541169699Skan# define FTYPE DFtype 1542169699Skan#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) 1543169699Skan# define FSIZE XF_SIZE 1544169699Skan# define FTYPE XFtype 1545169699Skan#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) 1546169699Skan# define FSIZE TF_SIZE 1547169699Skan# define FTYPE TFtype 1548169699Skan#else 1549169699Skan# error 1550169699Skan#endif 1551169699Skan 1552169699Skan#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) 1553169699Skan 155418334Speter /* Protect against double-rounding error. 1555169699Skan Represent any low-order bits, that might be truncated by a bit that 1556169699Skan won't be lost. The bit can go in anywhere below the rounding position 1557169699Skan of the FSTYPE. A fixed mask and bit position handles all usual 1558169699Skan configurations. */ 1559169699Skan if (u >= ((UDWtype) 1 << FSIZE)) 156018334Speter { 1561169699Skan if ((UDWtype) u & (REP_BIT - 1)) 156218334Speter { 1563169699Skan u &= ~ (REP_BIT - 1); 1564169699Skan u |= REP_BIT; 156518334Speter } 156618334Speter } 156718334Speter 1568169699Skan /* Do the calculation in a wider type so that we don't lose any of 1569169699Skan the precision of the high word while multiplying it. */ 1570169699Skan FTYPE f = (UWtype) (u >> W_TYPE_SIZE); 1571169699Skan f *= Wtype_MAXp1_F; 1572169699Skan f += (UWtype)u; 1573169699Skan return (FSTYPE) f; 1574169699Skan#else 1575169699Skan#if FSSIZE == W_TYPE_SIZE - 1 1576169699Skan# error 1577169699Skan#endif 1578169699Skan /* Finally, the word size is larger than the number of bits in the 1579169699Skan required FSTYPE, and we've got no suitable wider type. The only 1580169699Skan way to avoid double rounding is to special case the 1581169699Skan extraction. */ 1582169699Skan 1583169699Skan /* If there are no high bits set, fall back to one conversion. */ 1584169699Skan if ((UWtype)u == u) 1585169699Skan return (FSTYPE)(UWtype)u; 1586169699Skan 1587169699Skan /* Otherwise, find the power of two. */ 1588169699Skan UWtype hi = u >> W_TYPE_SIZE; 1589169699Skan 1590169699Skan UWtype count, shift; 1591169699Skan count_leading_zeros (count, hi); 1592169699Skan 1593169699Skan shift = W_TYPE_SIZE - count; 1594169699Skan 1595169699Skan /* Shift down the most significant bits. */ 1596169699Skan hi = u >> shift; 1597169699Skan 1598169699Skan /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ 1599169699Skan if (u & (((UDWtype)1 << shift) - 1)) 1600169699Skan hi |= 1; 1601169699Skan 1602169699Skan /* Convert the one word of data, and rescale. */ 1603169699Skan FSTYPE f = hi; 1604169699Skan f *= (UDWtype)1 << shift; 1605169699Skan return f; 1606169699Skan#endif 160718334Speter} 160818334Speter#endif 160918334Speter 1610169699Skan#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE 161118334Speter/* Reenable the normal types, in case limits.h needs them. */ 161218334Speter#undef char 161318334Speter#undef short 161418334Speter#undef int 161518334Speter#undef long 161618334Speter#undef unsigned 161718334Speter#undef float 161818334Speter#undef double 161918334Speter#undef MIN 162018334Speter#undef MAX 162118334Speter#include <limits.h> 162218334Speter 162390280SobrienUWtype 162490280Sobrien__fixunsxfSI (XFtype a) 162518334Speter{ 162690280Sobrien if (a >= - (DFtype) Wtype_MIN) 162790280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 162890280Sobrien return (Wtype) a; 162918334Speter} 163018334Speter#endif 163118334Speter 1632169699Skan#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE 163318334Speter/* Reenable the normal types, in case limits.h needs them. */ 163418334Speter#undef char 163518334Speter#undef short 163618334Speter#undef int 163718334Speter#undef long 163818334Speter#undef unsigned 163918334Speter#undef float 164018334Speter#undef double 164118334Speter#undef MIN 164218334Speter#undef MAX 164318334Speter#include <limits.h> 164418334Speter 164590280SobrienUWtype 164690280Sobrien__fixunsdfSI (DFtype a) 164718334Speter{ 164890280Sobrien if (a >= - (DFtype) Wtype_MIN) 164990280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 165090280Sobrien return (Wtype) a; 165118334Speter} 165218334Speter#endif 165318334Speter 1654169699Skan#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE 165518334Speter/* Reenable the normal types, in case limits.h needs them. */ 165618334Speter#undef char 165718334Speter#undef short 165818334Speter#undef int 165918334Speter#undef long 166018334Speter#undef unsigned 166118334Speter#undef float 166218334Speter#undef double 166318334Speter#undef MIN 166418334Speter#undef MAX 166518334Speter#include <limits.h> 166618334Speter 166790280SobrienUWtype 166890280Sobrien__fixunssfSI (SFtype a) 166918334Speter{ 167090280Sobrien if (a >= - (SFtype) Wtype_MIN) 167190280Sobrien return (Wtype) (a + Wtype_MIN) - Wtype_MIN; 167290280Sobrien return (Wtype) a; 167318334Speter} 167418334Speter#endif 167518334Speter 1676169699Skan/* Integer power helper used from __builtin_powi for non-constant 1677169699Skan exponents. */ 1678169699Skan 1679169699Skan#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \ 1680169699Skan || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \ 1681169699Skan || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \ 1682169699Skan || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE) 1683169699Skan# if defined(L_powisf2) 1684169699Skan# define TYPE SFtype 1685169699Skan# define NAME __powisf2 1686169699Skan# elif defined(L_powidf2) 1687169699Skan# define TYPE DFtype 1688169699Skan# define NAME __powidf2 1689169699Skan# elif defined(L_powixf2) 1690169699Skan# define TYPE XFtype 1691169699Skan# define NAME __powixf2 1692169699Skan# elif defined(L_powitf2) 1693169699Skan# define TYPE TFtype 1694169699Skan# define NAME __powitf2 1695169699Skan# endif 1696169699Skan 1697169699Skan#undef int 1698169699Skan#undef unsigned 1699169699SkanTYPE 1700169699SkanNAME (TYPE x, int m) 1701169699Skan{ 1702169699Skan unsigned int n = m < 0 ? -m : m; 1703169699Skan TYPE y = n % 2 ? x : 1; 1704169699Skan while (n >>= 1) 1705169699Skan { 1706169699Skan x = x * x; 1707169699Skan if (n % 2) 1708169699Skan y = y * x; 1709169699Skan } 1710169699Skan return m < 0 ? 1/y : y; 1711169699Skan} 1712169699Skan 1713169699Skan#endif 1714169699Skan 1715169699Skan#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ 1716169699Skan || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \ 1717169699Skan || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \ 1718169699Skan || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE) 1719169699Skan 1720169699Skan#undef float 1721169699Skan#undef double 1722169699Skan#undef long 1723169699Skan 1724169699Skan#if defined(L_mulsc3) || defined(L_divsc3) 1725169699Skan# define MTYPE SFtype 1726169699Skan# define CTYPE SCtype 1727169699Skan# define MODE sc 1728169699Skan# define CEXT f 1729169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0 1730169699Skan#elif defined(L_muldc3) || defined(L_divdc3) 1731169699Skan# define MTYPE DFtype 1732169699Skan# define CTYPE DCtype 1733169699Skan# define MODE dc 1734169699Skan# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64 1735169699Skan# define CEXT l 1736169699Skan# define NOTRUNC 1 1737169699Skan# else 1738169699Skan# define CEXT 1739169699Skan# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1 1740169699Skan# endif 1741169699Skan#elif defined(L_mulxc3) || defined(L_divxc3) 1742169699Skan# define MTYPE XFtype 1743169699Skan# define CTYPE XCtype 1744169699Skan# define MODE xc 1745169699Skan# define CEXT l 1746169699Skan# define NOTRUNC 1 1747169699Skan#elif defined(L_multc3) || defined(L_divtc3) 1748169699Skan# define MTYPE TFtype 1749169699Skan# define CTYPE TCtype 1750169699Skan# define MODE tc 1751169699Skan# define CEXT l 1752169699Skan# define NOTRUNC 1 1753169699Skan#else 1754169699Skan# error 1755169699Skan#endif 1756169699Skan 1757169699Skan#define CONCAT3(A,B,C) _CONCAT3(A,B,C) 1758169699Skan#define _CONCAT3(A,B,C) A##B##C 1759169699Skan 1760169699Skan#define CONCAT2(A,B) _CONCAT2(A,B) 1761169699Skan#define _CONCAT2(A,B) A##B 1762169699Skan 1763169699Skan/* All of these would be present in a full C99 implementation of <math.h> 1764169699Skan and <complex.h>. Our problem is that only a few systems have such full 1765169699Skan implementations. Further, libgcc_s.so isn't currently linked against 1766169699Skan libm.so, and even for systems that do provide full C99, the extra overhead 1767169699Skan of all programs using libgcc having to link against libm. So avoid it. */ 1768169699Skan 1769169699Skan#define isnan(x) __builtin_expect ((x) != (x), 0) 1770169699Skan#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1) 1771169699Skan#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0) 1772169699Skan 1773169699Skan#define INFINITY CONCAT2(__builtin_inf, CEXT) () 1774169699Skan#define I 1i 1775169699Skan 1776169699Skan/* Helpers to make the following code slightly less gross. */ 1777169699Skan#define COPYSIGN CONCAT2(__builtin_copysign, CEXT) 1778169699Skan#define FABS CONCAT2(__builtin_fabs, CEXT) 1779169699Skan 1780169699Skan/* Verify that MTYPE matches up with CEXT. */ 1781169699Skanextern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1]; 1782169699Skan 1783169699Skan/* Ensure that we've lost any extra precision. */ 1784169699Skan#if NOTRUNC 1785169699Skan# define TRUNC(x) 1786169699Skan#else 1787169699Skan# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x)) 1788169699Skan#endif 1789169699Skan 1790169699Skan#if defined(L_mulsc3) || defined(L_muldc3) \ 1791169699Skan || defined(L_mulxc3) || defined(L_multc3) 1792169699Skan 1793169699SkanCTYPE 1794169699SkanCONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) 1795169699Skan{ 1796169699Skan MTYPE ac, bd, ad, bc, x, y; 1797169699Skan 1798169699Skan ac = a * c; 1799169699Skan bd = b * d; 1800169699Skan ad = a * d; 1801169699Skan bc = b * c; 1802169699Skan 1803169699Skan TRUNC (ac); 1804169699Skan TRUNC (bd); 1805169699Skan TRUNC (ad); 1806169699Skan TRUNC (bc); 1807169699Skan 1808169699Skan x = ac - bd; 1809169699Skan y = ad + bc; 1810169699Skan 1811169699Skan if (isnan (x) && isnan (y)) 1812169699Skan { 1813169699Skan /* Recover infinities that computed as NaN + iNaN. */ 1814169699Skan _Bool recalc = 0; 1815169699Skan if (isinf (a) || isinf (b)) 1816169699Skan { 1817169699Skan /* z is infinite. "Box" the infinity and change NaNs in 1818169699Skan the other factor to 0. */ 1819169699Skan a = COPYSIGN (isinf (a) ? 1 : 0, a); 1820169699Skan b = COPYSIGN (isinf (b) ? 1 : 0, b); 1821169699Skan if (isnan (c)) c = COPYSIGN (0, c); 1822169699Skan if (isnan (d)) d = COPYSIGN (0, d); 1823169699Skan recalc = 1; 1824169699Skan } 1825169699Skan if (isinf (c) || isinf (d)) 1826169699Skan { 1827169699Skan /* w is infinite. "Box" the infinity and change NaNs in 1828169699Skan the other factor to 0. */ 1829169699Skan c = COPYSIGN (isinf (c) ? 1 : 0, c); 1830169699Skan d = COPYSIGN (isinf (d) ? 1 : 0, d); 1831169699Skan if (isnan (a)) a = COPYSIGN (0, a); 1832169699Skan if (isnan (b)) b = COPYSIGN (0, b); 1833169699Skan recalc = 1; 1834169699Skan } 1835169699Skan if (!recalc 1836169699Skan && (isinf (ac) || isinf (bd) 1837169699Skan || isinf (ad) || isinf (bc))) 1838169699Skan { 1839169699Skan /* Recover infinities from overflow by changing NaNs to 0. */ 1840169699Skan if (isnan (a)) a = COPYSIGN (0, a); 1841169699Skan if (isnan (b)) b = COPYSIGN (0, b); 1842169699Skan if (isnan (c)) c = COPYSIGN (0, c); 1843169699Skan if (isnan (d)) d = COPYSIGN (0, d); 1844169699Skan recalc = 1; 1845169699Skan } 1846169699Skan if (recalc) 1847169699Skan { 1848169699Skan x = INFINITY * (a * c - b * d); 1849169699Skan y = INFINITY * (a * d + b * c); 1850169699Skan } 1851169699Skan } 1852169699Skan 1853169699Skan return x + I * y; 1854169699Skan} 1855169699Skan#endif /* complex multiply */ 1856169699Skan 1857169699Skan#if defined(L_divsc3) || defined(L_divdc3) \ 1858169699Skan || defined(L_divxc3) || defined(L_divtc3) 1859169699Skan 1860169699SkanCTYPE 1861169699SkanCONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) 1862169699Skan{ 1863169699Skan MTYPE denom, ratio, x, y; 1864169699Skan 1865169699Skan /* ??? We can get better behavior from logarithmic scaling instead of 1866169699Skan the division. But that would mean starting to link libgcc against 1867169699Skan libm. We could implement something akin to ldexp/frexp as gcc builtins 1868169699Skan fairly easily... */ 1869169699Skan if (FABS (c) < FABS (d)) 1870169699Skan { 1871169699Skan ratio = c / d; 1872169699Skan denom = (c * ratio) + d; 1873169699Skan x = ((a * ratio) + b) / denom; 1874169699Skan y = ((b * ratio) - a) / denom; 1875169699Skan } 1876169699Skan else 1877169699Skan { 1878169699Skan ratio = d / c; 1879169699Skan denom = (d * ratio) + c; 1880169699Skan x = ((b * ratio) + a) / denom; 1881169699Skan y = (b - (a * ratio)) / denom; 1882169699Skan } 1883169699Skan 1884169699Skan /* Recover infinities and zeros that computed as NaN+iNaN; the only cases 1885169699Skan are nonzero/zero, infinite/finite, and finite/infinite. */ 1886169699Skan if (isnan (x) && isnan (y)) 1887169699Skan { 1888169699Skan if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) 1889169699Skan { 1890169699Skan x = COPYSIGN (INFINITY, c) * a; 1891169699Skan y = COPYSIGN (INFINITY, c) * b; 1892169699Skan } 1893169699Skan else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) 1894169699Skan { 1895169699Skan a = COPYSIGN (isinf (a) ? 1 : 0, a); 1896169699Skan b = COPYSIGN (isinf (b) ? 1 : 0, b); 1897169699Skan x = INFINITY * (a * c + b * d); 1898169699Skan y = INFINITY * (b * c - a * d); 1899169699Skan } 1900169699Skan else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) 1901169699Skan { 1902169699Skan c = COPYSIGN (isinf (c) ? 1 : 0, c); 1903169699Skan d = COPYSIGN (isinf (d) ? 1 : 0, d); 1904169699Skan x = 0.0 * (a * c + b * d); 1905169699Skan y = 0.0 * (b * c - a * d); 1906169699Skan } 1907169699Skan } 1908169699Skan 1909169699Skan return x + I * y; 1910169699Skan} 1911169699Skan#endif /* complex divide */ 1912169699Skan 1913169699Skan#endif /* all complex float routines */ 1914169699Skan 191518334Speter/* From here on down, the routines use normal data types. */ 191618334Speter 191718334Speter#define SItype bogus_type 191818334Speter#define USItype bogus_type 191918334Speter#define DItype bogus_type 192018334Speter#define UDItype bogus_type 192118334Speter#define SFtype bogus_type 192218334Speter#define DFtype bogus_type 192390280Sobrien#undef Wtype 192490280Sobrien#undef UWtype 192590280Sobrien#undef HWtype 192690280Sobrien#undef UHWtype 192790280Sobrien#undef DWtype 192890280Sobrien#undef UDWtype 192918334Speter 193018334Speter#undef char 193118334Speter#undef short 193218334Speter#undef int 193318334Speter#undef long 193418334Speter#undef unsigned 193518334Speter#undef float 193618334Speter#undef double 193718334Speter 193818334Speter#ifdef L__gcc_bcmp 193918334Speter 194018334Speter/* Like bcmp except the sign is meaningful. 194118334Speter Result is negative if S1 is less than S2, 194218334Speter positive if S1 is greater, 0 if S1 and S2 are equal. */ 194318334Speter 194418334Speterint 194590280Sobrien__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size) 194618334Speter{ 194718334Speter while (size > 0) 194818334Speter { 1949132727Skan const unsigned char c1 = *s1++, c2 = *s2++; 195018334Speter if (c1 != c2) 195118334Speter return c1 - c2; 195218334Speter size--; 195318334Speter } 195418334Speter return 0; 195518334Speter} 195618334Speter 195718334Speter#endif 195818334Speter 195990280Sobrien/* __eprintf used to be used by GCC's private version of <assert.h>. 196090280Sobrien We no longer provide that header, but this routine remains in libgcc.a 196190280Sobrien for binary backward compatibility. Note that it is not included in 196290280Sobrien the shared version of libgcc. */ 196318334Speter#ifdef L_eprintf 196418334Speter#ifndef inhibit_libc 196518334Speter 196618334Speter#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ 196718334Speter#include <stdio.h> 196852561Sobrien 196918334Spetervoid 197050600Sobrien__eprintf (const char *string, const char *expression, 197150600Sobrien unsigned int line, const char *filename) 197218334Speter{ 197318334Speter fprintf (stderr, string, expression, line, filename); 197418334Speter fflush (stderr); 197518334Speter abort (); 197618334Speter} 197718334Speter 197818334Speter#endif 197918334Speter#endif 198018334Speter 198118334Speter 198218334Speter#ifdef L_clear_cache 198318334Speter/* Clear part of an instruction cache. */ 198418334Speter 198518334Spetervoid 198690280Sobrien__clear_cache (char *beg __attribute__((__unused__)), 198790280Sobrien char *end __attribute__((__unused__))) 198818334Speter{ 198990280Sobrien#ifdef CLEAR_INSN_CACHE 199018334Speter CLEAR_INSN_CACHE (beg, end); 199118334Speter#endif /* CLEAR_INSN_CACHE */ 199218334Speter} 199318334Speter 199418334Speter#endif /* L_clear_cache */ 199518334Speter 1996132727Skan#ifdef L_enable_execute_stack 1997132727Skan/* Attempt to turn on execute permission for the stack. */ 1998132727Skan 1999132727Skan#ifdef ENABLE_EXECUTE_STACK 2000132727Skan ENABLE_EXECUTE_STACK 2001132727Skan#else 2002132727Skanvoid 2003132727Skan__enable_execute_stack (void *addr __attribute__((__unused__))) 2004132727Skan{} 2005132727Skan#endif /* ENABLE_EXECUTE_STACK */ 2006132727Skan 2007132727Skan#endif /* L_enable_execute_stack */ 2008132727Skan 200918334Speter#ifdef L_trampoline 201018334Speter 201118334Speter/* Jump to a trampoline, loading the static chain address. */ 201218334Speter 201352561Sobrien#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) 201418334Speter 2015169699Skanint 201690280Sobriengetpagesize (void) 201718334Speter{ 201818334Speter#ifdef _ALPHA_ 201918334Speter return 8192; 202018334Speter#else 202118334Speter return 4096; 202218334Speter#endif 202318334Speter} 202418334Speter 202590280Sobrien#ifdef __i386__ 202650600Sobrienextern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); 202750600Sobrien#endif 202850600Sobrien 202950600Sobrienint 203050600Sobrienmprotect (char *addr, int len, int prot) 203118334Speter{ 203218334Speter int np, op; 203318334Speter 203450600Sobrien if (prot == 7) 203550600Sobrien np = 0x40; 203650600Sobrien else if (prot == 5) 203750600Sobrien np = 0x20; 203850600Sobrien else if (prot == 4) 203950600Sobrien np = 0x10; 204050600Sobrien else if (prot == 3) 204150600Sobrien np = 0x04; 204250600Sobrien else if (prot == 1) 204350600Sobrien np = 0x02; 204450600Sobrien else if (prot == 0) 204550600Sobrien np = 0x01; 204618334Speter 204718334Speter if (VirtualProtect (addr, len, np, &op)) 204818334Speter return 0; 204918334Speter else 205018334Speter return -1; 205118334Speter} 205218334Speter 205352561Sobrien#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ 205418334Speter 205590280Sobrien#ifdef TRANSFER_FROM_TRAMPOLINE 205690280SobrienTRANSFER_FROM_TRAMPOLINE 205718334Speter#endif 205818334Speter#endif /* L_trampoline */ 205918334Speter 206052561Sobrien#ifndef __CYGWIN__ 206118334Speter#ifdef L__main 206218334Speter 206318334Speter#include "gbl-ctors.h" 2064169699Skan 206518334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these 206618334Speter cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 206718334Speter give the same symbol without quotes for an alternative entry point. You 206850600Sobrien must define both, or neither. */ 206918334Speter#ifndef NAME__MAIN 207018334Speter#define NAME__MAIN "__main" 207118334Speter#define SYMBOL__MAIN __main 207218334Speter#endif 207318334Speter 2074169699Skan#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP) 207550600Sobrien#undef HAS_INIT_SECTION 207650600Sobrien#define HAS_INIT_SECTION 207750600Sobrien#endif 207850600Sobrien 207950600Sobrien#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) 208090280Sobrien 208190280Sobrien/* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this 208290280Sobrien code to run constructors. In that case, we need to handle EH here, too. */ 208390280Sobrien 208490280Sobrien#ifdef EH_FRAME_SECTION_NAME 208590280Sobrien#include "unwind-dw2-fde.h" 208690280Sobrienextern unsigned char __EH_FRAME_BEGIN__[]; 208790280Sobrien#endif 208890280Sobrien 208918334Speter/* Run all the global destructors on exit from the program. */ 209018334Speter 209118334Spetervoid 209290280Sobrien__do_global_dtors (void) 209318334Speter{ 209418334Speter#ifdef DO_GLOBAL_DTORS_BODY 209518334Speter DO_GLOBAL_DTORS_BODY; 209618334Speter#else 209750600Sobrien static func_ptr *p = __DTOR_LIST__ + 1; 209850600Sobrien while (*p) 209950600Sobrien { 210050600Sobrien p++; 210150600Sobrien (*(p-1)) (); 210250600Sobrien } 210318334Speter#endif 210490280Sobrien#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) 210590280Sobrien { 210690280Sobrien static int completed = 0; 210790280Sobrien if (! completed) 210890280Sobrien { 210990280Sobrien completed = 1; 211090280Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 211190280Sobrien } 211290280Sobrien } 211390280Sobrien#endif 211418334Speter} 211550600Sobrien#endif 211618334Speter 211750600Sobrien#ifndef HAS_INIT_SECTION 211818334Speter/* Run all the global constructors on entry to the program. */ 211918334Speter 212018334Spetervoid 212190280Sobrien__do_global_ctors (void) 212218334Speter{ 212390280Sobrien#ifdef EH_FRAME_SECTION_NAME 212490280Sobrien { 212590280Sobrien static struct object object; 212690280Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 212790280Sobrien } 212890280Sobrien#endif 212918334Speter DO_GLOBAL_CTORS_BODY; 213090280Sobrien atexit (__do_global_dtors); 213118334Speter} 213250600Sobrien#endif /* no HAS_INIT_SECTION */ 213318334Speter 213450600Sobrien#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) 213518334Speter/* Subroutine called automatically by `main'. 213618334Speter Compiling a global function named `main' 213718334Speter produces an automatic call to this function at the beginning. 213818334Speter 213918334Speter For many systems, this routine calls __do_global_ctors. 214018334Speter For systems which support a .init section we use the .init section 214118334Speter to run __do_global_ctors, so we need not do anything here. */ 214218334Speter 2143132727Skanextern void SYMBOL__MAIN (void); 214418334Spetervoid 2145132727SkanSYMBOL__MAIN (void) 214618334Speter{ 214718334Speter /* Support recursive calls to `main': run initializers just once. */ 214818334Speter static int initialized; 214918334Speter if (! initialized) 215018334Speter { 215118334Speter initialized = 1; 215218334Speter __do_global_ctors (); 215318334Speter } 215418334Speter} 215550600Sobrien#endif /* no HAS_INIT_SECTION or INVOKE__main */ 215618334Speter 215718334Speter#endif /* L__main */ 215852561Sobrien#endif /* __CYGWIN__ */ 215918334Speter 216018334Speter#ifdef L_ctors 216118334Speter 216218334Speter#include "gbl-ctors.h" 216318334Speter 216418334Speter/* Provide default definitions for the lists of constructors and 216518334Speter destructors, so that we don't get linker errors. These symbols are 216618334Speter intentionally bss symbols, so that gld and/or collect will provide 216718334Speter the right values. */ 216818334Speter 216918334Speter/* We declare the lists here with two elements each, 217052561Sobrien so that they are valid empty lists if no other definition is loaded. 217152561Sobrien 217252561Sobrien If we are using the old "set" extensions to have the gnu linker 217352561Sobrien collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__ 217452561Sobrien must be in the bss/common section. 217552561Sobrien 217652561Sobrien Long term no port should use those extensions. But many still do. */ 217750600Sobrien#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) 217890280Sobrien#if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2) 217918334Speterfunc_ptr __CTOR_LIST__[2] = {0, 0}; 218018334Speterfunc_ptr __DTOR_LIST__[2] = {0, 0}; 218118334Speter#else 218218334Speterfunc_ptr __CTOR_LIST__[2]; 218318334Speterfunc_ptr __DTOR_LIST__[2]; 218418334Speter#endif 218518334Speter#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ 218618334Speter#endif /* L_ctors */ 2187169699Skan#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */ 2188