public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/6] Remove surplus frame from MASM function entry
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
  2012-03-22 23:26 ` [PATCH 2/6] Add kludge for missing format specifiers on MSVC Peter Rosin
  2012-03-22 23:26 ` [PATCH 6/6] Add Microsoftian variant of the cdecl ABI Peter Rosin
@ 2012-03-22 23:26 ` Peter Rosin
  2012-03-22 23:26 ` [PATCH 1/6] Put declarations before statements, C89 style Peter Rosin
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:26 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog       |    5 +++++
 src/x86/win32.S |    2 --
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2d03e59..0c0cc68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2012-03-22  Peter Rosin  <peda@lysator.liu.se>
 
+	* src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual
+	frame on function entry, MASM adds one automatically.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
 	* testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing
 	bits in the MSVC headers.
 
diff --git a/src/x86/win32.S b/src/x86/win32.S
index 47629fe..f1a1278 100644
--- a/src/x86/win32.S
+++ b/src/x86/win32.S
@@ -171,8 +171,6 @@ ca_epilogue:
 ffi_call_win32 ENDP
 
 ffi_closure_THISCALL PROC NEAR FORCEFRAME
-	push	ebp
-	mov	ebp, esp
 	sub	esp, 40
 	lea	edx, [ebp -24]
 	mov	[ebp - 12], edx	/* resp */
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/6] Add kludge for missing format specifiers on MSVC
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
@ 2012-03-22 23:26 ` Peter Rosin
  2012-03-22 23:26 ` [PATCH 6/6] Add Microsoftian variant of the cdecl ABI Peter Rosin
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:26 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog                       |    5 +++++
 testsuite/libffi.call/ffitest.h |    9 +++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 70ecba9..2d03e59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2012-03-22  Peter Rosin  <peda@lysator.liu.se>
 
+	* testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing
+	bits in the MSVC headers.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
 	* testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style
 	with no declarations after statements.
 	* testsuite/libffi.call/cls_16byte.c: Likewise.
diff --git a/testsuite/libffi.call/ffitest.h b/testsuite/libffi.call/ffitest.h
index 0e95e16..ecda068 100644
--- a/testsuite/libffi.call/ffitest.h
+++ b/testsuite/libffi.call/ffitest.h
@@ -110,6 +110,15 @@
 #endif
 #endif
 
