aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2004-02-07 03:06:46 +0000
committerAlan Modra <amodra@gcc.gnu.org>2004-02-07 13:36:46 +1030
commitfb7e4164c03f723aaf0abc3dffe3f743d8888eba (patch)
tree528dfa87534bd4e0e301d8ec7b35a3eabc6f7670 /gcc
parent254878eaddab86eae9ec232baedfdc4103cf7ef9 (diff)
downloadgcc-fb7e4164c03f723aaf0abc3dffe3f743d8888eba.zip
gcc-fb7e4164c03f723aaf0abc3dffe3f743d8888eba.tar.gz
gcc-fb7e4164c03f723aaf0abc3dffe3f743d8888eba.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/rs6000/darwin-ldouble.c4
-rw-r--r--gcc/config/rs6000/libgcc-ppc64.ver7
-rw-r--r--gcc/config/rs6000/ppc64-fp.c53
-rw-r--r--gcc/config/rs6000/rs6000.c11
-rw-r--r--gcc/config/rs6000/t-linux6421
6 files changed, 100 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 48393ee..d4d04ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+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>
Ulrich Weigand <uweigand@de.ibm.com>
diff --git a/gcc/config/rs6000/darwin-ldouble.c b/gcc/config/rs6000/darwin-ldouble.c
index 678b93f..e3dc562 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 0000000..116d5e7
--- /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 755827f..c736d9a 100644
--- a/gcc/config/rs6000/ppc64-fp.c
+++ b/gcc/config/rs6000/ppc64-fp.c
@@ -33,17 +33,28 @@ 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)
{
if (a < 0)
@@ -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 1db36b1..9cacc88 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 b94975e..0e86f5f 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 > $@
+