From: Alan Modra Date: Sat, 7 Feb 2004 03:06:46 +0000 (+0000) Subject: t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c. X-Git-Tag: releases/gcc-4.0.0~10288 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb7e4164c03f723aaf0abc3dffe3f743d8888eba;p=thirdparty%2Fgcc.git t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c. * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c. (SHLIB_MAPFILES): Add libgcc-ppc64.ver. (SHLIB_MKMAP_OPTS): Delete. (TARGET_LIBGCC2_CFLAGS): Add -specs. (bispecs): Add rule. * config/rs6000/libgcc-ppc64.ver: New file. * config/rs6000/ppc64-fp.c (__fixtfdi, __floatditf): New functions. (__floatdidf, __floatdisf): Optimize multiply. (__fixunstfdi): New function. * config/rs6000/rs6000.c (rs6000_complex_function_value): Allow for real and imag parts larger than one register. (function_arg): Correct type of reg used when fp arg split partially to stack. * config/rs6000/darwin-ldouble.c: Protect with #if !_SOFT_FLOAT and __MACH__ or __powerpc64__. From-SVN: r77440 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48393ee5ece6..d4d04ff07c73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2004-02-07 Alan Modra + + * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c. + (SHLIB_MAPFILES): Add libgcc-ppc64.ver. + (SHLIB_MKMAP_OPTS): Delete. + (TARGET_LIBGCC2_CFLAGS): Add -specs. + (bispecs): Add rule. + * config/rs6000/libgcc-ppc64.ver: New file. + * config/rs6000/ppc64-fp.c (__fixtfdi, __floatditf): New functions. + (__floatdidf, __floatdisf): Optimize multiply. + (__fixunstfdi): New function. + * config/rs6000/rs6000.c (rs6000_complex_function_value): Allow for + real and imag parts larger than one register. + (function_arg): Correct type of reg used when fp arg split partially + to stack. + * config/rs6000/darwin-ldouble.c: Protect with #if !_SOFT_FLOAT + and __MACH__ or __powerpc64__. + 2004-02-06 Roger Sayle Ulrich Weigand diff --git a/gcc/config/rs6000/darwin-ldouble.c b/gcc/config/rs6000/darwin-ldouble.c index 678b93f23927..e3dc56274458 100644 --- a/gcc/config/rs6000/darwin-ldouble.c +++ b/gcc/config/rs6000/darwin-ldouble.c @@ -48,6 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA This code currently assumes big-endian. */ +#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__)) + #define fabs(x) __builtin_fabs(x) #define unlikely(x) __builtin_expect ((x), 0) @@ -199,3 +201,5 @@ _xlqdiv (double a, double b, double c, double d) z.dval[1] = (t - u) + tau; return z.ldval; } + +#endif diff --git a/gcc/config/rs6000/libgcc-ppc64.ver b/gcc/config/rs6000/libgcc-ppc64.ver new file mode 100644 index 000000000000..116d5e73fa07 --- /dev/null +++ b/gcc/config/rs6000/libgcc-ppc64.ver @@ -0,0 +1,7 @@ +GCC_3.4 { + # long double support + _xlqadd + _xlqsub + _xlqmul + _xlqdiv +} diff --git a/gcc/config/rs6000/ppc64-fp.c b/gcc/config/rs6000/ppc64-fp.c index 755827fb0b46..c736d9ad7c86 100644 --- a/gcc/config/rs6000/ppc64-fp.c +++ b/gcc/config/rs6000/ppc64-fp.c @@ -33,16 +33,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #if defined(__powerpc64__) #include "config/fp-bit.h" +extern DItype __fixtfdi (TFtype); extern DItype __fixdfdi (DFtype); extern DItype __fixsfdi (SFtype); extern USItype __fixunsdfsi (DFtype); extern USItype __fixunssfsi (SFtype); +extern TFtype __floatditf (DItype); extern DFtype __floatdidf (DItype); extern SFtype __floatdisf (DItype); +extern DItype __fixunstfdi (TFtype); static DItype local_fixunssfdi (SFtype); static DItype local_fixunsdfdi (DFtype); +DItype +__fixtfdi (TFtype a) +{ + if (a < 0) + return - __fixunstfdi (-a); + return __fixunstfdi (a); +} + DItype __fixdfdi (DFtype a) { @@ -77,14 +88,25 @@ __fixunssfsi (SFtype a) return (SItype) a; } +TFtype +__floatditf (DItype u) +{ + DFtype dh, dl; + + dh = (SItype) (u >> (sizeof (SItype) * 8)); + dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); + dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); + + return (TFtype) dh + (TFtype) dl; +} + DFtype __floatdidf (DItype u) { DFtype d; d = (SItype) (u >> (sizeof (SItype) * 8)); - d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); - d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); + d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); return d; @@ -109,13 +131,36 @@ __floatdisf (DItype u) } } f = (SItype) (u >> (sizeof (SItype) * 8)); - f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); - f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); + f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); return (SFtype) f; } +DItype +__fixunstfdi (TFtype a) +{ + if (a < 0) + return 0; + + /* Compute high word of result, as a flonum. */ + const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8))); + /* Convert that to fixed (but not to DItype!), + and shift it into the high word. */ + UDItype v = (USItype) b; + v <<= (sizeof (SItype) * 8); + /* Remove high part from the TFtype, leaving the low part as flonum. */ + a -= (TFtype) v; + /* Convert that to fixed (but not to DItype!) and add it in. + Sometimes A comes out negative. This is significant, since + A has more bits than a long int does. */ + if (a < 0) + v -= (USItype) (-a); + else + v += (USItype) a; + return v; +} + /* This version is needed to prevent recursion; fixunsdfdi in libgcc calls fixdfdi, which in turn calls calls fixunsdfdi. */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1db36b17f2e2..9cacc88f7001 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4417,7 +4417,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* If this is partially on the stack, then we only include the portion actually in registers here. */ - ? gen_rtx_REG (SImode, + ? gen_rtx_REG (Pmode, GP_ARG_MIN_REG + align_words) : gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words))), @@ -15726,6 +15726,7 @@ rs6000_complex_function_value (enum machine_mode mode) unsigned int regno; rtx r1, r2; enum machine_mode inner = GET_MODE_INNER (mode); + unsigned int inner_bytes = GET_MODE_SIZE (inner); if (FLOAT_MODE_P (mode)) regno = FP_ARG_RETURN; @@ -15734,15 +15735,17 @@ rs6000_complex_function_value (enum machine_mode mode) regno = GP_ARG_RETURN; /* 32-bit is OK since it'll go in r3/r4. */ - if (TARGET_32BIT - && GET_MODE_BITSIZE (inner) >= 32) + if (TARGET_32BIT && inner_bytes >= 4) return gen_rtx_REG (mode, regno); } + if (inner_bytes >= 8) + return gen_rtx_REG (mode, regno); + r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno), const0_rtx); r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1), - GEN_INT (GET_MODE_UNIT_SIZE (inner))); + GEN_INT (inner_bytes)); return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2)); } diff --git a/gcc/config/rs6000/t-linux64 b/gcc/config/rs6000/t-linux64 index b94975e0c1d5..0e86f5f26ff0 100644 --- a/gcc/config/rs6000/t-linux64 +++ b/gcc/config/rs6000/t-linux64 @@ -1,8 +1,12 @@ -# These functions are needed for soft-float on powerpc64-linux. -LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c -# Modify the shared lib version file -SHLIB_MKMAP_OPTS = -v dotsyms=1 +#rs6000/t-linux64 + +LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \ + $(srcdir)/config/rs6000/darwin-ldouble.c + +TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC -specs=bispecs + +SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc64.ver MULTILIB_OPTIONS = m64/m32 msoft-float MULTILIB_DIRNAMES = 64 32 nof @@ -12,8 +16,6 @@ MULTILIB_EXCLUSIONS = m64/!m32/msoft-float MULTILIB_OSDIRNAMES = ../lib64 ../lib nof MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) -TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC - # We want fine grained libraries, so use the new code to build the # floating point emulation libraries. # fp-bit is only to be used by 32-bit multilibs @@ -30,3 +32,10 @@ fp-bit32.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT'; \ cat $(srcdir)/config/fp-bit.c; \ echo '#endif' ) > fp-bit32.c + +# Hack to use -mlong-double-128 just for compiling 64 bit libgcc +mklibgcc: bispecs + +bispecs: specs + sed -e '/cc1_options/{ n; s/$$/ %{!m32:-mlong-double-128}/; }' < specs > $@ +