OSDN Git Service

* config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c.
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 7 Feb 2004 03:06:46 +0000 (03:06 +0000)
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 7 Feb 2004 03:06:46 +0000 (03:06 +0000)
(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__.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77440 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/darwin-ldouble.c
gcc/config/rs6000/libgcc-ppc64.ver [new file with mode: 0644]
gcc/config/rs6000/ppc64-fp.c
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/t-linux64

index 48393ee..d4d04ff 100644 (file)
@@ -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>
 
index 678b93f..e3dc562 100644 (file)
@@ -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 (file)
index 0000000..116d5e7
--- /dev/null
@@ -0,0 +1,7 @@
+GCC_3.4 {
+  # long double support
+  _xlqadd
+  _xlqsub
+  _xlqmul
+  _xlqdiv
+}
index 755827f..c736d9a 100644 (file)
@@ -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.  */
 
index 1db36b1..9cacc88 100644 (file)
@@ -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));
 }
 
index b94975e..0e86f5f 100644 (file)
@@ -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 > $@
+