+/* MSVC kludge.  */
+#if defined _MSC_VER
+#define PRIuPTR "lu"
+#define PRIu8 "u"
+#define PRId8 "d"
+#define PRIu64 "I64u"
+#define PRId64 "I64d"
+#endif
+
 #ifdef USING_MMAP
 static inline void *
 allocate_mmap (size_t size)
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 0/6] MSVC fixes
@ 2012-03-22 23:26 Peter Rosin
  2012-03-22 23:26 ` [PATCH 2/6] Add kludge for missing format specifiers on MSVC Peter Rosin
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:26 UTC (permalink / raw)
  To: libffi-discuss

Hi!

This series fixes a number of problems that MSVC has with libffi.

The first patches are pretty mechanic, but the last one adds a
new ABI for x86-win32.  As it happens, Microsoft and GCC does not
agree on the details of the cdecl calling convention when they
are returning structures (at least).  MS thinks that the caller
pops the hidden structure return address and GCC thinks that
the callee should do it.  And MS relies on the callee to return
the structure return address in eax, while GCC seems to not care
about that (which is pretty sane, the compiler should be able
to keep track och where it did put that structure after all).

With the patches the testsuite behaves *much* better for MSVC.
What still fails is return_uc.c (crashes, but works when running
in the debugger), struct1_win32.c, struct2_win32.c (haven't
really looked, they crash) and closure_thiscall.c (no support for
using __thiscall from C apparently). And both the C++ tests fail
(haven't looked at all).

It would be interesting to see if MSVC can call into a libffi
built by GCC and vice versa, to check if the structure return
discrepancy really is fixed.  That should be possible if I did
this right, right?

Cheers,
Peter

[PATCH 1/6] Put declarations before statements, C89 style
[PATCH 2/6] Add kludge for missing format specifiers on MSVC
[PATCH 3/6] Remove surplus frame from MASM function entry
[PATCH 4/6] Use __fastcall for MSVC
[PATCH 5/6] Translate inline assembly to MSVC format
[PATCH 6/6] Add Microsoftian variant of the cdecl ABI

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/6] Put declarations before statements, C89 style
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
                   ` (2 preceding siblings ...)
  2012-03-22 23:26 ` [PATCH 3/6] Remove surplus frame from MASM function entry Peter Rosin
@ 2012-03-22 23:26 ` Peter Rosin
  2012-03-22 23:33 ` [PATCH 4/6] Use __fastcall for MSVC Peter Rosin
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:26 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog                                          |   71 ++++++++++++++++++++
 testsuite/libffi.call/cls_12byte.c                 |    8 +-
 testsuite/libffi.call/cls_16byte.c                 |    8 +-
 testsuite/libffi.call/cls_18byte.c                 |    8 +-
 testsuite/libffi.call/cls_19byte.c                 |    8 +-
 testsuite/libffi.call/cls_1_1byte.c                |    8 +-
 testsuite/libffi.call/cls_20byte.c                 |    8 +-
 testsuite/libffi.call/cls_20byte1.c                |    8 +-
 testsuite/libffi.call/cls_24byte.c                 |   10 ++--
 testsuite/libffi.call/cls_2byte.c                  |    8 +-
 testsuite/libffi.call/cls_3_1byte.c                |    8 +-
 testsuite/libffi.call/cls_3byte1.c                 |    8 +-
 testsuite/libffi.call/cls_3byte2.c                 |    8 +-
 testsuite/libffi.call/cls_4_1byte.c                |    8 +-
 testsuite/libffi.call/cls_4byte.c                  |    8 +-
 testsuite/libffi.call/cls_5_1_byte.c               |    8 +-
 testsuite/libffi.call/cls_5byte.c                  |    8 +-
 testsuite/libffi.call/cls_64byte.c                 |   10 ++--
 testsuite/libffi.call/cls_6_1_byte.c               |    8 +-
 testsuite/libffi.call/cls_6byte.c                  |    8 +-
 testsuite/libffi.call/cls_7_1_byte.c               |    8 +-
 testsuite/libffi.call/cls_7byte.c                  |    8 +-
 testsuite/libffi.call/cls_8byte.c                  |    8 +-
 testsuite/libffi.call/cls_9byte1.c                 |    8 +-
 testsuite/libffi.call/cls_9byte2.c                 |    8 +-
 testsuite/libffi.call/cls_align_double.c           |    8 +-
 testsuite/libffi.call/cls_align_float.c            |    8 +-
 testsuite/libffi.call/cls_align_longdouble.c       |    8 +-
 testsuite/libffi.call/cls_align_longdouble_split.c |    8 +-
 .../libffi.call/cls_align_longdouble_split2.c      |    8 +-
 testsuite/libffi.call/cls_align_pointer.c          |    8 +-
 testsuite/libffi.call/cls_align_sint16.c           |    8 +-
 testsuite/libffi.call/cls_align_sint32.c           |    8 +-
 testsuite/libffi.call/cls_align_sint64.c           |    8 +-
 testsuite/libffi.call/cls_align_uint16.c           |    8 +-
 testsuite/libffi.call/cls_align_uint32.c           |    8 +-
 testsuite/libffi.call/cls_align_uint64.c           |    8 +-
 testsuite/libffi.call/cls_dbls_struct.c            |    4 +-
 testsuite/libffi.call/cls_pointer_stack.c          |    6 +-
 testsuite/libffi.call/err_bad_typedef.c            |    4 +-
 testsuite/libffi.call/huge_struct.c                |   26 ++++----
 testsuite/libffi.call/nested_struct.c              |   12 ++--
 testsuite/libffi.call/nested_struct1.c             |   14 ++--
 testsuite/libffi.call/nested_struct10.c            |   12 ++--
 testsuite/libffi.call/nested_struct2.c             |   10 ++--
 testsuite/libffi.call/nested_struct3.c             |   10 ++--
 testsuite/libffi.call/nested_struct4.c             |   10 ++--
 testsuite/libffi.call/nested_struct5.c             |   10 ++--
 testsuite/libffi.call/nested_struct6.c             |   12 ++--
 testsuite/libffi.call/nested_struct7.c             |   10 ++--
 testsuite/libffi.call/nested_struct8.c             |   12 ++--
 testsuite/libffi.call/nested_struct9.c             |   12 ++--
 testsuite/libffi.call/stret_large.c                |   10 ++--
 testsuite/libffi.call/stret_large2.c               |   10 ++--
 testsuite/libffi.call/stret_medium.c               |   10 ++--
 testsuite/libffi.call/stret_medium2.c              |   10 ++--
 testsuite/libffi.call/struct1.c                    |   12 ++--
 testsuite/libffi.call/struct1_win32.c              |   12 ++--
 testsuite/libffi.call/struct2.c                    |   10 ++--
 testsuite/libffi.call/struct2_win32.c              |   10 ++--
 testsuite/libffi.call/struct3.c                    |    9 ++-
 testsuite/libffi.call/struct4.c                    |   13 ++--
 testsuite/libffi.call/struct5.c                    |   13 ++--
 testsuite/libffi.call/struct6.c                    |   14 ++--
 testsuite/libffi.call/struct7.c                    |   14 ++--
 testsuite/libffi.call/struct8.c                    |   13 ++--
 testsuite/libffi.call/struct9.c                    |   13 ++--
 testsuite/libffi.call/testclosure.c                |    4 +-
 68 files changed, 393 insertions(+), 311 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6d35a09..70ecba9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,76 @@
 2012-03-22  Peter Rosin  <peda@lysator.liu.se>
 
+	* testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style
+	with no declarations after statements.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_dbls_struct.c: Likewise.
+	* testsuite/libffi.call/cls_pointer_stack.c: Likewise.
+	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
+	* testsuite/libffi.call/huge_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct10.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+	* testsuite/libffi.call/nested_struct5.c: Likewise.
+	* testsuite/libffi.call/nested_struct6.c: Likewise.
+	* testsuite/libffi.call/nested_struct7.c: Likewise.
+	* testsuite/libffi.call/nested_struct8.c: Likewise.
+	* testsuite/libffi.call/nested_struct9.c: Likewise.
+	* testsuite/libffi.call/stret_large.c: Likewise.
+	* testsuite/libffi.call/stret_large2.c: Likewise.
+	* testsuite/libffi.call/stret_medium.c: Likewise.
+	* testsuite/libffi.call/stret_medium2.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+	* testsuite/libffi.call/struct1_win32.c: Likewise.
+	* testsuite/libffi.call/struct2.c: Likewise.
+	* testsuite/libffi.call/struct2_win32.c: Likewise.
+	* testsuite/libffi.call/struct3.c: Likewise.
+	* testsuite/libffi.call/struct4.c: Likewise.
+	* testsuite/libffi.call/struct5.c: Likewise.
+	* testsuite/libffi.call/struct6.c: Likewise.
+	* testsuite/libffi.call/struct7.c: Likewise.
+	* testsuite/libffi.call/struct8.c: Likewise.
+	* testsuite/libffi.call/struct9.c: Likewise.
+	* testsuite/libffi.call/testclosure.c: Likewise.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
 	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_THISCALL): Use the correct
 	distance (__dis) between the call site and the destination.
 
diff --git a/testsuite/libffi.call/cls_12byte.c b/testsuite/libffi.call/cls_12byte.c
index f0a334f..ea0825d 100644
--- a/testsuite/libffi.call/cls_12byte.c
+++ b/testsuite/libffi.call/cls_12byte.c
@@ -49,15 +49,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
+  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
+  struct cls_struct_12byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_12byte h_dbl = { 7, 4, 9 };
-  struct cls_struct_12byte j_dbl = { 1, 5, 3 };
-  struct cls_struct_12byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/cls_16byte.c b/testsuite/libffi.call/cls_16byte.c
index 9b9292a..89a08a2 100644
--- a/testsuite/libffi.call/cls_16byte.c
+++ b/testsuite/libffi.call/cls_16byte.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
+  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
+  struct cls_struct_16byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
-  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
-  struct cls_struct_16byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/cls_18byte.c b/testsuite/libffi.call/cls_18byte.c
index 40c8c6d..9f75da8 100644
--- a/testsuite/libffi.call/cls_18byte.c
+++ b/testsuite/libffi.call/cls_18byte.c
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
+  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
+  struct cls_struct_18byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
-  struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
-  struct cls_struct_18byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_19byte.c b/testsuite/libffi.call/cls_19byte.c
index aa64248..278794b 100644
--- a/testsuite/libffi.call/cls_19byte.c
+++ b/testsuite/libffi.call/cls_19byte.c
@@ -57,15 +57,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
+  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
+  struct cls_struct_19byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
-  struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
-  struct cls_struct_19byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_1_1byte.c b/testsuite/libffi.call/cls_1_1byte.c
index b9402d6..82492c0 100644
--- a/testsuite/libffi.call/cls_1_1byte.c
+++ b/testsuite/libffi.call/cls_1_1byte.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_1_1byte g_dbl = { 12 };
+  struct cls_struct_1_1byte f_dbl = { 178 };
+  struct cls_struct_1_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_1_1byte g_dbl = { 12 };
-  struct cls_struct_1_1byte f_dbl = { 178 };
-  struct cls_struct_1_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = NULL;
 
diff --git a/testsuite/libffi.call/cls_20byte.c b/testsuite/libffi.call/cls_20byte.c
index 80dd7ac..3f8bb28 100644
--- a/testsuite/libffi.call/cls_20byte.c
+++ b/testsuite/libffi.call/cls_20byte.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
+  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
+  struct cls_struct_20byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
-  struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
-  struct cls_struct_20byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/cls_20byte1.c b/testsuite/libffi.call/cls_20byte1.c
index 50bcbbf..6562727 100644
--- a/testsuite/libffi.call/cls_20byte1.c
+++ b/testsuite/libffi.call/cls_20byte1.c
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
+  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
+  struct cls_struct_20byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
-  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
-  struct cls_struct_20byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/cls_24byte.c b/testsuite/libffi.call/cls_24byte.c
index 46a6eb4..1d82f6e 100644
--- a/testsuite/libffi.call/cls_24byte.c
+++ b/testsuite/libffi.call/cls_24byte.c
@@ -61,17 +61,17 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
   struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
   struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
   struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
   struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
   struct cls_struct_24byte res_dbl;
 
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/cls_2byte.c b/testsuite/libffi.call/cls_2byte.c
index 101e130..81bb0a6 100644
--- a/testsuite/libffi.call/cls_2byte.c
+++ b/testsuite/libffi.call/cls_2byte.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_2byte g_dbl = { 12, 127 };
+  struct cls_struct_2byte f_dbl = { 1, 13 };
+  struct cls_struct_2byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_2byte g_dbl = { 12, 127 };
-  struct cls_struct_2byte f_dbl = { 1, 13 };
-  struct cls_struct_2byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_3_1byte.c b/testsuite/libffi.call/cls_3_1byte.c
index fc780c3..b782746 100644
--- a/testsuite/libffi.call/cls_3_1byte.c
+++ b/testsuite/libffi.call/cls_3_1byte.c
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
+  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
+  struct cls_struct_3_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
-  struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
-  struct cls_struct_3_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_3byte1.c b/testsuite/libffi.call/cls_3byte1.c
index 5705ce3..a02c463 100644
--- a/testsuite/libffi.call/cls_3byte1.c
+++ b/testsuite/libffi.call/cls_3byte1.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3byte g_dbl = { 12, 119 };
+  struct cls_struct_3byte f_dbl = { 1, 15 };
+  struct cls_struct_3byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3byte g_dbl = { 12, 119 };
-  struct cls_struct_3byte f_dbl = { 1, 15 };
-  struct cls_struct_3byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_3byte2.c b/testsuite/libffi.call/cls_3byte2.c
index 01770a0..c7251ce 100644
--- a/testsuite/libffi.call/cls_3byte2.c
+++ b/testsuite/libffi.call/cls_3byte2.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
+  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
+  struct cls_struct_3byte_1 res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
-  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
-  struct cls_struct_3byte_1 res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_4_1byte.c b/testsuite/libffi.call/cls_4_1byte.c
index f3806d7..2d6d8b6 100644
--- a/testsuite/libffi.call/cls_4_1byte.c
+++ b/testsuite/libffi.call/cls_4_1byte.c
@@ -56,15 +56,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
+  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
+  struct cls_struct_4_1byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
-  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
-  struct cls_struct_4_1byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_4byte.c b/testsuite/libffi.call/cls_4byte.c
index a1aba3c..4ac3787 100644
--- a/testsuite/libffi.call/cls_4byte.c
+++ b/testsuite/libffi.call/cls_4byte.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_4byte g_dbl = { 127, 120 };
+  struct cls_struct_4byte f_dbl = { 12, 128 };
+  struct cls_struct_4byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_4byte g_dbl = { 127, 120 };
-  struct cls_struct_4byte f_dbl = { 12, 128 };
-  struct cls_struct_4byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_5_1_byte.c b/testsuite/libffi.call/cls_5_1_byte.c
index 2ceba3d..ad9d51c 100644
--- a/testsuite/libffi.call/cls_5_1_byte.c
+++ b/testsuite/libffi.call/cls_5_1_byte.c
@@ -58,15 +58,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_5byte.c b/testsuite/libffi.call/cls_5byte.c
index 61d595c..4e0c000 100644
--- a/testsuite/libffi.call/cls_5byte.c
+++ b/testsuite/libffi.call/cls_5byte.c
@@ -53,15 +53,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
+  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
+  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_5byte g_dbl = { 127, 120, 1 };
-  struct cls_struct_5byte f_dbl = { 12, 128, 9 };
-  struct cls_struct_5byte res_dbl = { 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_64byte.c b/testsuite/libffi.call/cls_64byte.c
index 576ebe0..a55edc2 100644
--- a/testsuite/libffi.call/cls_64byte.c
+++ b/testsuite/libffi.call/cls_64byte.c
@@ -66,17 +66,17 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
-  cls_struct_type.size = 0;
-  cls_struct_type.alignment = 0;
-  cls_struct_type.type = FFI_TYPE_STRUCT;
-  cls_struct_type.elements = cls_struct_fields;
-
   struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
   struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
   struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
   struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
   struct cls_struct_64byte res_dbl;
 
+  cls_struct_type.size = 0;
+  cls_struct_type.alignment = 0;
+  cls_struct_type.type = FFI_TYPE_STRUCT;
+  cls_struct_type.elements = cls_struct_fields;
+
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/cls_6_1_byte.c b/testsuite/libffi.call/cls_6_1_byte.c
index 9f2eff6..b4dcdba 100644
--- a/testsuite/libffi.call/cls_6_1_byte.c
+++ b/testsuite/libffi.call/cls_6_1_byte.c
@@ -60,15 +60,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
+  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
-  struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_6byte.c b/testsuite/libffi.call/cls_6byte.c
index 73257b0..7406780 100644
--- a/testsuite/libffi.call/cls_6byte.c
+++ b/testsuite/libffi.call/cls_6byte.c
@@ -56,15 +56,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
+  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
+  struct cls_struct_6byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
-  struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
-  struct cls_struct_6byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_7_1_byte.c b/testsuite/libffi.call/cls_7_1_byte.c
index 50d09c9..14a7e96 100644
--- a/testsuite/libffi.call/cls_7_1_byte.c
+++ b/testsuite/libffi.call/cls_7_1_byte.c
@@ -62,15 +62,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
+  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
-  struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_7byte.c b/testsuite/libffi.call/cls_7byte.c
index f5c0000..1645cc6 100644
--- a/testsuite/libffi.call/cls_7byte.c
+++ b/testsuite/libffi.call/cls_7byte.c
@@ -55,15 +55,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
+  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
+  struct cls_struct_7byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
-  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
-  struct cls_struct_7byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ushort;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_8byte.c b/testsuite/libffi.call/cls_8byte.c
index 4aa99d1..f6c1ea5 100644
--- a/testsuite/libffi.call/cls_8byte.c
+++ b/testsuite/libffi.call/cls_8byte.c
@@ -49,15 +49,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_8byte g_dbl = { 1, 2.0 };
+  struct cls_struct_8byte f_dbl = { 4, 5.0 };
+  struct cls_struct_8byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_8byte g_dbl = { 1, 2.0 };
-  struct cls_struct_8byte f_dbl = { 4, 5.0 };
-  struct cls_struct_8byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_9byte1.c b/testsuite/libffi.call/cls_9byte1.c
index cc5e9d6..0b85722 100644
--- a/testsuite/libffi.call/cls_9byte1.c
+++ b/testsuite/libffi.call/cls_9byte1.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_9byte h_dbl = { 7, 8.0};
+  struct cls_struct_9byte j_dbl = { 1, 9.0};
+  struct cls_struct_9byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_9byte h_dbl = { 7, 8.0};
-  struct cls_struct_9byte j_dbl = { 1, 9.0};
-  struct cls_struct_9byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_sint;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_9byte2.c b/testsuite/libffi.call/cls_9byte2.c
index 5c0ba0d..edf991d 100644
--- a/testsuite/libffi.call/cls_9byte2.c
+++ b/testsuite/libffi.call/cls_9byte2.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[3];
 
+  struct cls_struct_9byte h_dbl = { 7.0, 8};
+  struct cls_struct_9byte j_dbl = { 1.0, 9};
+  struct cls_struct_9byte res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_9byte h_dbl = { 7.0, 8};
-  struct cls_struct_9byte j_dbl = { 1.0, 9};
-  struct cls_struct_9byte res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/cls_align_double.c b/testsuite/libffi.call/cls_align_double.c
index 22b94d5..aad5f3c 100644
--- a/testsuite/libffi.call/cls_align_double.c
+++ b/testsuite/libffi.call/cls_align_double.c
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_double;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_float.c b/testsuite/libffi.call/cls_align_float.c
index 62637f2..37e0855 100644
--- a/testsuite/libffi.call/cls_align_float.c
+++ b/testsuite/libffi.call/cls_align_float.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_longdouble.c b/testsuite/libffi.call/cls_align_longdouble.c
index af38060..b3322d8 100644
--- a/testsuite/libffi.call/cls_align_longdouble.c
+++ b/testsuite/libffi.call/cls_align_longdouble.c
@@ -51,15 +51,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_longdouble;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_longdouble_split.c b/testsuite/libffi.call/cls_align_longdouble_split.c
index a3732bd..15f9365 100644
--- a/testsuite/libffi.call/cls_align_longdouble_split.c
+++ b/testsuite/libffi.call/cls_align_longdouble_split.c
@@ -87,15 +87,15 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[3];
 
+	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+	struct cls_struct_align res_dbl;
+
 	cls_struct_type.size = 0;
 	cls_struct_type.alignment = 0;
 	cls_struct_type.type = FFI_TYPE_STRUCT;
 	cls_struct_type.elements = cls_struct_fields;
 
-	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-	struct cls_struct_align res_dbl;
-
 	cls_struct_fields[0] = &ffi_type_longdouble;
 	cls_struct_fields[1] = &ffi_type_longdouble;
 	cls_struct_fields[2] = &ffi_type_longdouble;
diff --git a/testsuite/libffi.call/cls_align_longdouble_split2.c b/testsuite/libffi.call/cls_align_longdouble_split2.c
index 63a0f76..ca1c356 100644
--- a/testsuite/libffi.call/cls_align_longdouble_split2.c
+++ b/testsuite/libffi.call/cls_align_longdouble_split2.c
@@ -67,15 +67,15 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[3];
 
+	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+	struct cls_struct_align res_dbl;
+
 	cls_struct_type.size = 0;
 	cls_struct_type.alignment = 0;
 	cls_struct_type.type = FFI_TYPE_STRUCT;
 	cls_struct_type.elements = cls_struct_fields;
 
-	struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
-	struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
-	struct cls_struct_align res_dbl;
-
 	cls_struct_fields[0] = &ffi_type_longdouble;
 	cls_struct_fields[1] = &ffi_type_longdouble;
 	cls_struct_fields[2] = &ffi_type_longdouble;
diff --git a/testsuite/libffi.call/cls_align_pointer.c b/testsuite/libffi.call/cls_align_pointer.c
index cbc4f95..8fbf36a 100644
--- a/testsuite/libffi.call/cls_align_pointer.c
+++ b/testsuite/libffi.call/cls_align_pointer.c
@@ -54,15 +54,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
+  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
-  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_pointer;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_sint16.c b/testsuite/libffi.call/cls_align_sint16.c
index 383ea41..039b874 100644
--- a/testsuite/libffi.call/cls_align_sint16.c
+++ b/testsuite/libffi.call/cls_align_sint16.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sshort;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_sint32.c b/testsuite/libffi.call/cls_align_sint32.c
index 705d78c..c96c6d1 100644
--- a/testsuite/libffi.call/cls_align_sint32.c
+++ b/testsuite/libffi.call/cls_align_sint32.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sint;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_sint64.c b/testsuite/libffi.call/cls_align_sint64.c
index 31d53af..9aa7bdd 100644
--- a/testsuite/libffi.call/cls_align_sint64.c
+++ b/testsuite/libffi.call/cls_align_sint64.c
@@ -51,15 +51,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_sint64;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_uint16.c b/testsuite/libffi.call/cls_align_uint16.c
index cb6b748..97620b7 100644
--- a/testsuite/libffi.call/cls_align_uint16.c
+++ b/testsuite/libffi.call/cls_align_uint16.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_ushort;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_uint32.c b/testsuite/libffi.call/cls_align_uint32.c
index e453d3e..5766fad 100644
--- a/testsuite/libffi.call/cls_align_uint32.c
+++ b/testsuite/libffi.call/cls_align_uint32.c
@@ -50,15 +50,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_align_uint64.c b/testsuite/libffi.call/cls_align_uint64.c
index 495c79f..a52cb89 100644
--- a/testsuite/libffi.call/cls_align_uint64.c
+++ b/testsuite/libffi.call/cls_align_uint64.c
@@ -52,15 +52,15 @@ int main (void)
   ffi_type cls_struct_type;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_align g_dbl = { 12, 4951, 127 };
+  struct cls_struct_align f_dbl = { 1, 9320, 13 };
+  struct cls_struct_align res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
   cls_struct_type.elements = cls_struct_fields;
 
-  struct cls_struct_align g_dbl = { 12, 4951, 127 };
-  struct cls_struct_align f_dbl = { 1, 9320, 13 };
-  struct cls_struct_align res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint64;
   cls_struct_fields[2] = &ffi_type_uchar;
diff --git a/testsuite/libffi.call/cls_dbls_struct.c b/testsuite/libffi.call/cls_dbls_struct.c
index 660dabb..d663791 100644
--- a/testsuite/libffi.call/cls_dbls_struct.c
+++ b/testsuite/libffi.call/cls_dbls_struct.c
@@ -37,6 +37,8 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
 	ffi_type	ts1_type;
 	ffi_type*	ts1_type_elements[4];
 
+	Dbls arg = { 1.0, 2.0 };
+
 	ts1_type.size = 0;
 	ts1_type.alignment = 0;
 	ts1_type.type = FFI_TYPE_STRUCT;
@@ -48,8 +50,6 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
 
 	cl_arg_types[0] = &ts1_type;
 
-	Dbls arg = { 1.0, 2.0 };
-
 	/* Initialize the cif */
 	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
 				 &ffi_type_void, cl_arg_types) == FFI_OK);
diff --git a/testsuite/libffi.call/cls_pointer_stack.c b/testsuite/libffi.call/cls_pointer_stack.c
index d631cf8..e31139e 100644
--- a/testsuite/libffi.call/cls_pointer_stack.c
+++ b/testsuite/libffi.call/cls_pointer_stack.c
@@ -28,11 +28,12 @@ void* cls_pointer_fn2(void* a1, void* a2)
 	char		trample6	= trample4 + ((char*)&a2)[1];
 	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
 	char		trample8	= trample6 + trample2;
+	void*		result;
 
 	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
 		trample5, trample6, trample7, trample8);
 
-	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
+	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
 
 	printf("0x%08x 0x%08x: 0x%08x\n", 
 	       (unsigned int)(uintptr_t) a1,
@@ -52,11 +53,12 @@ void* cls_pointer_fn1(void* a1, void* a2)
 	char		trample6	= trample4 + ((char*)&a2)[1];
 	long double	trample7	= (intptr_t)trample5 + (intptr_t)trample1;
 	char		trample8	= trample6 + trample2;
+	void*		result;
 
 	dummyVar	= dummy_func(trample1, trample2, trample3, trample4,
 		trample5, trample6, trample7, trample8);
 
-	void*	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
+	result	= (void*)((intptr_t)a1 + (intptr_t)a2);
 
 	printf("0x%08x 0x%08x: 0x%08x\n",
                (unsigned int)(intptr_t) a1,
diff --git a/testsuite/libffi.call/err_bad_typedef.c b/testsuite/libffi.call/err_bad_typedef.c
index 2539273..bf60161 100644
--- a/testsuite/libffi.call/err_bad_typedef.c
+++ b/testsuite/libffi.call/err_bad_typedef.c
@@ -13,10 +13,10 @@ int main (void)
 	ffi_cif cif;
 	ffi_type* arg_types[1];
 
-	arg_types[0] = NULL;
-
 	ffi_type	badType	= ffi_type_void;
 
+	arg_types[0] = NULL;
+
 	badType.size = 0;
 
 	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
diff --git a/testsuite/libffi.call/huge_struct.c b/testsuite/libffi.call/huge_struct.c
index e04e1d5..380fedf 100644
--- a/testsuite/libffi.call/huge_struct.c
+++ b/testsuite/libffi.call/huge_struct.c
@@ -229,6 +229,19 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
 	ffi_type*	st_fields[51];
 	BigStruct	retVal;
 
+	uint8_t		ui8		= 1;
+	int8_t		si8		= 2;
+	uint16_t	ui16	= 3;
+	int16_t		si16	= 4;
+	uint32_t	ui32	= 5;
+	int32_t		si32	= 6;
+	uint64_t	ui64	= 7;
+	int64_t		si64	= 8;
+	float		f		= 9;
+	double		d		= 10;
+	long double	ld		= 11;
+	char*		p		= (char*)0x12345678;
+
 	memset (&retVal, 0, sizeof(retVal));
 
 	ret_struct_type.size = 0;
@@ -251,19 +264,6 @@ main(int argc __UNUSED__, const char** argv __UNUSED__)
 
 	st_fields[50] = NULL;
 
-	uint8_t		ui8		= 1;
-	int8_t		si8		= 2;
-	uint16_t	ui16	= 3;
-	int16_t		si16	= 4;
-	uint32_t	ui32	= 5;
-	int32_t		si32	= 6;
-	uint64_t	ui64	= 7;
-	int64_t		si64	= 8;
-	float		f		= 9;
-	double		d		= 10;
-	long double	ld		= 11;
-	char*		p		= (char*)0x12345678;
-
 	argTypes[0]		= argTypes[12]	= argTypes[24]	= argTypes[36]	= argTypes[48]	= &ffi_type_uint8;
 	argValues[0]	= argValues[12]	= argValues[24]	= argValues[36]	= argValues[48]	= &ui8;
 	argTypes[1]		= argTypes[13]	= argTypes[25]	= argTypes[37]	= argTypes[49]	= &ffi_type_sint8;
diff --git a/testsuite/libffi.call/nested_struct.c b/testsuite/libffi.call/nested_struct.c
index 8aa527e..c15e3a0 100644
--- a/testsuite/libffi.call/nested_struct.c
+++ b/testsuite/libffi.call/nested_struct.c
@@ -77,6 +77,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+				      {3, 1.0, 8.0}};
+  struct cls_struct_combined res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -92,12 +98,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-				      {3, 1.0, 8.0}};
-  struct cls_struct_combined res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/nested_struct1.c b/testsuite/libffi.call/nested_struct1.c
index 2a9f515..1087f7b 100644
--- a/testsuite/libffi.call/nested_struct1.c
+++ b/testsuite/libffi.call/nested_struct1.c
@@ -81,6 +81,13 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
+  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
+  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
+				      {3, 1.0, 8.0}};
+  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
+  struct cls_struct_combined res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -96,13 +103,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
-  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
-  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
-				      {3, 1.0, 8.0}};
-  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
-  struct cls_struct_combined res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_float;
   cls_struct_fields[2] = &ffi_type_sint;
diff --git a/testsuite/libffi.call/nested_struct10.c b/testsuite/libffi.call/nested_struct10.c
index d6a718b..34a74e7 100644
--- a/testsuite/libffi.call/nested_struct10.c
+++ b/testsuite/libffi.call/nested_struct10.c
@@ -67,6 +67,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = { 99, {12LL , 127}, 255};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -82,12 +88,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = { 99, {12LL , 127}, 255};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct2.c b/testsuite/libffi.call/nested_struct2.c
index de1584c..69268cd 100644
--- a/testsuite/libffi.call/nested_struct2.c
+++ b/testsuite/libffi.call/nested_struct2.c
@@ -57,6 +57,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1, 7};
+  struct B f_dbl = {{12 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -67,11 +72,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1, 7};
-  struct B f_dbl = {{12 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_ulong;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct3.c b/testsuite/libffi.call/nested_struct3.c
index 58aa853..ab18cad 100644
--- a/testsuite/libffi.call/nested_struct3.c
+++ b/testsuite/libffi.call/nested_struct3.c
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct4.c b/testsuite/libffi.call/nested_struct4.c
index 98e491e..2ffb4d6 100644
--- a/testsuite/libffi.call/nested_struct4.c
+++ b/testsuite/libffi.call/nested_struct4.c
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct5.c b/testsuite/libffi.call/nested_struct5.c
index d8e3537..6c79845 100644
--- a/testsuite/libffi.call/nested_struct5.c
+++ b/testsuite/libffi.call/nested_struct5.c
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_longdouble;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct6.c b/testsuite/libffi.call/nested_struct6.c
index 2f2b25a..59d3579 100644
--- a/testsuite/libffi.call/nested_struct6.c
+++ b/testsuite/libffi.call/nested_struct6.c
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1.0, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1.0, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_double;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct7.c b/testsuite/libffi.call/nested_struct7.c
index 14c7023..27595e6 100644
--- a/testsuite/libffi.call/nested_struct7.c
+++ b/testsuite/libffi.call/nested_struct7.c
@@ -58,6 +58,11 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1;
   ffi_type* dbl_arg_types[3];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12.0 , 127}, 99};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -68,11 +73,6 @@ int main (void)
   cls_struct_type1.type = FFI_TYPE_STRUCT;
   cls_struct_type1.elements = cls_struct_fields1;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12.0 , 127}, 99};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct8.c b/testsuite/libffi.call/nested_struct8.c
index bb77ead..0e6c682 100644
--- a/testsuite/libffi.call/nested_struct8.c
+++ b/testsuite/libffi.call/nested_struct8.c
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1LL, 7};
+  struct B f_dbl = {{12LL , 127}, 99};
+  struct C g_dbl = { 2LL, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1LL, 7};
-  struct B f_dbl = {{12LL , 127}, 99};
-  struct C g_dbl = { 2LL, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uint64;
   cls_struct_fields[1] = &ffi_type_uchar;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/nested_struct9.c b/testsuite/libffi.call/nested_struct9.c
index e9f541c..5f7ac67 100644
--- a/testsuite/libffi.call/nested_struct9.c
+++ b/testsuite/libffi.call/nested_struct9.c
@@ -66,6 +66,12 @@ int main (void)
   ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
   ffi_type* dbl_arg_types[4];
 
+  struct A e_dbl = { 1, 7LL};
+  struct B f_dbl = {{12.0 , 127}, 99};
+  struct C g_dbl = { 2, 9};
+
+  struct B res_dbl;
+
   cls_struct_type.size = 0;
   cls_struct_type.alignment = 0;
   cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -81,12 +87,6 @@ int main (void)
   cls_struct_type2.type = FFI_TYPE_STRUCT;
   cls_struct_type2.elements = cls_struct_fields2;
 
-  struct A e_dbl = { 1, 7LL};
-  struct B f_dbl = {{12.0 , 127}, 99};
-  struct C g_dbl = { 2, 9};
-
-  struct B res_dbl;
-
   cls_struct_fields[0] = &ffi_type_uchar;
   cls_struct_fields[1] = &ffi_type_uint64;
   cls_struct_fields[2] = NULL;
diff --git a/testsuite/libffi.call/stret_large.c b/testsuite/libffi.call/stret_large.c
index 23a93b9..f32938c 100644
--- a/testsuite/libffi.call/stret_large.c
+++ b/testsuite/libffi.call/stret_large.c
@@ -82,17 +82,17 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[5];
 
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
 	struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
 	struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
 	struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
 	struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
 	struct_108byte res_dbl;
 
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
 	cls_struct_fields[0] = &ffi_type_double;
 	cls_struct_fields[1] = &ffi_type_double;
 	cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/stret_large2.c b/testsuite/libffi.call/stret_large2.c
index e2599d2..3b0ef9a 100644
--- a/testsuite/libffi.call/stret_large2.c
+++ b/testsuite/libffi.call/stret_large2.c
@@ -84,17 +84,17 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[5];
 
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
 	struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
 	struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
 	struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
 	struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
 	struct_116byte res_dbl;
 
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
 	cls_struct_fields[0] = &ffi_type_double;
 	cls_struct_fields[1] = &ffi_type_double;
 	cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/stret_medium.c b/testsuite/libffi.call/stret_medium.c
index 1fc6a9e..973ee02 100644
--- a/testsuite/libffi.call/stret_medium.c
+++ b/testsuite/libffi.call/stret_medium.c
@@ -68,17 +68,17 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[5];
 
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
 	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
 	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
 	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
 	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
 	struct_72byte res_dbl;
 
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
 	cls_struct_fields[0] = &ffi_type_double;
 	cls_struct_fields[1] = &ffi_type_double;
 	cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/stret_medium2.c b/testsuite/libffi.call/stret_medium2.c
index cb2f2fb..84323d1 100644
--- a/testsuite/libffi.call/stret_medium2.c
+++ b/testsuite/libffi.call/stret_medium2.c
@@ -69,17 +69,17 @@ int main (void)
 	ffi_type cls_struct_type;
 	ffi_type* dbl_arg_types[5];
 
-	cls_struct_type.size = 0;
-	cls_struct_type.alignment = 0;
-	cls_struct_type.type = FFI_TYPE_STRUCT;
-	cls_struct_type.elements = cls_struct_fields;
-
 	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
 	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
 	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
 	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
 	struct_72byte res_dbl;
 
+	cls_struct_type.size = 0;
+	cls_struct_type.alignment = 0;
+	cls_struct_type.type = FFI_TYPE_STRUCT;
+	cls_struct_type.elements = cls_struct_fields;
+
 	cls_struct_fields[0] = &ffi_type_double;
 	cls_struct_fields[1] = &ffi_type_double;
 	cls_struct_fields[2] = &ffi_type_double;
diff --git a/testsuite/libffi.call/struct1.c b/testsuite/libffi.call/struct1.c
index ea76c85..bfc23f6 100644
--- a/testsuite/libffi.call/struct1.c
+++ b/testsuite/libffi.call/struct1.c
@@ -30,6 +30,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts1_type;
   ffi_type *ts1_type_elements[4];
+
+  test_structure_1 ts1_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result =
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+
   ts1_type.size = 0;
   ts1_type.alignment = 0;
   ts1_type.type = FFI_TYPE_STRUCT;
@@ -39,11 +46,6 @@ int main (void)
   ts1_type_elements[2] = &ffi_type_uint;
   ts1_type_elements[3] = NULL;
   
-  test_structure_1 ts1_arg;
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_1 *ts1_result = 
-    (test_structure_1 *) malloc (sizeof(test_structure_1));
-  
   args[0] = &ts1_type;
   values[0] = &ts1_arg;
   
diff --git a/testsuite/libffi.call/struct1_win32.c b/testsuite/libffi.call/struct1_win32.c
index 4a7eb94..a97e981 100644
--- a/testsuite/libffi.call/struct1_win32.c
+++ b/testsuite/libffi.call/struct1_win32.c
@@ -30,6 +30,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts1_type;
   ffi_type *ts1_type_elements[4];
+
+  test_structure_1 ts1_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_1 *ts1_result =
+    (test_structure_1 *) malloc (sizeof(test_structure_1));
+
   ts1_type.size = 0;
   ts1_type.alignment = 0;
   ts1_type.type = FFI_TYPE_STRUCT;
@@ -39,11 +46,6 @@ int main (void)
   ts1_type_elements[2] = &ffi_type_uint;
   ts1_type_elements[3] = NULL;
   
-  test_structure_1 ts1_arg;
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_1 *ts1_result = 
-    (test_structure_1 *) malloc (sizeof(test_structure_1));
-  
   args[0] = &ts1_type;
   values[0] = &ts1_arg;
   
diff --git a/testsuite/libffi.call/struct2.c b/testsuite/libffi.call/struct2.c
index 14bc9fd..d85385e 100644
--- a/testsuite/libffi.call/struct2.c
+++ b/testsuite/libffi.call/struct2.c
@@ -29,6 +29,11 @@ int main (void)
   test_structure_2 ts2_arg;
   ffi_type ts2_type;
   ffi_type *ts2_type_elements[3];
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_2 *ts2_result =
+    (test_structure_2 *) malloc (sizeof(test_structure_2));
+
   ts2_type.size = 0;
   ts2_type.alignment = 0;
   ts2_type.type = FFI_TYPE_STRUCT;
@@ -37,11 +42,6 @@ int main (void)
   ts2_type_elements[1] = &ffi_type_double;
   ts2_type_elements[2] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_2 *ts2_result = 
-    (test_structure_2 *) malloc (sizeof(test_structure_2));
-  
   args[0] = &ts2_type;
   values[0] = &ts2_arg;
   
diff --git a/testsuite/libffi.call/struct2_win32.c b/testsuite/libffi.call/struct2_win32.c
index 2bfbdc5..f4505be 100644
--- a/testsuite/libffi.call/struct2_win32.c
+++ b/testsuite/libffi.call/struct2_win32.c
@@ -29,6 +29,11 @@ int main (void)
   test_structure_2 ts2_arg;
   ffi_type ts2_type;
   ffi_type *ts2_type_elements[3];
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_2 *ts2_result =
+    (test_structure_2 *) malloc (sizeof(test_structure_2));
+
   ts2_type.size = 0;
   ts2_type.alignment = 0;
   ts2_type.type = FFI_TYPE_STRUCT;
@@ -37,11 +42,6 @@ int main (void)
   ts2_type_elements[1] = &ffi_type_double;
   ts2_type_elements[2] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_2 *ts2_result = 
-    (test_structure_2 *) malloc (sizeof(test_structure_2));
-  
   args[0] = &ts2_type;
   values[0] = &ts2_arg;
   
diff --git a/testsuite/libffi.call/struct3.c b/testsuite/libffi.call/struct3.c
index e0bb09b..de883c2 100644
--- a/testsuite/libffi.call/struct3.c
+++ b/testsuite/libffi.call/struct3.c
@@ -27,6 +27,11 @@ int main (void)
   int compare_value;
   ffi_type ts3_type;
   ffi_type *ts3_type_elements[2];
+
+  test_structure_3 ts3_arg;
+  test_structure_3 *ts3_result =
+    (test_structure_3 *) malloc (sizeof(test_structure_3));
+
   ts3_type.size = 0;
   ts3_type.alignment = 0;
   ts3_type.type = FFI_TYPE_STRUCT;
@@ -34,10 +39,6 @@ int main (void)
   ts3_type_elements[0] = &ffi_type_sint;
   ts3_type_elements[1] = NULL;
 
-  test_structure_3 ts3_arg;
-  test_structure_3 *ts3_result = 
-    (test_structure_3 *) malloc (sizeof(test_structure_3));
-  
   args[0] = &ts3_type;
   values[0] = &ts3_arg;
   
diff --git a/testsuite/libffi.call/struct4.c b/testsuite/libffi.call/struct4.c
index 0ad0a83..48e0349 100644
--- a/testsuite/libffi.call/struct4.c
+++ b/testsuite/libffi.call/struct4.c
@@ -28,21 +28,22 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts4_type;
   ffi_type *ts4_type_elements[4];  
+
+  test_structure_4 ts4_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_4 *ts4_result =
+    (test_structure_4 *) malloc (sizeof(test_structure_4));
+
   ts4_type.size = 0;
   ts4_type.alignment = 0;
   ts4_type.type = FFI_TYPE_STRUCT;
-  test_structure_4 ts4_arg;
   ts4_type.elements = ts4_type_elements;
   ts4_type_elements[0] = &ffi_type_uint;
   ts4_type_elements[1] = &ffi_type_uint;
   ts4_type_elements[2] = &ffi_type_uint;
   ts4_type_elements[3] = NULL;
 
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_4 *ts4_result = 
-    (test_structure_4 *) malloc (sizeof(test_structure_4));
-  
   args[0] = &ts4_type;
   values[0] = &ts4_arg;
   
diff --git a/testsuite/libffi.call/struct5.c b/testsuite/libffi.call/struct5.c
index c03cc97..28b1f0c 100644
--- a/testsuite/libffi.call/struct5.c
+++ b/testsuite/libffi.call/struct5.c
@@ -27,6 +27,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts5_type;
   ffi_type *ts5_type_elements[3];
+
+  test_structure_5 ts5_arg1, ts5_arg2;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_5 *ts5_result =
+    (test_structure_5 *) malloc (sizeof(test_structure_5));
+
   ts5_type.size = 0;
   ts5_type.alignment = 0;
   ts5_type.type = FFI_TYPE_STRUCT;
@@ -35,12 +42,6 @@ int main (void)
   ts5_type_elements[1] = &ffi_type_schar;
   ts5_type_elements[2] = NULL;
 
-  test_structure_5 ts5_arg1, ts5_arg2;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_5 *ts5_result = 
-    (test_structure_5 *) malloc (sizeof(test_structure_5));
-  
   args[0] = &ts5_type;
   args[1] = &ts5_type;
   values[0] = &ts5_arg1;
diff --git a/testsuite/libffi.call/struct6.c b/testsuite/libffi.call/struct6.c
index 83db9af..0e26746 100644
--- a/testsuite/libffi.call/struct6.c
+++ b/testsuite/libffi.call/struct6.c
@@ -27,6 +27,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts6_type;
   ffi_type *ts6_type_elements[3];
+
+  test_structure_6 ts6_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_6 *ts6_result =
+    (test_structure_6 *) malloc (sizeof(test_structure_6));
+
   ts6_type.size = 0;
   ts6_type.alignment = 0;
   ts6_type.type = FFI_TYPE_STRUCT;
@@ -35,13 +42,6 @@ int main (void)
   ts6_type_elements[1] = &ffi_type_double;
   ts6_type_elements[2] = NULL;
 
-
-  test_structure_6 ts6_arg;
-
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_6 *ts6_result = 
-    (test_structure_6 *) malloc (sizeof(test_structure_6));
-  
   args[0] = &ts6_type;
   values[0] = &ts6_arg;
 
diff --git a/testsuite/libffi.call/struct7.c b/testsuite/libffi.call/struct7.c
index 58aac4c..8f2bbfd 100644
--- a/testsuite/libffi.call/struct7.c
+++ b/testsuite/libffi.call/struct7.c
@@ -29,6 +29,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts7_type;
   ffi_type *ts7_type_elements[4];
+
+  test_structure_7 ts7_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_7 *ts7_result =
+    (test_structure_7 *) malloc (sizeof(test_structure_7));
+
   ts7_type.size = 0;
   ts7_type.alignment = 0;
   ts7_type.type = FFI_TYPE_STRUCT;
@@ -38,13 +45,6 @@ int main (void)
   ts7_type_elements[2] = &ffi_type_double;
   ts7_type_elements[3] = NULL;
 
-
-  test_structure_7 ts7_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_7 *ts7_result = 
-    (test_structure_7 *) malloc (sizeof(test_structure_7));
-  
   args[0] = &ts7_type;
   values[0] = &ts7_arg;
   
diff --git a/testsuite/libffi.call/struct8.c b/testsuite/libffi.call/struct8.c
index c773ac7..266e1f0 100644
--- a/testsuite/libffi.call/struct8.c
+++ b/testsuite/libffi.call/struct8.c
@@ -31,6 +31,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts8_type;
   ffi_type *ts8_type_elements[5];
+
+  test_structure_8 ts8_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_8 *ts8_result =
+    (test_structure_8 *) malloc (sizeof(test_structure_8));
+
   ts8_type.size = 0;
   ts8_type.alignment = 0;
   ts8_type.type = FFI_TYPE_STRUCT;
@@ -41,12 +48,6 @@ int main (void)
   ts8_type_elements[3] = &ffi_type_float;
   ts8_type_elements[4] = NULL;
 
-  test_structure_8 ts8_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_8 *ts8_result = 
-    (test_structure_8 *) malloc (sizeof(test_structure_8));
-  
   args[0] = &ts8_type;
   values[0] = &ts8_arg;
   
diff --git a/testsuite/libffi.call/struct9.c b/testsuite/libffi.call/struct9.c
index f30091f..efeb716 100644
--- a/testsuite/libffi.call/struct9.c
+++ b/testsuite/libffi.call/struct9.c
@@ -28,6 +28,13 @@ int main (void)
   void *values[MAX_ARGS];
   ffi_type ts9_type;
   ffi_type *ts9_type_elements[3];
+
+  test_structure_9 ts9_arg;
+
+  /* This is a hack to get a properly aligned result buffer */
+  test_structure_9 *ts9_result =
+    (test_structure_9 *) malloc (sizeof(test_structure_9));
+
   ts9_type.size = 0;
   ts9_type.alignment = 0;
   ts9_type.type = FFI_TYPE_STRUCT;
@@ -36,12 +43,6 @@ int main (void)
   ts9_type_elements[1] = &ffi_type_sint;
   ts9_type_elements[2] = NULL;
 
-  test_structure_9 ts9_arg;
-  
-  /* This is a hack to get a properly aligned result buffer */
-  test_structure_9 *ts9_result = 
-    (test_structure_9 *) malloc (sizeof(test_structure_9));
-  
   args[0] = &ts9_type;
   values[0] = &ts9_arg;
   
diff --git a/testsuite/libffi.call/testclosure.c b/testsuite/libffi.call/testclosure.c
index 161cc89..ca31056 100644
--- a/testsuite/libffi.call/testclosure.c
+++ b/testsuite/libffi.call/testclosure.c
@@ -43,13 +43,13 @@ int main (void)
   ffi_type cls_struct_type0;
   ffi_type* dbl_arg_types[5];
 
+  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
+
   cls_struct_type0.size = 0;
   cls_struct_type0.alignment = 0;
   cls_struct_type0.type = FFI_TYPE_STRUCT;
   cls_struct_type0.elements = cls_struct_fields0;
 
-  struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
-
   cls_struct_fields0[0] = &ffi_type_float;
   cls_struct_fields0[1] = &ffi_type_float;
   cls_struct_fields0[2] = &ffi_type_float;
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 6/6] Add Microsoftian variant of the cdecl ABI
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
  2012-03-22 23:26 ` [PATCH 2/6] Add kludge for missing format specifiers on MSVC Peter Rosin
