Commit c2422174b3edc0de0b148dfd6b67087bb881c4a6

Anthony Green 2013-11-02T14:08:23

Merge pull request #45 from foss-for-synopsys-dwc-arc-processors/arc_support arc: Fix build error

diff --git a/ChangeLog b/ChangeLog
index bbc0745..c8ca936 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2013-11-02  Mischa Jonker  <mjonker@synopsys.com>
+
+	* Makefile.am (nodist_libffi_la_SOURCES): Fix build error.
+	* Makefile.in: Rebuilt.
+
+2013-11-02  David Schneider  <david.schneider@bivab.de>
+
+	* src/arm/ffi.c: more robust argument handling for closures on arm hardfloat
+	* testsuite/libffi.call/many_mixed.c: New file.
+	* testsuite/libffi.call/cls_many_mixed_args.c: More tests.
+
 2013-11-02  Vitaly Budovski
 
 	* src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32.
diff --git a/Makefile.am b/Makefile.am
index cb078ed..e9ba8cb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -182,7 +182,7 @@ if AARCH64
 nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
 endif
 if ARC
-nodist_libffi_la_SOURCES += src/arc/sysv.S src/arc/ffi.c
+nodist_libffi_la_SOURCES += src/arc/arcompact.S src/arc/ffi.c
 endif
 if ARM
 nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
diff --git a/Makefile.in b/Makefile.in
index 348c4d8..db84a35 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -995,7 +995,7 @@ src/arc/$(am__dirstamp):
 src/arc/$(DEPDIR)/$(am__dirstamp):
 	@$(MKDIR_P) src/arc/$(DEPDIR)
 	@: > src/arc/$(DEPDIR)/$(am__dirstamp)
-src/arc/sysv.lo: src/arc/$(am__dirstamp) \
+src/arc/arcompact.lo: src/arc/$(am__dirstamp) \
 	src/arc/$(DEPDIR)/$(am__dirstamp)
 src/arc/ffi.lo: src/arc/$(am__dirstamp) \
 	src/arc/$(DEPDIR)/$(am__dirstamp)
diff --git a/src/arm/ffi.c b/src/arm/ffi.c
index 14e9d55..d52ad02 100644
--- a/src/arm/ffi.c
+++ b/src/arm/ffi.c
@@ -4,8 +4,8 @@
            Copyright (c) 2011 Anthony Green
 	   Copyright (c) 2011 Free Software Foundation
            Copyright (c) 1998, 2008, 2011  Red Hat, Inc.
-	   
-   ARM Foreign Function Interface 
+
+   ARM Foreign Function Interface
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -313,7 +313,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
   unsigned int temp;
   
   /* If the return value is a struct and we don't have a return	*/
-  /* value address then we need to make one		        */
+  /* value address then we need to make one			*/
 
   if ((rvalue == NULL) && 
       (cif->flags == FFI_TYPE_STRUCT))
@@ -489,18 +489,23 @@ ffi_prep_incoming_args_VFP(char *stack, void **rvalue,
 
           p_argv++;
           regp = tregp + z;
-          /* if regp points above the end of the register area */
+          // if we read past the last core register, make sure we have not read
+          // from the stack before and continue reading after regp
+          if(regp > eo_regp)
+            {
+            if(stack_used)
+              {
+                abort(); // we should never read past the end of the register
+                         // are if the stack is already in use
+              }
+            argp = regp;
+            }
           if(regp >= eo_regp)
             {
-              /* sanity check that we haven't read from the stack area before
-               * reaching this point */
-              FFI_ASSERT(argp <= regp);
-              FFI_ASSERT(argp == stack + 16);
-              argp = regp;
-              done_with_regs = 1;
-              stack_used = 1;
+            done_with_regs = 1;
+            stack_used = 1;
             }
-            continue;
+          continue;
           }
       }
     stack_used = 1;
@@ -773,7 +778,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
 #endif
   else
     return FFI_BAD_ABI;
-    
+
 #if FFI_EXEC_TRAMPOLINE_TABLE
   void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
   config[0] = closure;
diff --git a/testsuite/libffi.call/cls_many_mixed_args.c b/testsuite/libffi.call/cls_many_mixed_args.c
index 18cdfcc..e4b1eb1 100644
--- a/testsuite/libffi.call/cls_many_mixed_args.c
+++ b/testsuite/libffi.call/cls_many_mixed_args.c
@@ -9,7 +9,7 @@
 #include <float.h>
 #include <math.h>
 
-#define NARGS 12
+#define NARGS 16
 
 static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
 			      void* userdata __UNUSED__)
@@ -19,7 +19,7 @@ static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
   double t;
   for(i = 0; i < NARGS; i++)
     {
-    if(i == 8) 
+    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
       {
       t = *(long int *)args[i];
       CHECK(t == i+1);
@@ -33,7 +33,9 @@ static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
     }
   *(double *)resp = r;
 }
-typedef double (*cls_ret_double)(double, double, double, double, double, double, double, double, long int, double, double, double);
+typedef double (*cls_ret_double)(double, double, double, double, long int,
+double, double, double, double, long int, double, long int, double, long int,
+double, long int);
 
 int main (void)
 {
@@ -43,11 +45,11 @@ int main (void)
   ffi_type * cl_arg_types[NARGS];
   double res;
   int i;
-  double expected = 15.9;
+  double expected = 64.9;
 
   for(i = 0; i < NARGS; i++)
     {
-    if(i == 8) 
+    if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
       cl_arg_types[i] = &ffi_type_slong;
     else
       cl_arg_types[i] = &ffi_type_double;
@@ -59,8 +61,8 @@ int main (void)
 
   CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
 
-  res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 9,
-                                                                1.0, 1.1, 1.2);
+  res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
+                                 1.1, 12, 1.3, 14, 1.5, 16);
   if (abs(res - expected) < FLT_EPSILON)
     exit(0);
   else
diff --git a/testsuite/libffi.call/many_mixed.c b/testsuite/libffi.call/many_mixed.c
new file mode 100644
index 0000000..85ec36e
--- /dev/null
+++ b/testsuite/libffi.call/many_mixed.c
@@ -0,0 +1,78 @@
+/* Area:	ffi_call
+   Purpose:	Check return value double, with many arguments
+   Limitations:	none.
+   PR:		none.
+   Originator:	From the original ffitest.c  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+
+static double many(double f1,
+		  double f2,
+		  long int i1,
+		  double f3,
+		  double f4,
+		  long int i2,
+		  double f5,
+		  double f6,
+		  long int i3,
+		  double f7,
+		  double f8,
+		  long int i4,
+		  double f9,
+		  double f10,
+		  long int i5,
+		  double f11,
+		  double f12,
+		  long int i6,
+		  double f13)
+{
+  return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[19];
+  void *values[19];
+  double fa[19];
+  long int la[19];
+  double f, ff;
+  int i;
+
+  for (i = 0; i < 19; i++)
+    {
+	  if( (i - 2) % 3 == 0) {
+	    args[i] = &ffi_type_slong;
+	    la[i] = (long int) i;
+	    values[i] = &la[i];
+	  }
+	  else {
+	    args[i] = &ffi_type_double;
+	    fa[i] = (double) i;
+	    values[i] = &fa[i];
+	  }
+    }
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19,
+		       &ffi_type_double, args) == FFI_OK);
+
+    ffi_call(&cif, FFI_FN(many), &f, values);
+
+    ff =  many(fa[0], fa[1], la[2],
+               fa[3], fa[4], la[5],
+               fa[6], fa[7], la[8],
+               fa[9], fa[10], la[11],
+               fa[12], fa[13], la[14],
+               fa[15], fa[16], la[17],
+               fa[18]);
+    if (fabs(f - ff) < FLT_EPSILON)
+      exit(0);
+    else
+      abort();
+}