OSDN Git Service

* testsuite/libffi.call/float1.c (value_type): New typedef.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Sep 2005 19:56:22 +0000 (19:56 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Sep 2005 19:56:22 +0000 (19:56 +0000)
(CANARY): New define.
(main): Check for result buffer overflow.
* src/powerpc/linux64.S: Handle linux64 long double returns.
* src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
(ffi_prep_cif_machdep): Handle linux64 long double returns.

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

libffi/ChangeLog
libffi/src/powerpc/ffi.c
libffi/src/powerpc/linux64.S
libffi/testsuite/libffi.call/float1.c

index fd61c4b..df544ba 100644 (file)
@@ -1,3 +1,12 @@
+2005-09-26  Tom Tromey  <tromey@redhat.com>
+
+       * testsuite/libffi.call/float1.c (value_type): New typedef.
+       (CANARY): New define.
+       (main): Check for result buffer overflow.
+       * src/powerpc/linux64.S: Handle linux64 long double returns.
+       * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
+       (ffi_prep_cif_machdep): Handle linux64 long double returns.
+
 2005-08-25  Alan Modra  <amodra@bigpond.net.au>
 
        PR target/23404
index cc410bc..7d8bf3a 100644 (file)
@@ -39,6 +39,7 @@ enum {
   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
   FLAG_RETURNS_FP       = 1 << (31-29),
   FLAG_RETURNS_64BITS   = 1 << (31-28),
+  FLAG_RETURNS_128BITS  = 1 << (31-27),
 
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
@@ -543,6 +544,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
       /* else fall through.  */
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
     case FFI_TYPE_LONGDOUBLE:
+      if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
+       {
+         flags |= FLAG_RETURNS_128BITS;
+         flags |= FLAG_RETURNS_FP;
+         break;
+       }
 #endif
       intarg_count++;
       flags |= FLAG_RETVAL_REFERENCE;
index 18423bf..25b2c4f 100644 (file)
@@ -120,9 +120,13 @@ ffi_call_LINUX64:
        blr
 
 .Lfp_return_value:
+       bt      27, .Lfd_return_value
        bf      28, .Lfloat_return_value
        stfd    %f1, 0(%r30)
-       stfd    %f2, 8(%r30)    /* It might be a long double */
+       b       .Ldone_return_value
+.Lfd_return_value:
+       stfd    %f1, 0(%r30)
+       stfd    %f2, 8(%r30)
        b       .Ldone_return_value
 .Lfloat_return_value:
        stfs    %f1, 0(%r30)
index 94636a2..fb81d7d 100644 (file)
@@ -8,6 +8,14 @@
 #include "ffitest.h"
 #include "float.h"
 
+typedef union
+{
+  double d;
+  unsigned char c[sizeof (double)];
+} value_type;
+
+#define CANARY 0xba
+
 static double dblit(float f)
 {
   return f/3.0;
@@ -19,8 +27,8 @@ int main (void)
   ffi_type *args[MAX_ARGS];
   void *values[MAX_ARGS];
   float f;
-  double d;
-
+  value_type result[2];
+  int i;
 
   args[0] = &ffi_type_float;
   values[0] = &f;
@@ -31,11 +39,19 @@ int main (void)
   
   f = 3.14159;
   
-  ffi_call(&cif, FFI_FN(dblit), &d, values);
+  /* Put a canary in the return array.  This is a regression test for
+     a buffer overrun.  */
+  memset(result[1].c, CANARY, sizeof (double));
+
+  ffi_call(&cif, FFI_FN(dblit), &result[0].d, values);
   
   /* These are not always the same!! Check for a reasonable delta */
  
-  CHECK(d - dblit(f) < DBL_EPSILON);
+  CHECK(result[0].d - dblit(f) < DBL_EPSILON);
+
+  /* Check the canary.  */
+  for (i = 0; i < sizeof (double); ++i)
+    CHECK(result[1].c[i] == CANARY);
 
   exit(0);