X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flibgcc2.c;h=20e7bd2b6d794592e2d60866b53a3b7f2289ceb2;hb=9faf44d607eac99a28edbec0beea479c3417ffe4;hp=f3a0a2429708f1066681291230701992d7da809d;hpb=427911176defd91fb2ac55f17bde1da551c2c02b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index f3a0a242970..20e7bd2b6d7 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -1,33 +1,29 @@ /* More subroutines needed by GCC output code on some machines. */ /* Compile this one with gcc. */ /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) - GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ #include "tconfig.h" #include "tsystem.h" @@ -40,15 +36,11 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #define ATTRIBUTE_HIDDEN #endif -#ifndef MIN_UNITS_PER_WORD -#define MIN_UNITS_PER_WORD UNITS_PER_WORD -#endif - /* Work out the largest "word" size that we can deal with on this target. */ #if MIN_UNITS_PER_WORD > 4 # define LIBGCC2_MAX_UNITS_PER_WORD 8 #elif (MIN_UNITS_PER_WORD > 2 \ - || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)) + || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4)) # define LIBGCC2_MAX_UNITS_PER_WORD 4 #else # define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD @@ -84,7 +76,7 @@ __negdi2 (DWtype u) Wtype __addvSI3 (Wtype a, Wtype b) { - const Wtype w = a + b; + const Wtype w = (UWtype) a + (UWtype) b; if (b >= 0 ? w < a : w > a) abort (); @@ -95,7 +87,7 @@ __addvSI3 (Wtype a, Wtype b) SItype __addvsi3 (SItype a, SItype b) { - const SItype w = a + b; + const SItype w = (USItype) a + (USItype) b; if (b >= 0 ? w < a : w > a) abort (); @@ -109,7 +101,7 @@ __addvsi3 (SItype a, SItype b) DWtype __addvDI3 (DWtype a, DWtype b) { - const DWtype w = a + b; + const DWtype w = (UDWtype) a + (UDWtype) b; if (b >= 0 ? w < a : w > a) abort (); @@ -122,7 +114,7 @@ __addvDI3 (DWtype a, DWtype b) Wtype __subvSI3 (Wtype a, Wtype b) { - const Wtype w = a - b; + const Wtype w = (UWtype) a - (UWtype) b; if (b >= 0 ? w > a : w < a) abort (); @@ -133,7 +125,7 @@ __subvSI3 (Wtype a, Wtype b) SItype __subvsi3 (SItype a, SItype b) { - const SItype w = a - b; + const SItype w = (USItype) a - (USItype) b; if (b >= 0 ? w > a : w < a) abort (); @@ -147,7 +139,7 @@ __subvsi3 (SItype a, SItype b) DWtype __subvDI3 (DWtype a, DWtype b) { - const DWtype w = a - b; + const DWtype w = (UDWtype) a - (UDWtype) b; if (b >= 0 ? w > a : w < a) abort (); @@ -187,7 +179,7 @@ __mulvsi3 (SItype a, SItype b) Wtype __negvSI2 (Wtype a) { - const Wtype w = -a; + const Wtype w = -(UWtype) a; if (a >= 0 ? w > 0 : w < 0) abort (); @@ -198,7 +190,7 @@ __negvSI2 (Wtype a) SItype __negvsi2 (SItype a) { - const SItype w = -a; + const SItype w = -(USItype) a; if (a >= 0 ? w > 0 : w < 0) abort (); @@ -212,7 +204,7 @@ __negvsi2 (SItype a) DWtype __negvDI2 (DWtype a) { - const DWtype w = -a; + const DWtype w = -(UDWtype) a; if (a >= 0 ? w > 0 : w < 0) abort (); @@ -231,7 +223,7 @@ __absvSI2 (Wtype a) #ifdef L_negvsi2 w = __negvSI2 (a); #else - w = -a; + w = -(UWtype) a; if (w < 0) abort (); @@ -249,7 +241,7 @@ __absvsi2 (SItype a) #ifdef L_negvsi2 w = __negvsi2 (a); #else - w = -a; + w = -(USItype) a; if (w < 0) abort (); @@ -270,7 +262,7 @@ __absvDI2 (DWtype a) #ifdef L_negvdi2 w = __negvDI2 (a); #else - w = -a; + w = -(UDWtype) a; if (w < 0) abort (); @@ -406,16 +398,16 @@ __mulvDI3 (DWtype u, DWtype v) /* Unless shift functions are defined with full ANSI prototypes, - parameter b will be promoted to int if word_type is smaller than an int. */ + parameter b will be promoted to int if shift_count_type is smaller than an int. */ #ifdef L_lshrdi3 DWtype -__lshrdi3 (DWtype u, word_type b) +__lshrdi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -437,13 +429,13 @@ __lshrdi3 (DWtype u, word_type b) #ifdef L_ashldi3 DWtype -__ashldi3 (DWtype u, word_type b) +__ashldi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -465,13 +457,13 @@ __ashldi3 (DWtype u, word_type b) #ifdef L_ashrdi3 DWtype -__ashrdi3 (DWtype u, word_type b) +__ashrdi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -493,8 +485,8 @@ __ashrdi3 (DWtype u, word_type b) #endif #ifdef L_bswapsi2 -UWtype -__bswapSI2 (UWtype u) +SItype +__bswapsi2 (SItype u) { return ((((u) & 0xff000000) >> 24) | (((u) & 0x00ff0000) >> 8) @@ -503,8 +495,8 @@ __bswapSI2 (UWtype u) } #endif #ifdef L_bswapdi2 -UDWtype -__bswapDI2 (UDWtype u) +DItype +__bswapdi2 (DItype u) { return ((((u) & 0xff00000000000000ull) >> 56) | (((u) & 0x00ff000000000000ull) >> 40) @@ -1082,7 +1074,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) DWtype __divdi3 (DWtype u, DWtype v) { - word_type c = 0; + Wtype c = 0; DWunion uu = {.ll = u}; DWunion vv = {.ll = v}; DWtype w; @@ -1106,7 +1098,7 @@ __divdi3 (DWtype u, DWtype v) DWtype __moddi3 (DWtype u, DWtype v) { - word_type c = 0; + Wtype c = 0; DWunion uu = {.ll = u}; DWunion vv = {.ll = v}; DWtype w; @@ -1146,7 +1138,7 @@ __udivdi3 (UDWtype n, UDWtype d) #endif #ifdef L_cmpdi2 -word_type +cmp_return_type __cmpdi2 (DWtype a, DWtype b) { const DWunion au = {.ll = a}; @@ -1165,7 +1157,7 @@ __cmpdi2 (DWtype a, DWtype b) #endif #ifdef L_ucmpdi2 -word_type +cmp_return_type __ucmpdi2 (DWtype a, DWtype b) { const DWunion au = {.ll = a}; @@ -1184,7 +1176,7 @@ __ucmpdi2 (DWtype a, DWtype b) #endif #if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE -DWtype +UDWtype __fixunstfDI (TFtype a) { if (a < 0) @@ -1220,7 +1212,7 @@ __fixtfdi (TFtype a) #endif #if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE -DWtype +UDWtype __fixunsxfDI (XFtype a) { if (a < 0) @@ -1256,7 +1248,7 @@ __fixxfdi (XFtype a) #endif #if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE -DWtype +UDWtype __fixunsdfDI (DFtype a) { /* Get high part of result. The division here will just moves the radix @@ -1285,7 +1277,7 @@ __fixdfdi (DFtype a) #endif #if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE -DWtype +UDWtype __fixunssfDI (SFtype a) { #if LIBGCC2_HAS_DF_MODE @@ -1420,11 +1412,7 @@ __floatunditf (UDWtype u) #define F_MODE_OK(SIZE) \ (SIZE < DI_SIZE \ && SIZE > (DI_SIZE - SIZE + FSSIZE) \ - /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ - The conversion from long double to float suffers from double \ - rounding, because we convert via double. In any case, the \ - fallback code is faster. */ \ - && !IS_IBM_EXTENDED (SIZE)) + && !AVOID_FP_TYPE_CONVERSION(SIZE)) #if defined(L_floatdisf) #define FUNC __floatdisf #define FSTYPE SFtype @@ -1515,13 +1503,21 @@ FUNC (DWtype u) hi = u >> shift; /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ - if (u & (((DWtype)1 << shift) - 1)) + if ((UWtype)u << (W_TYPE_SIZE - shift)) hi |= 1; /* Convert the one word of data, and rescale. */ - FSTYPE f = hi; - f *= (UDWtype)1 << shift; - return f; + FSTYPE f = hi, e; + if (shift == W_TYPE_SIZE) + e = Wtype_MAXp1_F; + /* The following two cases could be merged if we knew that the target + supported a native unsigned->float conversion. More often, we only + have a signed conversion, and have to add extra fixup code. */ + else if (shift == W_TYPE_SIZE - 1) + e = Wtype_MAXp1_F / 2; + else + e = (Wtype)1 << shift; + return f * e; #endif } #endif @@ -1532,11 +1528,7 @@ FUNC (DWtype u) #define F_MODE_OK(SIZE) \ (SIZE < DI_SIZE \ && SIZE > (DI_SIZE - SIZE + FSSIZE) \ - /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ - The conversion from long double to float suffers from double \ - rounding, because we convert via double. In any case, the \ - fallback code is faster. */ \ - && !IS_IBM_EXTENDED (SIZE)) + && !AVOID_FP_TYPE_CONVERSION(SIZE)) #if defined(L_floatundisf) #define FUNC __floatundisf #define FSTYPE SFtype @@ -1620,13 +1612,21 @@ FUNC (UDWtype u) hi = u >> shift; /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ - if (u & (((UDWtype)1 << shift) - 1)) + if ((UWtype)u << (W_TYPE_SIZE - shift)) hi |= 1; /* Convert the one word of data, and rescale. */ - FSTYPE f = hi; - f *= (UDWtype)1 << shift; - return f; + FSTYPE f = hi, e; + if (shift == W_TYPE_SIZE) + e = Wtype_MAXp1_F; + /* The following two cases could be merged if we knew that the target + supported a native unsigned->float conversion. More often, we only + have a signed conversion, and have to add extra fixup code. */ + else if (shift == W_TYPE_SIZE - 1) + e = Wtype_MAXp1_F / 2; + else + e = (Wtype)1 << shift; + return f * e; #endif } #endif @@ -1772,7 +1772,11 @@ NAME (TYPE x, int m) # define MTYPE TFtype # define CTYPE TCtype # define MODE tc -# define CEXT l +# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128 +# define CEXT l +# else +# define CEXT LIBGCC2_TF_CEXT +# endif # define NOTRUNC 1 #else # error @@ -1794,7 +1798,7 @@ NAME (TYPE x, int m) #define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1) #define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0) -#define INFINITY CONCAT2(__builtin_inf, CEXT) () +#define INFINITY CONCAT2(__builtin_huge_val, CEXT) () #define I 1i /* Helpers to make the following code slightly less gross. */ @@ -1818,6 +1822,7 @@ CTYPE CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) { MTYPE ac, bd, ad, bc, x, y; + CTYPE res; ac = a * c; bd = b * d; @@ -1874,7 +1879,9 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) } } - return x + I * y; + __real__ res = x; + __imag__ res = y; + return res; } #endif /* complex multiply */ @@ -1885,8 +1892,9 @@ CTYPE CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) { MTYPE denom, ratio, x, y; + CTYPE res; - /* ??? We can get better behavior from logarithmic scaling instead of + /* ??? We can get better behavior from logarithmic scaling instead of the division. But that would mean starting to link libgcc against libm. We could implement something akin to ldexp/frexp as gcc builtins fairly easily... */ @@ -1909,7 +1917,7 @@ CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) are nonzero/zero, infinite/finite, and finite/infinite. */ if (isnan (x) && isnan (y)) { - if (denom == 0.0 && (!isnan (a) || !isnan (b))) + if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) { x = COPYSIGN (INFINITY, c) * a; y = COPYSIGN (INFINITY, c) * b; @@ -1930,7 +1938,9 @@ CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) } } - return x + I * y; + __real__ res = x; + __imag__ res = y; + return res; } #endif /* complex divide */ @@ -2034,7 +2044,9 @@ __enable_execute_stack (void *addr __attribute__((__unused__))) /* Jump to a trampoline, loading the static chain address. */ -#if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) +#if defined(WINNT) && ! defined(__CYGWIN__) +int getpagesize (void); +int mprotect (char *,int, int); int getpagesize (void) @@ -2046,14 +2058,10 @@ getpagesize (void) #endif } -#ifdef __i386__ -extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); -#endif - int mprotect (char *addr, int len, int prot) { - int np, op; + DWORD np, op; if (prot == 7) np = 0x40; @@ -2067,6 +2075,8 @@ mprotect (char *addr, int len, int prot) np = 0x02; else if (prot == 0) np = 0x01; + else + return -1; if (VirtualProtect (addr, len, np, &op)) return 0; @@ -2074,7 +2084,7 @@ mprotect (char *addr, int len, int prot) return -1; } -#endif /* WINNT && ! __CYGWIN__ && ! _UWIN */ +#endif /* WINNT && ! __CYGWIN__ */ #ifdef TRANSFER_FROM_TRAMPOLINE TRANSFER_FROM_TRAMPOLINE