@ 2012-03-22 23:26 ` Peter Rosin
  2012-03-29 18:21   ` [PATCH 6/6 try 2] " Peter Rosin
  2012-03-22 23:26 ` [PATCH 3/6] Remove surplus frame from MASM function entry Peter Rosin
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:26 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog           |   19 +++++++++++++++++++
 src/x86/ffi.c       |   27 +++++++++++++++++++++------
 src/x86/ffitarget.h |    7 ++++++-
 src/x86/win32.S     |   18 ++++++++++++++++++
 4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7e4a68f..d4a3c86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2012-03-22  Peter Rosin  <peda@lysator.liu.se>
 
+	* src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and
+	make it the default for MSVC.
+	(FFI_TYPE_MS_STRUCT): New structure return convention.
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure
+	return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT
+	instead of an ordinary FFI_TYPE_STRUCT.
+	(ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_call): Likewise.
+	(ffi_prep_incoming_args_SYSV): Likewise.
+	(ffi_raw_call): Likewise.
+	(ffi_prep_closure_loc): Thread FFI_MS_CDECL as FFI_SYSV.
+	* src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT,
+	return a pointer to the result structure in eax and don't pop
+	that pointer from the stack, the caller takes care of it.
+	(ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_closure_raw_SYSV): Likewise.
+
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
 	* testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline
 	assembly version with Intel syntax.
 	* testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise.
diff --git a/src/x86/ffi.c b/src/x86/ffi.c
index ea5a83c..8675182 100644
--- a/src/x86/ffi.c
+++ b/src/x86/ffi.c
@@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
 
   argp = stack;
 
-  if (ecif->cif->flags == FFI_TYPE_STRUCT
+  if ((ecif->cif->flags == FFI_TYPE_STRUCT
+       || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
 #ifdef X86_WIN64
       && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
           && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
@@ -279,7 +280,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
       else
 #endif
         {
-          cif->flags = FFI_TYPE_STRUCT;
+          if (cif->abi == FFI_MS_CDECL)
+            cif->flags = FFI_TYPE_MS_STRUCT;
+          else
+            cif->flags = FFI_TYPE_STRUCT;
           /* allocate space for return value pointer */
           cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
         }
@@ -349,7 +353,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
     }
 #else
   if (rvalue == NULL
-      && cif->flags == FFI_TYPE_STRUCT)
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -368,6 +373,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 #elif defined(X86_WIN32)
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
 		     ecif.rvalue, fn);
       break;
@@ -511,7 +517,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
     argp += sizeof(void *);
   }
 #else
-  if ( cif->flags == FFI_TYPE_STRUCT ) {
+  if ( cif->flags == FFI_TYPE_STRUCT
+       || cif->flags == FFI_TYPE_MS_STRUCT ) {
     *rvalue = *(void **) argp;
     argp += sizeof(void *);
   }
@@ -671,6 +678,12 @@ ffi_prep_closure_loc (ffi_closure* closure,
                                    &ffi_closure_STDCALL,
                                    (void*)codeloc, cif->bytes);
     }
+  else if (cif->abi == FFI_MS_CDECL)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
 #endif /* X86_WIN32 */
 #endif /* !X86_WIN64 */
   else
@@ -747,8 +760,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
   /* If the return value is a struct and we don't have a return */
   /* value address then we need to make one                     */
 
-  if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
+  if (rvalue == NULL
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -761,6 +775,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
 #ifdef X86_WIN32
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
 		     ecif.rvalue, fn);
       break;
diff --git a/src/x86/ffitarget.h b/src/x86/ffitarget.h
index 54a6121..f442654 100644
--- a/src/x86/ffitarget.h
+++ b/src/x86/ffitarget.h
@@ -80,9 +80,13 @@ typedef enum ffi_abi {
   FFI_STDCALL,
   FFI_THISCALL,
   FFI_FASTCALL,
+  FFI_MS_CDECL,
   FFI_LAST_ABI,
-  /* TODO: Add fastcall support for the sake of completeness */
+#ifdef _MSC_VER
+  FFI_DEFAULT_ABI = FFI_MS_CDECL
+#else
   FFI_DEFAULT_ABI = FFI_SYSV
+#endif
 
 #elif defined(X86_WIN64)
   FFI_WIN64,
@@ -109,6 +113,7 @@ typedef enum ffi_abi {
 #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
 #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
 #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
+#define FFI_TYPE_MS_STRUCT       (FFI_TYPE_LAST + 4)
 
 #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
 #define FFI_TRAMPOLINE_SIZE 24
diff --git a/src/x86/win32.S b/src/x86/win32.S
index f1a1278..0998356 100644
--- a/src/x86/win32.S
+++ b/src/x86/win32.S
@@ -121,6 +121,7 @@ ca_jumpdata:
         dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
 
 ca_retint8:
         ;; Load %ecx with the pointer to storage for the return value
@@ -215,6 +216,7 @@ cs_jumpdata:
         dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
 
 cs_retint8:
         mov   al, [ecx]
@@ -250,6 +252,12 @@ cs_retstruct:
         ;; Epilogue code is autogenerated.
         ret	4
 
+cs_retmsstruct:
+        ;; Caller expects us to return a pointer to the real return value.
+        mov   eax, ecx
+        ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
+        jmp   cs_epilogue
+
 cs_epilogue:
         ;; Epilogue code is autogenerated.
         ret
@@ -300,6 +308,7 @@ cr_jumpdata:
         dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
 
 cr_retint8:
         mov   al, [ecx]
@@ -500,6 +509,7 @@ _ffi_call_win32:
 	.long	.Lretstruct1b		/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lretstruct2b		/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lretstruct4b		/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lretstruct		/* FFI_TYPE_MS_STRUCT */
 1:
 	add	%ecx, %ecx
 	add	%ecx, %ecx
@@ -642,6 +652,7 @@ _ffi_closure_SYSV:
 	.long	.Lcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lcls_retmsstruct	/* FFI_TYPE_MS_STRUCT */
 
 1:
 	add	%eax, %eax
@@ -706,6 +717,12 @@ _ffi_closure_SYSV:
 	popl	%ebp
 	ret	$0x4
 
+.Lcls_retmsstruct:
+	# Caller expects us to return a pointer to the real return value.
+	mov	%ecx, %eax
+	# Caller doesn't expects us to pop struct return value pointer hidden arg.
+	jmp	.Lcls_epilogue
+
 .Lcls_noretval:
 .Lcls_epilogue:
 	movl	%ebp, %esp
@@ -768,6 +785,7 @@ _ffi_closure_raw_SYSV:
 	.long	.Lrcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lrcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lrcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lrcls_retstruct	/* FFI_TYPE_MS_STRUCT */
 1:
 	add	%eax, %eax
 	add	%eax, %eax
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 4/6] Use __fastcall for MSVC
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
                   ` (3 preceding siblings ...)
  2012-03-22 23:26 ` [PATCH 1/6] Put declarations before statements, C89 style Peter Rosin
@ 2012-03-22 23:33 ` Peter Rosin
  2012-03-22 23:33 ` [PATCH 5/6] Translate inline assembly to MSVC format Peter Rosin
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:33 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog                               |   12 ++++++++++++
 testsuite/libffi.call/fastthis1_win32.c |    2 +-
 testsuite/libffi.call/fastthis2_win32.c |    2 +-
 testsuite/libffi.call/fastthis3_win32.c |    2 +-
 testsuite/libffi.call/ffitest.h         |    8 ++++++++
 testsuite/libffi.call/strlen2_win32.c   |    2 +-
 testsuite/libffi.call/struct1_win32.c   |    2 +-
 testsuite/libffi.call/struct2_win32.c   |    2 +-
 8 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0c0cc68..4951703 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2012-03-23  Peter Rosin  <peda@lysator.liu.se>
+
+	* testsuite/libffi.call/ffitest.h: Provide abstration of
+	__attribute__((fastcall)) in the form of a __FASTCALL__
+	define.  Define it to __fastcall for MSVC.
+	* testsuite/libffi.call/fastthis1_win32.c: Use the above.
+	* testsuite/libffi.call/fastthis2_win32.c: Likewise.
+	* testsuite/libffi.call/fastthis3_win32.c: Likewise.
+	* testsuite/libffi.call/strlen2_win32.c: Likewise.
+	* testsuite/libffi.call/struct1_win32.c: Likewise.
+	* testsuite/libffi.call/struct2_win32.c: Likewise.
+
 2012-03-22  Peter Rosin  <peda@lysator.liu.se>
 
 	* src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual
diff --git a/testsuite/libffi.call/fastthis1_win32.c b/testsuite/libffi.call/fastthis1_win32.c
index b3c4c73..cbc4724 100644
--- a/testsuite/libffi.call/fastthis1_win32.c
+++ b/testsuite/libffi.call/fastthis1_win32.c
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(char *s, float a)
+static size_t __FASTCALL__ my_fastcall_f(char *s, float a)
 {
   return (size_t) ((int) strlen(s) + (int) a);
 }
diff --git a/testsuite/libffi.call/fastthis2_win32.c b/testsuite/libffi.call/fastthis2_win32.c
index f148a12..7bdd0e1 100644
--- a/testsuite/libffi.call/fastthis2_win32.c
+++ b/testsuite/libffi.call/fastthis2_win32.c
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s)
+static size_t __FASTCALL__ my_fastcall_f(float a, char *s)
 {
   return (size_t) ((int) strlen(s) + (int) a);
 }
diff --git a/testsuite/libffi.call/fastthis3_win32.c b/testsuite/libffi.call/fastthis3_win32.c
index 5cf82bb..b5d606d 100644
--- a/testsuite/libffi.call/fastthis3_win32.c
+++ b/testsuite/libffi.call/fastthis3_win32.c
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s, int i)
+static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i)
 {
   return (size_t) ((int) strlen(s) + (int) a + i);
 }
diff --git a/testsuite/libffi.call/ffitest.h b/testsuite/libffi.call/ffitest.h
index ecda068..d81d4da 100644
--- a/testsuite/libffi.call/ffitest.h
+++ b/testsuite/libffi.call/ffitest.h
@@ -25,6 +25,14 @@
 #define __UNUSED__
 #endif
 
+/* Define __FASTCALL__ so that other compilers than gcc can run the tests.  */
+#undef __FASTCALL__
+#if defined _MSC_VER
+#define __FASTCALL__ __fastcall
+#else
+#define __FASTCALL__ __attribute__((fastcall))
+#endif
+
 /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
    file open.  */
 #ifdef HAVE_MMAP_ANON
diff --git a/testsuite/libffi.call/strlen2_win32.c b/testsuite/libffi.call/strlen2_win32.c
index ce8520a..0d81061 100644
--- a/testsuite/libffi.call/strlen2_win32.c
+++ b/testsuite/libffi.call/strlen2_win32.c
@@ -8,7 +8,7 @@
 
 #include "ffitest.h"
 
-static size_t __attribute__((fastcall)) my_fastcall_strlen(char *s)
+static size_t __FASTCALL__ my_fastcall_strlen(char *s)
 {
   return (strlen(s));
 }
diff --git a/testsuite/libffi.call/struct1_win32.c b/testsuite/libffi.call/struct1_win32.c
index a97e981..b756f5a 100644
--- a/testsuite/libffi.call/struct1_win32.c
+++ b/testsuite/libffi.call/struct1_win32.c
@@ -14,7 +14,7 @@ typedef struct
   unsigned int ui;
 } test_structure_1;
 
-static __attribute__ ((fastcall)) test_structure_1 struct1(test_structure_1 ts)
+static test_structure_1 __FASTCALL__ struct1(test_structure_1 ts)
 {
   ts.uc++;
   ts.d--;
diff --git a/testsuite/libffi.call/struct2_win32.c b/testsuite/libffi.call/struct2_win32.c
index f4505be..5d02285 100644
--- a/testsuite/libffi.call/struct2_win32.c
+++ b/testsuite/libffi.call/struct2_win32.c
@@ -13,7 +13,7 @@ typedef struct
   double d2;
 } test_structure_2;
 
-static test_structure_2 __attribute__ ((fastcall)) struct2(test_structure_2 ts)
+static test_structure_2 __FASTCALL__ struct2(test_structure_2 ts)
 {
   ts.d1--;
   ts.d2--;
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 5/6] Translate inline assembly to MSVC format
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
                   ` (4 preceding siblings ...)
  2012-03-22 23:33 ` [PATCH 4/6] Use __fastcall for MSVC Peter Rosin
@ 2012-03-22 23:33 ` Peter Rosin
  2012-03-23  0:13 ` [PATCH 0/6] MSVC fixes Peter Rosin
  2012-03-23  0:23 ` Anthony Green
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-22 23:33 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog                                |    6 ++++++
 testsuite/libffi.call/closure_stdcall.c  |    8 ++++++++
 testsuite/libffi.call/closure_thiscall.c |    8 ++++++++
 3 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4951703..7e4a68f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-22  Peter Rosin  <peda@lysator.liu.se>
+
+	* testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline
+	assembly version with Intel syntax.
+	* testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise.
+
 2012-03-23  Peter Rosin  <peda@lysator.liu.se>
 
 	* testsuite/libffi.call/ffitest.h: Provide abstration of
diff --git a/testsuite/libffi.call/closure_stdcall.c b/testsuite/libffi.call/closure_stdcall.c
index 6bfcc1f..1407f02 100644
--- a/testsuite/libffi.call/closure_stdcall.c
+++ b/testsuite/libffi.call/closure_stdcall.c
@@ -49,9 +49,17 @@ int main (void)
   CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
                              (void *) 3 /* userdata */, code) == FFI_OK);
 
+#ifdef _MSC_VER
+  __asm { mov sp_pre, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+#endif
   res = (*(closure_test_type0)code)(0, 1, 2, 3);
+#ifdef _MSC_VER
+  __asm { mov sp_post, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+#endif
   /* { dg-output "0 1 2 3: 9" } */
 
   printf("res: %d\n",res);
diff --git a/testsuite/libffi.call/closure_thiscall.c b/testsuite/libffi.call/closure_thiscall.c
index 6c46f35..0f93649 100644
--- a/testsuite/libffi.call/closure_thiscall.c
+++ b/testsuite/libffi.call/closure_thiscall.c
@@ -49,9 +49,17 @@ int main (void)
   CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
                              (void *) 3 /* userdata */, code) == FFI_OK);
 
+#ifdef _MSC_VER
+  __asm { mov sp_pre, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+#endif
   res = (*(closure_test_type0)code)(0, 1, 2, 3);
+#ifdef _MSC_VER
+  __asm { mov sp_post, esp }
+#else
   asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+#endif
   /* { dg-output "0 1 2 3: 9" } */
 
   printf("res: %d\n",res);
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/6] MSVC fixes
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
                   ` (5 preceding siblings ...)
  2012-03-22 23:33 ` [PATCH 5/6] Translate inline assembly to MSVC format Peter Rosin
@ 2012-03-23  0:13 ` Peter Rosin
  2012-03-23  0:23 ` Anthony Green
  7 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-23  0:13 UTC (permalink / raw)
  To: libffi-discuss

Peter Rosin skrev 2012-03-23 00:25:
> It would be interesting to see if MSVC can call into a libffi
> built by GCC and vice versa, to check if the structure return
> discrepancy really is fixed.  That should be possible if I did
> this right, right?

Hi again!

I have now tested with testsuite/libffi.call/cls_12byte.c.

Compiling the test with GCC and linking with a MSVC-built ffi-5.dll
works, and building it with MSVC and linking it with an import lib
for the GCC-built libffi-5.dll also works.  Both executables output
the expected:

7 4 9 1 5 3: 8 9 12
res: 8 9 12
7 4 9 1 5 3: 8 9 12
res: 8 9 12

So, both libraries can handle returns of large structures for both
FFI_SYSV and FFI_MS_CDECL.

Neat, if I might say so myself!

Cheers,
Peter

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/6] MSVC fixes
  2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
                   ` (6 preceding siblings ...)
  2012-03-23  0:13 ` [PATCH 0/6] MSVC fixes Peter Rosin
@ 2012-03-23  0:23 ` Anthony Green
  2012-03-23  7:35   ` Peter Rosin
  7 siblings, 1 reply; 14+ messages in thread
From: Anthony Green @ 2012-03-23  0:23 UTC (permalink / raw)
  To: libffi-discuss

On 3/22/2012 7:25 PM, Peter Rosin wrote:
> Hi!
>
> This series fixes a number of problems that MSVC has with libffi.

Thanks Peter.   Do you know if MS makes a Free-as-in-Beer MSVC distribution?

Thanks,

AG


>
> The first patches are pretty mechanic, but the last one adds a
> new ABI for x86-win32.  As it happens, Microsoft and GCC does not
> agree on the details of the cdecl calling convention when they
> are returning structures (at least).  MS thinks that the caller
> pops the hidden structure return address and GCC thinks that
> the callee should do it.  And MS relies on the callee to return
> the structure return address in eax, while GCC seems to not care
> about that (which is pretty sane, the compiler should be able
> to keep track och where it did put that structure after all).
>
> With the patches the testsuite behaves *much* better for MSVC.
> What still fails is return_uc.c (crashes, but works when running
> in the debugger), struct1_win32.c, struct2_win32.c (haven't
> really looked, they crash) and closure_thiscall.c (no support for
> using __thiscall from C apparently). And both the C++ tests fail
> (haven't looked at all).
>
> It would be interesting to see if MSVC can call into a libffi
> built by GCC and vice versa, to check if the structure return
> discrepancy really is fixed.  That should be possible if I did
> this right, right?
>
> Cheers,
> Peter
>
> [PATCH 1/6] Put declarations before statements, C89 style
> [PATCH 2/6] Add kludge for missing format specifiers on MSVC
> [PATCH 3/6] Remove surplus frame from MASM function entry
> [PATCH 4/6] Use __fastcall for MSVC
> [PATCH 5/6] Translate inline assembly to MSVC format
> [PATCH 6/6] Add Microsoftian variant of the cdecl ABI

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/6] MSVC fixes
  2012-03-23  0:23 ` Anthony Green
@ 2012-03-23  7:35   ` Peter Rosin
  2012-03-23 10:03     ` Peter Rosin
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2012-03-23  7:35 UTC (permalink / raw)
  To: Anthony Green; +Cc: libffi-discuss

Anthony Green skrev 2012-03-23 01:23:
> On 3/22/2012 7:25 PM, Peter Rosin wrote:
>> This series fixes a number of problems that MSVC has with libffi.
> 
> Thanks Peter.   Do you know if MS makes a Free-as-in-Beer MSVC distribution?

Yes, they do, Microsoft named them the "Express" edition.

Latest non-beta version here:
http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express

I have a few wrapper scripts and hacks in the environment to make it work, and
one more small unfinished patch that's needed for the testsuite to work with
MSVC when libffi is a dll.  I'll write something up to describe my environment
later, things are interfering...

I'm going to need to make some personal notes of all that anyway, or else I'm
going to need to find it all out again next time, which would be a big waste
of time.

Cheers,
Peter

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/6] MSVC fixes
  2012-03-23  7:35   ` Peter Rosin
@ 2012-03-23 10:03     ` Peter Rosin
  2012-03-23 10:04       ` Peter Rosin
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2012-03-23 10:03 UTC (permalink / raw)
  To: Anthony Green; +Cc: libffi-discuss

[-- Attachment #1: Type: text/plain, Size: 7802 bytes --]

Peter Rosin skrev 2012-03-23 08:35:
> Anthony Green skrev 2012-03-23 01:23:
>> On 3/22/2012 7:25 PM, Peter Rosin wrote:
>>> This series fixes a number of problems that MSVC has with libffi.
>>
>> Thanks Peter.   Do you know if MS makes a Free-as-in-Beer MSVC distribution?
> 
> Yes, they do, Microsoft named them the "Express" edition.
> 
> Latest non-beta version here:
> http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express
> 
> I have a few wrapper scripts and hacks in the environment to make it work, and
> one more small unfinished patch that's needed for the testsuite to work with
> MSVC when libffi is a dll.  I'll write something up to describe my environment
> later, things are interfering...

Notes on using libffi with MSVC

MSVC is best run from MSYS.  MSVC is *much* more similar in nature to
the MinGW-GCC than to the more posixy-expecting toolchains provided
by Cygwin.

The testsuite needs dejagnu/expect/tcl and I selected to use the Cygwin
versions.  But doing that and running from MSYS forces you to set up
an "identify mount" (google it) so that the posix tools in Cygwin
finds the same files as the native Win32 tools do.  I created my
identity mount in an unorthodox way because I already had everything
installed in a way not compatible with an ordinary identity mount
setting.

I have Cygwin installed in C:\Cygwin, MinGW in c:\MinGW and the MSYS
root in C:\MinGW\msys\1.0.  The cygdrive prefix for Cygwin is "/cygdrive"
and for MSYS it's just plain old "/".  I.e., the defaults.

Then add a mount to Cygwin so that Cygwin processes sees /c/Cygwin
the same way as MSYS processes does:

cygwin$ mount C:/ /c

Then create a junction named "C:\c" pointing back to "C:\" so that
native Win32 processes sees /c/Cygwin the same way too.  In a cmd window:

C:\> mklink /D c:\c c:\

With this everybody can access the same files as /c/Cygwin/bla/bla, at
least as long as the current drive of native Win32 processes is C:, but
that's a fairly easy promise to keep in this setting.

Using Cygwin, I then checkout libffi:

cygwin$ cd   # Now in C:\Cygwin\home\<username>
cygwin$ git clone git://.../libffi.git

Then fool the libffi testsuite into thinking that MSYS has dejagnu etc
like this:  

cygwin$ cat << 'EOF' > dejagnu/runtest
#! /bin/sh
export DEJAGNULIBS=/c/Cygwin/usr/share/dejagnu
/c/Cygwin/bin/runtest "$@"
EOF
cygwin$ chmod +x dejagnu/runtest
cygwin$ cat << 'EOF' > libffi/expect/expect
#! /bin/sh
/c/Cygwin/bin/expect "$@"
EOF
cygwin$ chmod +x libffi/expect/expect

Then provide the libffi testsuite with an xgcc wrapper that invokes MSVC
with a hacked version of the latest version of the compile script from
automake (attached, this hacked version works better than the provided
msvcc.sh):

cygwin$ cat << 'EOF' > libffi/xgcc
#! /bin/sh
/c/Cygwin/home/<username>/libffi/compile cl -nologo -Zi -MD "$@"
EOF
cygwin$ chmod +x libffi/xgcc

Then replace the compile script as provided by libffi (the one in
/c/Cygwin/home/<username>/libffi/compile) with the above mentioned
version.

I'm using this script to set up the environment for running MSVC,
but I don't know how the directories map to the "Express" edition?
I think there's an install option to add these directories to the
Windows environment, making MSVC visible allover (but I don't like
that so I'm using my script instead).


cygwin$ cat << 'EOF' > /c/Cygwin/home/peda/bin/vccvars.sh
case `uname` in
CYGWIN*) c=/cygdrive/c ;;
*)       c=/c ;;
esac

COMNTOOLS=$c'/Program Files (x86)/Microsoft Visual Studio 10.0/'
PSDK=$c'/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/'

VS100COMNTOOLS=$COMNTOOLS'Common7/Tools/'
WindowsSdkDir=$PSDK
VCINSTALLDIR=$COMNTOOLS'VC/'
VSINSTALLDIR=$COMNTOOLS
DevEnvDir=$COMNTOOLS'Common7/IDE/'

export PATH=$c'/Program Files (x86)/Microsoft F#/v4.0/:'\
$COMNTOOLS'VSTSDB/Deploy:'\
$DevEnvDir':'\
$VCINSTALLDIR'BIN':\
$VS100COMNTOOLS':'\
$c'/Windows/Microsoft.NET/Framework/v4.0.30319:'\
$c'/Windows/Microsoft.NET/Framework/v3.5:'\
$VCINSTALLDIR'VCPackages:'\
$c'/Program Files (x86)/HTML Help Workshop:'\
$COMNTOOLS'Team Tools/Performance Tools:'\
$PSDK'bin/NETFX 4.0 Tools:'$PATH


COMNTOOLS='c:\Program Files (x86)\Microsoft Visual Studio 10.0\'
PSDK='c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\'

export VS100COMNTOOLS=$COMNTOOLS'Common7\Tools\'
export WindowsSdkDir=$PSDK
export VCINSTALLDIR=$COMNTOOLS'VC\'
export VSINSTALLDIR=$COMNTOOLS
export DevEnvDir=$COMNTOOLS'Common7\IDE\'

export INCLUDE=$PSDK'INCLUDE;'$INCLUDE
export INCLUDE=$VCINSTALLDIR'ATLMFC\INCLUDE;'$INCLUDE
export INCLUDE=$VCINSTALLDIR'INCLUDE;'$INCLUDE
export LIB=$PSDK'LIB;'$LIB
export LIB=$VCINSTALLDIR'ATLMFC\LIB;'$LIB
export LIB=$VCINSTALLDIR'LIB;'$LIB
export LIBPATH=$PSDK'LIB;'$LIBPATH
export LIBPATH=$VCINSTALLDIR'ATLMFC\LIB;'$LIBPATH
export LIBPATH=$VCINSTALLDIR'LIB;'$LIBPATH
export DevEnvDir=$COMNTOOLS'Common7\IDE\'
EOF
cygwin$ chmod -x /c/Cygwin/home/<username>/bin/vcvars.sh


Set up the MSYS environment to run MSVC.

msys$ . /c/Cygwin/home/<username>/bin/vcvars.sh

Finally, build the dang thing:

msys$ cd /c/Cygwin/home/<username>/libffi
msys$ cd msvc
msys$ ../configure \
  CC="/c/Cygwin/home/<usename>/libffi/compile cl -nologo" \
  CFLAGS="-MD -Zi" \
  CXX="/c/Cygwin/home/<username>/libffi/compile cl -nologo" \
  CXXFLAGS="-MD -Zi" \
  NM="dumpbin -symbols" \
  --enable-dependency-tracking \
  --disable-shared
msys$ make
msys$ make check | grep -v "excess errors"  # MSVC is *noisy*


Hmmm, I wonder what I forgot?

One thing is that I can't remember if I had to do anything special
to prevent Cygwin from creating symbolic links (MSYS and native
Win32 processes don't understand those).

Oh, along those lines, one thing to keep in mind is that MSYS does
not provide symbolic links at all (ln -s makes a copy), so I have to
run ./config.status to recopy ../src/x86/ffitarget.h to the build
tree in case it has changed.



With the below patch, I can configure with the below args
and get a DLL that can be used by the testsuite, but that
FFI_BUILDING define should be added to a Makefile instead of
burdening the user to add it to CFLAGS so the patch is not
finished (but perhaps it's not an acceptable approach to add
an FFI_BUILDING define?).

Cheers,
Peter


msys$ ../configure \
  CC="/c/Cygwin/home/<usename>/libffi/compile cl -nologo" \
  CFLAGS="-MD -Zi -DFFI_BUILDING" \
  CXX="/c/Cygwin/home/<username>/libffi/compile cl -nologo" \
  CXXFLAGS="-MD -Zi -DFFI_BUILDING" \
  NM="dumpbin -symbols" \
  --enable-dependency-tracking


diff --git a/include/ffi.h.in b/include/ffi.h.in
index 84017f1..100ec04 100644
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -166,19 +166,25 @@ typedef struct _ffi_type
  #error "long size not supported"
 #endif

+#if defined _MSC_VER && !defined FFI_BUILDING
+#define FFI_EXTERN extern __declspec(dllimport)
+#else
+#define FFI_EXTERN extern
+#endif
+
 /* These are defined in types.c */
-extern ffi_type ffi_type_void;
-extern ffi_type ffi_type_uint8;
-extern ffi_type ffi_type_sint8;
-extern ffi_type ffi_type_uint16;
-extern ffi_type ffi_type_sint16;
-extern ffi_type ffi_type_uint32;
-extern ffi_type ffi_type_sint32;
-extern ffi_type ffi_type_uint64;
-extern ffi_type ffi_type_sint64;
-extern ffi_type ffi_type_float;
-extern ffi_type ffi_type_double;
-extern ffi_type ffi_type_pointer;
+FFI_EXTERN ffi_type ffi_type_void;
+FFI_EXTERN ffi_type ffi_type_uint8;
+FFI_EXTERN ffi_type ffi_type_sint8;
+FFI_EXTERN ffi_type ffi_type_uint16;
+FFI_EXTERN ffi_type ffi_type_sint16;
+FFI_EXTERN ffi_type ffi_type_uint32;
+FFI_EXTERN ffi_type ffi_type_sint32;
+FFI_EXTERN ffi_type ffi_type_uint64;
+FFI_EXTERN ffi_type ffi_type_sint64;
+FFI_EXTERN ffi_type ffi_type_float;
+FFI_EXTERN ffi_type ffi_type_double;
+FFI_EXTERN ffi_type ffi_type_pointer;

 #if @HAVE_LONG_DOUBLE@
 extern ffi_type ffi_type_longdouble;

[-- Attachment #2: compile --]
[-- Type: text/plain, Size: 8325 bytes --]

#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.

scriptversion=2012-03-05.13; # UTC

# Copyright (C) 1999-2012 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.

nl='
'

# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" ""	$nl"

ofile=
cfile=

file_conv=

# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
  file=$1
  case $file in
    / | /[!/]*) # absolute file, and not a UNC file
      if test -z "$file_conv"; then
	# lazily determine how to convert abs files
	case `uname -s` in
	  MINGW*)
	    file_conv=mingw
	    ;;
	  CYGWIN*)
	    file_conv=cygwin
	    ;;
	  *)
	    file_conv=wine
	    ;;
	esac
      fi
      case $file_conv/,$2, in
	*,$file_conv,*)
	  ;;
	mingw/*)
	  file=`echo "$file" | sed -e 's/^.//' -e 's/^./&:/'`
	  ;;
	cygwin/*)
	  file=`cygpath -m "$file" || echo "$file"`
	  ;;
	wine/*)
	  file=`winepath -w "$file" || echo "$file"`
	  ;;
      esac
      ;;
  esac
}

# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
  func_file_conv "$1"
  if test -n "$file"; then
    if test -z "$lib_path"; then
      lib_path=$file
    else
      lib_path="$lib_path;$file"
    fi
    linker_opts="$linker_opts -LIBPATH:$file"
  fi
}

# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
  lib=$1
  found=no
  save_IFS=$IFS
  IFS=';'
  for dir in $lib_path $LIB
  do
    IFS=$save_IFS
    if $shared && test -f "$dir/$lib.dll.lib"; then
      found=yes
      lib=$dir/$lib.dll.lib
      break
    fi
    if test -f "$dir/$lib.lib"; then
      found=yes
      lib=$dir/$lib.lib
      break
    fi
    if test -f "$dir/lib$lib.a"; then
      found=yes
      lib=$dir/lib$lib.a
      break
    fi
  done
  IFS=$save_IFS

  if test "$found" != yes; then
    lib=$lib.lib
  fi
  
}

# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
  # Assume a capable shell
  lib_path=
  shared=:
  linker_opts=
  dashS=false
  assemble=false
  for arg
  do
    if test -n "$eat"; then
      eat=
    else
      case $1 in
	-o)
	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
	  eat=1
	  ofile=$2
	  case $2 in
	    *.o | *.[oO][bB][jJ])
	      func_file_conv "$2"
	      set x "$@" -Fo"$file"
	      shift
	      ;;
	    *)
	      func_file_conv "$2"
	      set x "$@" -Fe"$file"
	      shift
	      ;;
	  esac
	  ;;
	-I)
	  eat=1
	  func_file_conv "$2" mingw
	  set x "$@" -I"$file"
	  shift
	  ;;
	-I*)
	  func_file_conv "${1#-I}" mingw
	  set x "$@" -I"$file"
	  shift
	  ;;
	-lm | -W)
	  ;;
	-l)
	  eat=1
	  func_cl_dashl "$2"
	  set x "$@" "$lib"
	  shift
	  ;;
	-l*)
	  func_cl_dashl "${1#-l}"
	  set x "$@" "$lib"
	  shift
	  ;;
	-L)
	  eat=1
	  func_cl_dashL "$2"
	  ;;
	-L*)
	  func_cl_dashL "${1#-L}"
	  ;;
	-S)
	  dashS=:
	  exit 1
	  ;;
	-static)
	  shared=false
	  ;;
	-Wl,*)
	  arg=${1#-Wl,}
	  save_ifs="$IFS"; IFS=','
	  for flag in $arg; do
	    IFS="$save_ifs"
	    linker_opts="$linker_opts $flag"
	  done
	  IFS="$save_ifs"
	  ;;
	-Xlinker)
	  eat=1
	  linker_opts="$linker_opts $2"
	  ;;
	-*)
	  set x "$@" "$1"
	  shift
	  ;;
	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
	  cfile=$1
	  func_file_conv "$1"
	  set x "$@" -Tp"$file"
	  shift
	  ;;
	*.c | *.cpp | *.CPP)
	  cfile=$1
	  func_file_conv "$1" mingw
	  set x "$@" "$file"
	  shift
	  ;;
	*.[sS] | *.asm | *.ASM)
	  cfile=$1
	  assemble=:
	  func_file_conv "$1"
	  set x "$@" "$file"
	  shift
	  ;;
	*.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
	  func_file_conv "$1" mingw
	  set x "$@" "$file"
	  shift
	  ;;
	*)
	  set x "$@" "$1"
	  shift
	  ;;
      esac
    fi
    shift
  done
  if $dashS; then
    func_file_conv "${ofile:-${cfile%.*}.s}"
    set x "$@" -Fa"$file" -c -FoNUL
    shift
  fi
  if test -n "$linker_opts"; then
    linker_opts="-link$linker_opts"
  fi
  if $assemble; then
    # Preprocess with cl -EP
    sifile=${ofile:-$cfile}
    "$@" -EP > "${sifile%.*}.si" || exit $?
    # Now call ml instead of cl (dropping any .exe suffix from cl)
    # but also use the preprocessed file as input (and put it last
    # as it is required to be *after* any -Fo option).
    ml=${1%cl*}ml
    shift
    set x "$ml" "$@" -Ta"${sifile%.*}.si"
    shift
    for arg
    do
      case $1 in
	-D* | -I* | *.[sS] | *.asm | *.ASM)
	  ;;
	*)
	  set x "$@" "$1"
	  shift
	  ;;
      esac
      shift
    done
  fi
  exec "$@" $linker_opts
  exit 1
}

eat=

case $1 in
  '')
     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
     exit 1;
     ;;
  -h | --h*)
    cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]

Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.

If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.

Report bugs to <bug-automake@gnu.org>.
EOF
    exit $?
    ;;
  -v | --v*)
    echo "compile $scriptversion"
    exit $?
    ;;
  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
    func_cl_wrapper "$@"      # Doesn't return...
    ;;
esac

for arg
do
  if test -n "$eat"; then
    eat=
  else
    case $1 in
      -o)
	# configure might choose to run compile as 'compile cc -o foo foo.c'.
	# So we strip '-o arg' only if arg is an object.
	eat=1
	case $2 in
	  *.o | *.obj)
	    ofile=$2
	    ;;
	  *)
	    set x "$@" -o "$2"
	    shift
	    ;;
	esac
	;;
      *.c)
	cfile=$1
	set x "$@" "$1"
	shift
	;;
      *)
	set x "$@" "$1"
	shift
	;;
    esac
  fi
  shift
done

if test -z "$ofile" || test -z "$cfile"; then
  # If no '-o' option was seen then we might have been invoked from a
  # pattern rule where we don't need one.  That is ok -- this is a
  # normal compilation that the losing compiler can handle.  If no
  # '.c' file was seen then we are probably linking.  That is also
  # ok.
  exec "$@"
fi

# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`

# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file.  Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
  if mkdir "$lockdir" >/dev/null 2>&1; then
    break
  fi
  sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15

# Run the compile.
"$@"
ret=$?

if test -f "$cofile"; then
  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi

rmdir "$lockdir"
exit $ret

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/6] MSVC fixes
  2012-03-23 10:03     ` Peter Rosin
@ 2012-03-23 10:04       ` Peter Rosin
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2012-03-23 10:04 UTC (permalink / raw)
  To: Anthony Green; +Cc: libffi-discuss

Peter Rosin skrev 2012-03-23 11:03:
> The testsuite needs dejagnu/expect/tcl and I selected to use the Cygwin
> versions.  But doing that and running from MSYS forces you to set up
> an "identify mount" (google it) so that the posix tools in Cygwin

"identity mount"

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 6/6 try 2] Add Microsoftian variant of the cdecl ABI
  2012-03-22 23:26 ` [PATCH 6/6] Add Microsoftian variant of the cdecl ABI Peter Rosin
@ 2012-03-29 18:21   ` Peter Rosin
  2012-03-30 12:48     ` Anthony Green
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2012-03-29 18:21 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Peter Rosin

---
 ChangeLog           |   19 +++++++++++++++++++
 src/x86/ffi.c       |   27 +++++++++++++++++++++------
 src/x86/ffitarget.h |    7 ++++++-
 src/x86/win32.S     |   18 ++++++++++++++++++
 4 files changed, 64 insertions(+), 7 deletions(-)

Hi!

This is an update so that it applies cleanly after the latest merge
and it also fixes a spelling mistake in the ChnageLog.

Cheers,
Peter

diff --git a/ChangeLog b/ChangeLog
index 7b8e2e9..466af62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2012-03-29  Peter Rosin  <peda@lysator.liu.se>
+
+	* src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and
+	make it the default for MSVC.
+	(FFI_TYPE_MS_STRUCT): New structure return convention.
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure
+	return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT
+	instead of an ordinary FFI_TYPE_STRUCT.
+	(ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_call): Likewise.
+	(ffi_prep_incoming_args_SYSV): Likewise.
+	(ffi_raw_call): Likewise.
+	(ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV.
+	* src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT,
+	return a pointer to the result structure in eax and don't pop
+	that pointer from the stack, the caller takes care of it.
+	(ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_closure_raw_SYSV): Likewise.
+
 2012-03-21  Peter Rosin	 <peda@lysator.liu.se>
 
 	* testsuite/libffi.call/float_va.c (float_va_fn): Use %f when
diff --git a/src/x86/ffi.c b/src/x86/ffi.c
index f643b34..22e2997 100644
--- a/src/x86/ffi.c
+++ b/src/x86/ffi.c
@@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
 
   argp = stack;
 
-  if (ecif->cif->flags == FFI_TYPE_STRUCT
+  if ((ecif->cif->flags == FFI_TYPE_STRUCT
+       || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
 #ifdef X86_WIN64
       && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
           && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
@@ -279,7 +280,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
       else
 #endif
         {
-          cif->flags = FFI_TYPE_STRUCT;
+          if (cif->abi == FFI_MS_CDECL)
+            cif->flags = FFI_TYPE_MS_STRUCT;
+          else
+            cif->flags = FFI_TYPE_STRUCT;
           /* allocate space for return value pointer */
           cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
         }
@@ -349,7 +353,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
     }
 #else
   if (rvalue == NULL
-      && cif->flags == FFI_TYPE_STRUCT)
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -368,6 +373,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 #elif defined(X86_WIN32)
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
 		     ecif.rvalue, fn);
       break;
@@ -513,7 +519,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
     argp += sizeof(void *);
   }
 #else
-  if ( cif->flags == FFI_TYPE_STRUCT ) {
+  if ( cif->flags == FFI_TYPE_STRUCT
+       || cif->flags == FFI_TYPE_MS_STRUCT ) {
     *rvalue = *(void **) argp;
     argp += sizeof(void *);
   }
@@ -673,6 +680,12 @@ ffi_prep_closure_loc (ffi_closure* closure,
                                    &ffi_closure_STDCALL,
                                    (void*)codeloc, cif->bytes);
     }
+  else if (cif->abi == FFI_MS_CDECL)
+    {
+      FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+                           &ffi_closure_SYSV,
+                           (void*)codeloc);
+    }
 #endif /* X86_WIN32 */
 #endif /* !X86_WIN64 */
   else
@@ -762,8 +775,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
   /* If the return value is a struct and we don't have a return */
   /* value address then we need to make one                     */
 
-  if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
+  if (rvalue == NULL
+      && (cif->flags == FFI_TYPE_STRUCT
+          || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
@@ -776,6 +790,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
 #ifdef X86_WIN32
     case FFI_SYSV:
     case FFI_STDCALL:
+    case FFI_MS_CDECL:
       ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
 		     ecif.rvalue, fn);
       break;
diff --git a/src/x86/ffitarget.h b/src/x86/ffitarget.h
index 54a6121..f442654 100644
--- a/src/x86/ffitarget.h
+++ b/src/x86/ffitarget.h
@@ -80,9 +80,13 @@ typedef enum ffi_abi {
   FFI_STDCALL,
   FFI_THISCALL,
   FFI_FASTCALL,
+  FFI_MS_CDECL,
   FFI_LAST_ABI,
-  /* TODO: Add fastcall support for the sake of completeness */
+#ifdef _MSC_VER
+  FFI_DEFAULT_ABI = FFI_MS_CDECL
+#else
   FFI_DEFAULT_ABI = FFI_SYSV
+#endif
 
 #elif defined(X86_WIN64)
   FFI_WIN64,
@@ -109,6 +113,7 @@ typedef enum ffi_abi {
 #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
 #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
 #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
+#define FFI_TYPE_MS_STRUCT       (FFI_TYPE_LAST + 4)
 
 #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
 #define FFI_TRAMPOLINE_SIZE 24
diff --git a/src/x86/win32.S b/src/x86/win32.S
index 7eec4f3..a4e9fde 100644
--- a/src/x86/win32.S
+++ b/src/x86/win32.S
@@ -121,6 +121,7 @@ ca_jumpdata:
         dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset ca_epilogue       ;; FFI_TYPE_MS_STRUCT
 
 ca_retint8:
         ;; Load %ecx with the pointer to storage for the return value
@@ -217,6 +218,7 @@ cs_jumpdata:
         dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cs_retmsstruct    ;; FFI_TYPE_MS_STRUCT
 
 cs_retint8:
         mov   al, [ecx]
@@ -252,6 +254,12 @@ cs_retstruct:
         ;; Epilogue code is autogenerated.
         ret	4
 
+cs_retmsstruct:
+        ;; Caller expects us to return a pointer to the real return value.
+        mov   eax, ecx
+        ;; Caller doesn't expects us to pop struct return value pointer hidden arg.
+        jmp   cs_epilogue
+
 cs_epilogue:
         ;; Epilogue code is autogenerated.
         ret
@@ -315,6 +323,7 @@ cr_jumpdata:
         dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
         dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
         dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+        dd offset cr_epilogue       ;; FFI_TYPE_MS_STRUCT
 
 cr_retint8:
         mov   al, [ecx]
@@ -515,6 +524,7 @@ _ffi_call_win32:
 	.long	.Lretstruct1b		/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lretstruct2b		/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lretstruct4b		/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lretstruct		/* FFI_TYPE_MS_STRUCT */
 1:
 	add	%ecx, %ecx
 	add	%ecx, %ecx
@@ -657,6 +667,7 @@ _ffi_closure_SYSV:
 	.long	.Lcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lcls_retmsstruct	/* FFI_TYPE_MS_STRUCT */
 
 1:
 	add	%eax, %eax
@@ -721,6 +732,12 @@ _ffi_closure_SYSV:
 	popl	%ebp
 	ret	$0x4
 
+.Lcls_retmsstruct:
+	# Caller expects us to return a pointer to the real return value.
+	mov	%ecx, %eax
+	# Caller doesn't expects us to pop struct return value pointer hidden arg.
+	jmp	.Lcls_epilogue
+
 .Lcls_noretval:
 .Lcls_epilogue:
 	movl	%ebp, %esp
@@ -798,6 +815,7 @@ _ffi_closure_raw_SYSV:
 	.long	.Lrcls_retstruct1	/* FFI_TYPE_SMALL_STRUCT_1B */
 	.long	.Lrcls_retstruct2	/* FFI_TYPE_SMALL_STRUCT_2B */
 	.long	.Lrcls_retstruct4	/* FFI_TYPE_SMALL_STRUCT_4B */
+	.long	.Lrcls_retstruct	/* FFI_TYPE_MS_STRUCT */
 1:
 	add	%eax, %eax
 	add	%eax, %eax
-- 
1.7.9

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 6/6 try 2] Add Microsoftian variant of the cdecl ABI
  2012-03-29 18:21   ` [PATCH 6/6 try 2] " Peter Rosin
@ 2012-03-30 12:48     ` Anthony Green
  0 siblings, 0 replies; 14+ messages in thread
From: Anthony Green @ 2012-03-30 12:48 UTC (permalink / raw)
  To: Peter Rosin; +Cc: libffi-discuss

On Thu, Mar 29, 2012 at 2:20 PM, Peter Rosin <peda@lysator.liu.se> wrote:
> ---
>  ChangeLog           |   19 +++++++++++++++++++
>  src/x86/ffi.c       |   27 +++++++++++++++++++++------
>  src/x86/ffitarget.h |    7 ++++++-
>  src/x86/win32.S     |   18 ++++++++++++++++++
>  4 files changed, 64 insertions(+), 7 deletions(-)
>
> Hi!
>
> This is an update so that it applies cleanly after the latest merge
> and it also fixes a spelling mistake in the ChnageLog.

Thanks Peter.  I believe that I've committed all of your recent
changes, but it would be great if you could check this yourself.
It occurs to me that we should probably add something to the README
file about the msvc cdecl issue.   I can do this.

I've tested on x86_64 linux and 32-bit cygwin and all looks good on
those platforms.

AG

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-03-30 12:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-22 23:26 [PATCH 0/6] MSVC fixes Peter Rosin
2012-03-22 23:26 ` [PATCH 2/6] Add kludge for missing format specifiers on MSVC Peter Rosin
2012-03-22 23:26 ` [PATCH 6/6] Add Microsoftian variant of the cdecl ABI Peter Rosin
2012-03-29 18:21   ` [PATCH 6/6 try 2] " Peter Rosin
2012-03-30 12:48     ` Anthony Green
2012-03-22 23:26 ` [PATCH 3/6] Remove surplus frame from MASM function entry Peter Rosin
2012-03-22 23:26 ` [PATCH 1/6] Put declarations before statements, C89 style Peter Rosin
2012-03-22 23:33 ` [PATCH 4/6] Use __fastcall for MSVC Peter Rosin
2012-03-22 23:33 ` [PATCH 5/6] Translate inline assembly to MSVC format Peter Rosin
2012-03-23  0:13 ` [PATCH 0/6] MSVC fixes Peter Rosin
2012-03-23  0:23 ` Anthony Green
2012-03-23  7:35   ` Peter Rosin
2012-03-23 10:03     ` Peter Rosin
2012-03-23 10:04       ` Peter Rosin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).