Commit fb7e4164 by Alan Modra Committed by Alan Modra

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
parent 254878ea
2004-02-07 Alan Modra <amodra@bigpond.net.au>
* 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 <roger@eyesopen.com> 2004-02-06 Roger Sayle <roger@eyesopen.com>
Ulrich Weigand <uweigand@de.ibm.com> Ulrich Weigand <uweigand@de.ibm.com>
......
...@@ -48,6 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -48,6 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
This code currently assumes big-endian. */ This code currently assumes big-endian. */
#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
#define fabs(x) __builtin_fabs(x) #define fabs(x) __builtin_fabs(x)
#define unlikely(x) __builtin_expect ((x), 0) #define unlikely(x) __builtin_expect ((x), 0)
...@@ -199,3 +201,5 @@ _xlqdiv (double a, double b, double c, double d) ...@@ -199,3 +201,5 @@ _xlqdiv (double a, double b, double c, double d)
z.dval[1] = (t - u) + tau; z.dval[1] = (t - u) + tau;
return z.ldval; return z.ldval;
} }
#endif
GCC_3.4 {
# long double support
_xlqadd
_xlqsub
_xlqmul
_xlqdiv
}
...@@ -33,17 +33,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -33,17 +33,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#if defined(__powerpc64__) #if defined(__powerpc64__)
#include "config/fp-bit.h" #include "config/fp-bit.h"
extern DItype __fixtfdi (TFtype);
extern DItype __fixdfdi (DFtype); extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype); extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype); extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype); extern USItype __fixunssfsi (SFtype);
extern TFtype __floatditf (DItype);
extern DFtype __floatdidf (DItype); extern DFtype __floatdidf (DItype);
extern SFtype __floatdisf (DItype); extern SFtype __floatdisf (DItype);
extern DItype __fixunstfdi (TFtype);
static DItype local_fixunssfdi (SFtype); static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype); static DItype local_fixunsdfdi (DFtype);
DItype DItype
__fixtfdi (TFtype a)
{
if (a < 0)
return - __fixunstfdi (-a);
return __fixunstfdi (a);
}
DItype
__fixdfdi (DFtype a) __fixdfdi (DFtype a)
{ {
if (a < 0) if (a < 0)
...@@ -77,14 +88,25 @@ __fixunssfsi (SFtype a) ...@@ -77,14 +88,25 @@ __fixunssfsi (SFtype a)
return (SItype) 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 DFtype
__floatdidf (DItype u) __floatdidf (DItype u)
{ {
DFtype d; DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8)); d = (SItype) (u >> (sizeof (SItype) * 8));
d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d; return d;
...@@ -109,13 +131,36 @@ __floatdisf (DItype u) ...@@ -109,13 +131,36 @@ __floatdisf (DItype u)
} }
} }
f = (SItype) (u >> (sizeof (SItype) * 8)); f = (SItype) (u >> (sizeof (SItype) * 8));
f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f; 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 /* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */ calls fixdfdi, which in turn calls calls fixunsdfdi. */
......
...@@ -4417,7 +4417,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4417,7 +4417,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
/* If this is partially on the stack, then /* If this is partially on the stack, then
we only include the portion actually we only include the portion actually
in registers here. */ in registers here. */
? gen_rtx_REG (SImode, ? gen_rtx_REG (Pmode,
GP_ARG_MIN_REG + align_words) GP_ARG_MIN_REG + align_words)
: gen_rtx_REG (mode, : gen_rtx_REG (mode,
GP_ARG_MIN_REG + align_words))), GP_ARG_MIN_REG + align_words))),
...@@ -15726,6 +15726,7 @@ rs6000_complex_function_value (enum machine_mode mode) ...@@ -15726,6 +15726,7 @@ rs6000_complex_function_value (enum machine_mode mode)
unsigned int regno; unsigned int regno;
rtx r1, r2; rtx r1, r2;
enum machine_mode inner = GET_MODE_INNER (mode); enum machine_mode inner = GET_MODE_INNER (mode);
unsigned int inner_bytes = GET_MODE_SIZE (inner);
if (FLOAT_MODE_P (mode)) if (FLOAT_MODE_P (mode))
regno = FP_ARG_RETURN; regno = FP_ARG_RETURN;
...@@ -15734,15 +15735,17 @@ rs6000_complex_function_value (enum machine_mode mode) ...@@ -15734,15 +15735,17 @@ rs6000_complex_function_value (enum machine_mode mode)
regno = GP_ARG_RETURN; regno = GP_ARG_RETURN;
/* 32-bit is OK since it'll go in r3/r4. */ /* 32-bit is OK since it'll go in r3/r4. */
if (TARGET_32BIT if (TARGET_32BIT && inner_bytes >= 4)
&& GET_MODE_BITSIZE (inner) >= 32)
return gen_rtx_REG (mode, regno); 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), r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
const0_rtx); const0_rtx);
r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1), 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)); return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
} }
......
# 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 #rs6000/t-linux64
SHLIB_MKMAP_OPTS = -v dotsyms=1
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_OPTIONS = m64/m32 msoft-float
MULTILIB_DIRNAMES = 64 32 nof MULTILIB_DIRNAMES = 64 32 nof
...@@ -12,8 +16,6 @@ MULTILIB_EXCLUSIONS = m64/!m32/msoft-float ...@@ -12,8 +16,6 @@ MULTILIB_EXCLUSIONS = m64/!m32/msoft-float
MULTILIB_OSDIRNAMES = ../lib64 ../lib nof MULTILIB_OSDIRNAMES = ../lib64 ../lib nof
MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) 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 # We want fine grained libraries, so use the new code to build the
# floating point emulation libraries. # floating point emulation libraries.
# fp-bit is only to be used by 32-bit multilibs # fp-bit is only to be used by 32-bit multilibs
...@@ -30,3 +32,10 @@ fp-bit32.c: $(srcdir)/config/fp-bit.c ...@@ -30,3 +32,10 @@ fp-bit32.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT'; \ echo '#define FLOAT'; \
cat $(srcdir)/config/fp-bit.c; \ cat $(srcdir)/config/fp-bit.c; \
echo '#endif' ) > fp-bit32.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 > $@
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment