[runtime] Implement native-to-managed marshalling of byref delegate arguments. Fixes...
[mono.git] / mono / tests / libtest.c
index ceecaf02ae426835d9d311b09c9c2e1a96b3fce8..7a6f7d1e17225cc62eeed3efcd415b61ed187eb9 100644 (file)
@@ -33,7 +33,9 @@ typedef int (STDCALL *SimpleDelegate) (int a);
 
 #if defined(WIN32) && defined (_MSC_VER)
 #define LIBTEST_API __declspec(dllexport)
-#else 
+#elif defined(__GNUC__)
+#define LIBTEST_API  __attribute__ ((visibility ("default")))
+#else
 #define LIBTEST_API
 #endif
 
@@ -256,6 +258,28 @@ mono_return_int_su (union su a) {
        return a.i1;
 }
 
+struct FI {
+       float f1;
+       float f2;
+       float f3;
+};
+
+struct NestedFloat {
+       struct FI fi;
+       float f4;
+};
+
+LIBTEST_API struct NestedFloat STDCALL
+mono_return_nested_float (void)
+{
+       struct NestedFloat f;
+       f.fi.f1 = 1.0;
+       f.fi.f2 = 2.0;
+       f.fi.f3 = 3.0;
+       f.f4 = 4.0;
+       return f;
+}
+
 LIBTEST_API int STDCALL  
 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
                                                          int f, int g, int h, int i, int j);
@@ -387,7 +411,6 @@ mono_test_marshal_unicode_char_array (gunichar2 *s)
        return 0;
 }
 
-
 LIBTEST_API int STDCALL 
 mono_test_empty_pinvoke (int i)
 {
@@ -485,6 +508,22 @@ mono_test_marshal_out_array (int *a1)
        return 0;
 }
 
+LIBTEST_API int STDCALL
+mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
+{
+       int *arr;
+       int i, len;
+
+       len = 4;
+       arr = marshal_alloc (sizeof (gint32) * len);
+       for (i = 0; i < len; ++i)
+               arr [i] = i;
+       *out_arr = arr;
+       *out_len = len;
+
+       return 0;
+}
+
 LIBTEST_API int STDCALL  
 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
 {
@@ -837,6 +876,18 @@ mono_test_marshal_return_delegate (SimpleDelegate delegate)
        return delegate;
 }
 
+typedef int DelegateByrefDelegate (void *);
+
+LIBTEST_API int STDCALL
+mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
+{
+       int (*ptr) (int i);
+
+       del (&ptr);
+
+       return ptr (54);
+}
+
 static int STDCALL
 return_plus_one (int i)
 {
@@ -941,10 +992,7 @@ mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
 LIBTEST_API int STDCALL 
 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
 {
-       int res;
-
-       res = delegate (NULL);
-
+       delegate (NULL);
        return 0;
 }
 
@@ -1061,12 +1109,18 @@ mono_test_marshal_stringbuilder (char *s, int n)
 }
 
 LIBTEST_API int STDCALL  
-mono_test_marshal_stringbuilder2 (char *s, int n)
+mono_test_marshal_stringbuilder_append (char *s, int length)
 {
-       const char m[] = "EFGH";
+       const char out_sentinel[] = "CSHARP_";
+       const char out_len = strlen (out_sentinel);
+
+       for (int i=0; i < length; i++) {
+               s [i] = out_sentinel [i % out_len];
+       }
+
+       s [length] = '\0';
+
 
-       strncpy(s, m, n);
-       s [n] = '\0';
        return 0;
 }
 
@@ -1248,6 +1302,16 @@ mono_test_empty_struct (int a, EmptyStruct es, int b)
 #endif
 }
 
+LIBTEST_API EmptyStruct STDCALL
+mono_test_return_empty_struct (int a)
+{
+       EmptyStruct s;
+
+       g_assert (a == 42);
+
+       return s;
+}
+
 typedef struct {
        char a[100];
 } ByValStrStruct;
@@ -3493,6 +3557,9 @@ mono_test_marshal_lookup_symbol (const char *symbol_name)
        return lookup_mono_symbol (symbol_name);
 }
 
+#define MONO_BEGIN_EFRAME { void *__dummy; void *__region_cookie = mono_threads_enter_gc_unsafe_region ? mono_threads_enter_gc_unsafe_region (&__dummy) : NULL;
+#define MONO_END_EFRAME if (mono_threads_exit_gc_unsafe_region) mono_threads_exit_gc_unsafe_region (__region_cookie, &__dummy); }
+
 /**
  * test_method_thunk:
  *
@@ -3503,6 +3570,8 @@ mono_test_marshal_lookup_symbol (const char *symbol_name)
 LIBTEST_API int STDCALL  
 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
 {
+       int ret = 0;
+
        gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
                = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
 
@@ -3515,21 +3584,36 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
        gpointer (*mono_object_unbox)(gpointer)
                = lookup_mono_symbol ("mono_object_unbox");
 
+       gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
+               = lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
+
+       void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
+               = lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
+
+       
+
        gpointer test_method, ex = NULL;
        gpointer (STDCALL *CreateObject)(gpointer*);
 
+       MONO_BEGIN_EFRAME;
 
-       if (!mono_method_get_unmanaged_thunk)
-               return 1;
+       if (!mono_method_get_unmanaged_thunk) {
+               ret = 1;
+               goto done;
+       }
 
        test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
-       if (!test_method)
-               return 2;
+       if (!test_method) {
+               ret = 2;
+               goto done;
+       }
 
        CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
-       if (!CreateObject)
-               return 3;
-
+       if (!CreateObject) {
+               ret = 3;
+               goto done;
+       }
+       
 
        switch (test_id) {
 
@@ -3543,8 +3627,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
        case 1: {
                /* thunks.cs:Test.Test1 */
                int (STDCALL *F)(gpointer*) = test_method;
-               if (F (&ex) != 42)
-                       return 4;
+               if (F (&ex) != 42) {
+                       ret = 4;
+                       goto done;
+               }
                break;
        }
 
@@ -3552,8 +3638,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                /* thunks.cs:Test.Test2 */
                gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
                gpointer str = mono_string_new_wrapper ("foo");
-               if (str != F (str, &ex))
-                       return 4;
+               if (str != F (str, &ex)) {
+                       ret = 4;
+                       goto done;
+               }
                break;
        }
 
@@ -3567,8 +3655,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                obj = CreateObject (&ex);
                str = mono_string_new_wrapper ("bar");
 
-               if (str != F (obj, str, &ex))
-                       return 4;
+               if (str != F (obj, str, &ex)) {
+                       ret = 4;
+                       goto done;
+               }
                break;
        }
 
@@ -3582,8 +3672,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                obj = CreateObject (&ex);
                str = mono_string_new_wrapper ("bar");
 
-               if (42 != F (obj, str, 42, &ex))
-                       return 4;
+               if (42 != F (obj, str, 42, &ex)) {
+                       ret = 4;
+                       goto done;
+               }
 
                break;
        }
@@ -3599,8 +3691,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                str = mono_string_new_wrapper ("bar");
 
                F (obj, str, 42, &ex);
-               if (!ex)
-                   return 4;
+               if (!ex) {
+                       ret = 4;
+                       goto done;
+               }
 
                break;
        }
@@ -3617,11 +3711,15 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                obj = CreateObject (&ex);
 
                res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (!res)
-                       return 5;
+               if (!res) {
+                       ret = 5;
+                       goto done;
+               }
 
                break;
        }
@@ -3629,8 +3727,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
        case 7: {
                /* thunks.cs:Test.Test7 */
                gint64 (STDCALL *F)(gpointer*) = test_method;
-               if (F (&ex) != G_MAXINT64)
-                       return 4;
+               if (F (&ex) != G_MAXINT64) {
+                       ret = 4;
+                       goto done;
+               }
                break;
        }
 
@@ -3650,8 +3750,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                F = test_method;
 
                F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
                if (!(a1 == 254 &&
                      a2 == 32700 &&
@@ -3659,8 +3761,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                      a4 == 6789600 &&
                      (fabs (a5 - 3.1415) < 0.001) &&
                      (fabs (a6 - 3.1415) < 0.001) &&
-                     strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
-                       return 5;
+                     strcmp (mono_string_to_utf8 (a7), "Test8") == 0)){
+                               ret = 5;
+                               goto done;
+                       }
 
                break;
        }
@@ -3681,8 +3785,10 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                F = test_method;
 
                F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
-               if (!ex)
-                       return 4;
+               if (!ex) {
+                       ret = 4;
+                       goto done;
+               }
 
                break;
        }
@@ -3694,17 +3800,23 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                gpointer obj1, obj2;
 
                obj1 = obj2 = CreateObject (&ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
                F = test_method;
 
                F (&obj1, &ex);
-               if (ex)
-                       return 5;
+               if (ex) {
+                       ret = 5;
+                       goto done;
+               }
 
-               if (obj1 == obj2)
-                       return 6;
+               if (obj1 == obj2) {
+                       ret = 6;
+                       goto done;
+               }
 
                break;
        }
@@ -3718,15 +3830,21 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                int res;
 
                obj = CreateObject (&ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (!obj)
-                       return 5;
+               if (!obj) {
+                       ret = 5;
+                       goto done;
+               }
 
                a1 = mono_object_unbox (obj);
-               if (!a1)
-                       return 6;
+               if (!a1) {
+                       ret = 6;
+                       goto done;
+               }
 
                a1->A = 42;
                a1->B = 3.1415;
@@ -3734,15 +3852,21 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                F = test_method;
 
                res = F (obj, &ex);
-               if (ex)
-                       return 7;
+               if (ex) {
+                       ret = 7;
+                       goto done;
+               }
 
-               if (!res)
-                       return 8;
+               if (!res) {
+                       ret = 8;
+                       goto done;
+               }
 
                /* check whether the call was really by value */
-               if (a1->A != 42 || a1->B != 3.1415)
-                       return 9;
+               if (a1->A != 42 || a1->B != 3.1415) {
+                       ret = 9;
+                       goto done;
+               }
 
                break;
        }
@@ -3755,27 +3879,39 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                gpointer obj;
 
                obj = CreateObject (&ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (!obj)
-                       return 5;
+               if (!obj) {
+                       ret = 5;
+                       goto done;
+               }
 
                a1 = mono_object_unbox (obj);
-               if (!a1)
-                       return 6;
+               if (!a1) {
+                       ret = 6;
+                       goto done;
+               }
 
                F = test_method;
 
                F (obj, &ex);
-               if (ex)
-                       return 7;
+               if (ex) {
+                       ret = 7;
+                       goto done;
+               }
 
-               if (a1->A != 42)
-                       return 8;
+               if (a1->A != 42) {
+                       ret = 8;
+                       goto done;
+               }
 
-               if (!fabs (a1->B - 3.1415) < 0.001)
-                       return 9;
+               if (!(fabs (a1->B - 3.1415) < 0.001)) {
+                       ret = 9;
+                       goto done;
+               }
 
                break;
        }
@@ -3790,19 +3926,27 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                F = test_method;
 
                obj = F (&ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (!obj)
-                       return 5;
+               if (!obj) {
+                       ret = 5;
+                       goto done;
+               }
 
                a1 = mono_object_unbox (obj);
 
-               if (a1->A != 42)
-                       return 5;
+               if (a1->A != 42) {
+                       ret = 5;
+                       goto done;
+               }
 
-               if (!fabs (a1->B - 3.1415) < 0.001)
-                       return 6;
+               if (!(fabs (a1->B - 3.1415) < 0.001)) {
+                       ret = 6;
+                       goto done;
+               }
 
                break;
        }
@@ -3815,16 +3959,22 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                gpointer obj;
 
                obj = CreateObject (&ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (!obj)
-                       return 5;
+               if (!obj) {
+                       ret = 5;
+                       goto done;
+               }
                
                a1 = mono_object_unbox (obj);
 
-               if (!a1)
-                       return 6;
+               if (!a1) {
+                       ret = 6;
+                       goto done;
+               }
 
                a1->A = 42;
                a1->B = 3.1415;
@@ -3832,24 +3982,32 @@ test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_obj
                F = test_method;
 
                F (obj, &ex);
-               if (ex)
-                       return 4;
+               if (ex) {
+                       ret = 4;
+                       goto done;
+               }
 
-               if (a1->A != 1)
-                       return 5;
+               if (a1->A != 1) {
+                       ret = 5;
+                       goto done;
+               }
 
-               if (a1->B != 17)
-                       return 6;
+               if (a1->B != 17) {
+                       ret = 6;
+                       goto done;
+               }
 
                break;
        }
 
        default:
-               return 9;
+               ret = 9;
 
        }
+done:
+       MONO_END_EFRAME;
 
-       return 0;
+       return ret;
 }
 
 typedef struct 
@@ -5404,3 +5562,1610 @@ mono_test_has_thiscall (void)
 
 #endif
 
+
+typedef struct {
+       char f1;
+} sbyte1;
+
+LIBTEST_API sbyte1 STDCALL
+mono_return_sbyte1 (sbyte1 s1, int addend) {
+       if (s1.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte1 s1.f1: got %d but expected %d\n", s1.f1, 1);
+       }
+       s1.f1+=addend; 
+       return s1;
+}
+
+typedef struct {
+       char f1,f2;
+} sbyte2;
+
+LIBTEST_API sbyte2 STDCALL
+mono_return_sbyte2 (sbyte2 s2, int addend) {
+       if (s2.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte2 s2.f1: got %d but expected %d\n", s2.f1, 1);
+       }
+       if (s2.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte2 s2.f2: got %d but expected %d\n", s2.f2, 2);
+       }
+       s2.f1+=addend; s2.f2+=addend; 
+       return s2;
+}
+
+typedef struct {
+       char f1,f2,f3;
+} sbyte3;
+
+LIBTEST_API sbyte3 STDCALL
+mono_return_sbyte3 (sbyte3 s3, int addend) {
+       if (s3.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte3 s3.f1: got %d but expected %d\n", s3.f1, 1);
+       }
+       if (s3.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte3 s3.f2: got %d but expected %d\n", s3.f2, 2);
+       }
+       if (s3.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte3 s3.f3: got %d but expected %d\n", s3.f3, 3);
+       }
+       s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
+       return s3;
+}
+
+typedef struct {
+       char f1,f2,f3,f4;
+} sbyte4;
+
+LIBTEST_API sbyte4 STDCALL
+mono_return_sbyte4 (sbyte4 s4, int addend) {
+       if (s4.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte4 s4.f1: got %d but expected %d\n", s4.f1, 1);
+       }
+       if (s4.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte4 s4.f2: got %d but expected %d\n", s4.f2, 2);
+       }
+       if (s4.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte4 s4.f3: got %d but expected %d\n", s4.f3, 3);
+       }
+       if (s4.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte4 s4.f4: got %d but expected %d\n", s4.f4, 4);
+       }
+       s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
+       return s4;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5;
+} sbyte5;
+
+LIBTEST_API sbyte5 STDCALL
+mono_return_sbyte5 (sbyte5 s5, int addend) {
+       if (s5.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte5 s5.f1: got %d but expected %d\n", s5.f1, 1);
+       }
+       if (s5.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte5 s5.f2: got %d but expected %d\n", s5.f2, 2);
+       }
+       if (s5.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte5 s5.f3: got %d but expected %d\n", s5.f3, 3);
+       }
+       if (s5.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte5 s5.f4: got %d but expected %d\n", s5.f4, 4);
+       }
+       if (s5.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte5 s5.f5: got %d but expected %d\n", s5.f5, 5);
+       }
+       s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
+       return s5;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6;
+} sbyte6;
+
+LIBTEST_API sbyte6 STDCALL
+mono_return_sbyte6 (sbyte6 s6, int addend) {
+       if (s6.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f1: got %d but expected %d\n", s6.f1, 1);
+       }
+       if (s6.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f2: got %d but expected %d\n", s6.f2, 2);
+       }
+       if (s6.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f3: got %d but expected %d\n", s6.f3, 3);
+       }
+       if (s6.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f4: got %d but expected %d\n", s6.f4, 4);
+       }
+       if (s6.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f5: got %d but expected %d\n", s6.f5, 5);
+       }
+       if (s6.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte6 s6.f6: got %d but expected %d\n", s6.f6, 6);
+       }
+       s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
+       return s6;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7;
+} sbyte7;
+
+LIBTEST_API sbyte7 STDCALL
+mono_return_sbyte7 (sbyte7 s7, int addend) {
+       if (s7.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f1: got %d but expected %d\n", s7.f1, 1);
+       }
+       if (s7.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f2: got %d but expected %d\n", s7.f2, 2);
+       }
+       if (s7.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f3: got %d but expected %d\n", s7.f3, 3);
+       }
+       if (s7.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f4: got %d but expected %d\n", s7.f4, 4);
+       }
+       if (s7.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f5: got %d but expected %d\n", s7.f5, 5);
+       }
+       if (s7.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f6: got %d but expected %d\n", s7.f6, 6);
+       }
+       if (s7.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte7 s7.f7: got %d but expected %d\n", s7.f7, 7);
+       }
+       s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
+       return s7;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8;
+} sbyte8;
+
+LIBTEST_API sbyte8 STDCALL
+mono_return_sbyte8 (sbyte8 s8, int addend) {
+       if (s8.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f1: got %d but expected %d\n", s8.f1, 1);
+       }
+       if (s8.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f2: got %d but expected %d\n", s8.f2, 2);
+       }
+       if (s8.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f3: got %d but expected %d\n", s8.f3, 3);
+       }
+       if (s8.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f4: got %d but expected %d\n", s8.f4, 4);
+       }
+       if (s8.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f5: got %d but expected %d\n", s8.f5, 5);
+       }
+       if (s8.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f6: got %d but expected %d\n", s8.f6, 6);
+       }
+       if (s8.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f7: got %d but expected %d\n", s8.f7, 7);
+       }
+       if (s8.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte8 s8.f8: got %d but expected %d\n", s8.f8, 8);
+       }
+       s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
+       return s8;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9;
+} sbyte9;
+
+LIBTEST_API sbyte9 STDCALL
+mono_return_sbyte9 (sbyte9 s9, int addend) {
+       if (s9.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f1: got %d but expected %d\n", s9.f1, 1);
+       }
+       if (s9.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f2: got %d but expected %d\n", s9.f2, 2);
+       }
+       if (s9.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f3: got %d but expected %d\n", s9.f3, 3);
+       }
+       if (s9.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f4: got %d but expected %d\n", s9.f4, 4);
+       }
+       if (s9.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f5: got %d but expected %d\n", s9.f5, 5);
+       }
+       if (s9.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f6: got %d but expected %d\n", s9.f6, 6);
+       }
+       if (s9.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f7: got %d but expected %d\n", s9.f7, 7);
+       }
+       if (s9.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f8: got %d but expected %d\n", s9.f8, 8);
+       }
+       if (s9.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte9 s9.f9: got %d but expected %d\n", s9.f9, 9);
+       }
+       s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
+       return s9;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;
+} sbyte10;
+
+LIBTEST_API sbyte10 STDCALL
+mono_return_sbyte10 (sbyte10 s10, int addend) {
+       if (s10.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f1: got %d but expected %d\n", s10.f1, 1);
+       }
+       if (s10.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f2: got %d but expected %d\n", s10.f2, 2);
+       }
+       if (s10.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f3: got %d but expected %d\n", s10.f3, 3);
+       }
+       if (s10.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f4: got %d but expected %d\n", s10.f4, 4);
+       }
+       if (s10.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f5: got %d but expected %d\n", s10.f5, 5);
+       }
+       if (s10.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f6: got %d but expected %d\n", s10.f6, 6);
+       }
+       if (s10.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f7: got %d but expected %d\n", s10.f7, 7);
+       }
+       if (s10.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f8: got %d but expected %d\n", s10.f8, 8);
+       }
+       if (s10.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f9: got %d but expected %d\n", s10.f9, 9);
+       }
+       if (s10.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte10 s10.f10: got %d but expected %d\n", s10.f10, 10);
+       }
+       s10.f1+=addend; s10.f2+=addend; s10.f3+=addend; s10.f4+=addend; s10.f5+=addend; s10.f6+=addend; s10.f7+=addend; s10.f8+=addend; s10.f9+=addend; s10.f10+=addend; 
+       return s10;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11;
+} sbyte11;
+
+LIBTEST_API sbyte11 STDCALL
+mono_return_sbyte11 (sbyte11 s11, int addend) {
+       if (s11.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f1: got %d but expected %d\n", s11.f1, 1);
+       }
+       if (s11.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f2: got %d but expected %d\n", s11.f2, 2);
+       }
+       if (s11.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f3: got %d but expected %d\n", s11.f3, 3);
+       }
+       if (s11.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f4: got %d but expected %d\n", s11.f4, 4);
+       }
+       if (s11.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f5: got %d but expected %d\n", s11.f5, 5);
+       }
+       if (s11.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f6: got %d but expected %d\n", s11.f6, 6);
+       }
+       if (s11.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f7: got %d but expected %d\n", s11.f7, 7);
+       }
+       if (s11.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f8: got %d but expected %d\n", s11.f8, 8);
+       }
+       if (s11.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f9: got %d but expected %d\n", s11.f9, 9);
+       }
+       if (s11.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f10: got %d but expected %d\n", s11.f10, 10);
+       }
+       if (s11.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte11 s11.f11: got %d but expected %d\n", s11.f11, 11);
+       }
+       s11.f1+=addend; s11.f2+=addend; s11.f3+=addend; s11.f4+=addend; s11.f5+=addend; s11.f6+=addend; s11.f7+=addend; s11.f8+=addend; s11.f9+=addend; s11.f10+=addend; s11.f11+=addend; 
+       return s11;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12;
+} sbyte12;
+
+LIBTEST_API sbyte12 STDCALL
+mono_return_sbyte12 (sbyte12 s12, int addend) {
+       if (s12.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f1: got %d but expected %d\n", s12.f1, 1);
+       }
+       if (s12.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f2: got %d but expected %d\n", s12.f2, 2);
+       }
+       if (s12.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f3: got %d but expected %d\n", s12.f3, 3);
+       }
+       if (s12.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f4: got %d but expected %d\n", s12.f4, 4);
+       }
+       if (s12.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f5: got %d but expected %d\n", s12.f5, 5);
+       }
+       if (s12.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f6: got %d but expected %d\n", s12.f6, 6);
+       }
+       if (s12.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f7: got %d but expected %d\n", s12.f7, 7);
+       }
+       if (s12.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f8: got %d but expected %d\n", s12.f8, 8);
+       }
+       if (s12.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f9: got %d but expected %d\n", s12.f9, 9);
+       }
+       if (s12.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f10: got %d but expected %d\n", s12.f10, 10);
+       }
+       if (s12.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f11: got %d but expected %d\n", s12.f11, 11);
+       }
+       if (s12.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte12 s12.f12: got %d but expected %d\n", s12.f12, 12);
+       }
+       s12.f1+=addend; s12.f2+=addend; s12.f3+=addend; s12.f4+=addend; s12.f5+=addend; s12.f6+=addend; s12.f7+=addend; s12.f8+=addend; s12.f9+=addend; s12.f10+=addend; s12.f11+=addend; s12.f12+=addend; 
+       return s12;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13;
+} sbyte13;
+
+LIBTEST_API sbyte13 STDCALL
+mono_return_sbyte13 (sbyte13 s13, int addend) {
+       if (s13.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f1: got %d but expected %d\n", s13.f1, 1);
+       }
+       if (s13.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f2: got %d but expected %d\n", s13.f2, 2);
+       }
+       if (s13.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f3: got %d but expected %d\n", s13.f3, 3);
+       }
+       if (s13.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f4: got %d but expected %d\n", s13.f4, 4);
+       }
+       if (s13.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f5: got %d but expected %d\n", s13.f5, 5);
+       }
+       if (s13.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f6: got %d but expected %d\n", s13.f6, 6);
+       }
+       if (s13.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f7: got %d but expected %d\n", s13.f7, 7);
+       }
+       if (s13.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f8: got %d but expected %d\n", s13.f8, 8);
+       }
+       if (s13.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f9: got %d but expected %d\n", s13.f9, 9);
+       }
+       if (s13.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f10: got %d but expected %d\n", s13.f10, 10);
+       }
+       if (s13.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f11: got %d but expected %d\n", s13.f11, 11);
+       }
+       if (s13.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f12: got %d but expected %d\n", s13.f12, 12);
+       }
+       if (s13.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte13 s13.f13: got %d but expected %d\n", s13.f13, 13);
+       }
+       s13.f1+=addend; s13.f2+=addend; s13.f3+=addend; s13.f4+=addend; s13.f5+=addend; s13.f6+=addend; s13.f7+=addend; s13.f8+=addend; s13.f9+=addend; s13.f10+=addend; s13.f11+=addend; s13.f12+=addend; s13.f13+=addend; 
+       return s13;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14;
+} sbyte14;
+
+LIBTEST_API sbyte14 STDCALL
+mono_return_sbyte14 (sbyte14 s14, int addend) {
+       if (s14.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f1: got %d but expected %d\n", s14.f1, 1);
+       }
+       if (s14.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f2: got %d but expected %d\n", s14.f2, 2);
+       }
+       if (s14.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f3: got %d but expected %d\n", s14.f3, 3);
+       }
+       if (s14.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f4: got %d but expected %d\n", s14.f4, 4);
+       }
+       if (s14.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f5: got %d but expected %d\n", s14.f5, 5);
+       }
+       if (s14.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f6: got %d but expected %d\n", s14.f6, 6);
+       }
+       if (s14.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f7: got %d but expected %d\n", s14.f7, 7);
+       }
+       if (s14.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f8: got %d but expected %d\n", s14.f8, 8);
+       }
+       if (s14.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f9: got %d but expected %d\n", s14.f9, 9);
+       }
+       if (s14.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f10: got %d but expected %d\n", s14.f10, 10);
+       }
+       if (s14.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f11: got %d but expected %d\n", s14.f11, 11);
+       }
+       if (s14.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f12: got %d but expected %d\n", s14.f12, 12);
+       }
+       if (s14.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f13: got %d but expected %d\n", s14.f13, 13);
+       }
+       if (s14.f14 != 14) {
+               fprintf(stderr, "mono_return_sbyte14 s14.f14: got %d but expected %d\n", s14.f14, 14);
+       }
+       s14.f1+=addend; s14.f2+=addend; s14.f3+=addend; s14.f4+=addend; s14.f5+=addend; s14.f6+=addend; s14.f7+=addend; s14.f8+=addend; s14.f9+=addend; s14.f10+=addend; s14.f11+=addend; s14.f12+=addend; s14.f13+=addend; s14.f14+=addend; 
+       return s14;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
+} sbyte15;
+
+LIBTEST_API sbyte15 STDCALL
+mono_return_sbyte15 (sbyte15 s15, int addend) {
+       if (s15.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f1: got %d but expected %d\n", s15.f1, 1);
+       }
+       if (s15.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f2: got %d but expected %d\n", s15.f2, 2);
+       }
+       if (s15.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f3: got %d but expected %d\n", s15.f3, 3);
+       }
+       if (s15.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f4: got %d but expected %d\n", s15.f4, 4);
+       }
+       if (s15.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f5: got %d but expected %d\n", s15.f5, 5);
+       }
+       if (s15.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f6: got %d but expected %d\n", s15.f6, 6);
+       }
+       if (s15.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f7: got %d but expected %d\n", s15.f7, 7);
+       }
+       if (s15.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f8: got %d but expected %d\n", s15.f8, 8);
+       }
+       if (s15.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f9: got %d but expected %d\n", s15.f9, 9);
+       }
+       if (s15.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f10: got %d but expected %d\n", s15.f10, 10);
+       }
+       if (s15.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f11: got %d but expected %d\n", s15.f11, 11);
+       }
+       if (s15.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f12: got %d but expected %d\n", s15.f12, 12);
+       }
+       if (s15.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f13: got %d but expected %d\n", s15.f13, 13);
+       }
+       if (s15.f14 != 14) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f14: got %d but expected %d\n", s15.f14, 14);
+       }
+       if (s15.f15 != 15) {
+               fprintf(stderr, "mono_return_sbyte15 s15.f15: got %d but expected %d\n", s15.f15, 15);
+       }
+       s15.f1+=addend; s15.f2+=addend; s15.f3+=addend; s15.f4+=addend; s15.f5+=addend; s15.f6+=addend; s15.f7+=addend; s15.f8+=addend; s15.f9+=addend; s15.f10+=addend; s15.f11+=addend; s15.f12+=addend; s15.f13+=addend; s15.f14+=addend; s15.f15+=addend; 
+       return s15;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16;
+} sbyte16;
+
+LIBTEST_API sbyte16 STDCALL
+mono_return_sbyte16 (sbyte16 s16, int addend) {
+       if (s16.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f1: got %d but expected %d\n", s16.f1, 1);
+       }
+       if (s16.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f2: got %d but expected %d\n", s16.f2, 2);
+       }
+       if (s16.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f3: got %d but expected %d\n", s16.f3, 3);
+       }
+       if (s16.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f4: got %d but expected %d\n", s16.f4, 4);
+       }
+       if (s16.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f5: got %d but expected %d\n", s16.f5, 5);
+       }
+       if (s16.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f6: got %d but expected %d\n", s16.f6, 6);
+       }
+       if (s16.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f7: got %d but expected %d\n", s16.f7, 7);
+       }
+       if (s16.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f8: got %d but expected %d\n", s16.f8, 8);
+       }
+       if (s16.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f9: got %d but expected %d\n", s16.f9, 9);
+       }
+       if (s16.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f10: got %d but expected %d\n", s16.f10, 10);
+       }
+       if (s16.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f11: got %d but expected %d\n", s16.f11, 11);
+       }
+       if (s16.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f12: got %d but expected %d\n", s16.f12, 12);
+       }
+       if (s16.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f13: got %d but expected %d\n", s16.f13, 13);
+       }
+       if (s16.f14 != 14) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f14: got %d but expected %d\n", s16.f14, 14);
+       }
+       if (s16.f15 != 15) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f15: got %d but expected %d\n", s16.f15, 15);
+       }
+       if (s16.f16 != 16) {
+               fprintf(stderr, "mono_return_sbyte16 s16.f16: got %d but expected %d\n", s16.f16, 16);
+       }
+       s16.f1+=addend; s16.f2+=addend; s16.f3+=addend; s16.f4+=addend; s16.f5+=addend; s16.f6+=addend; s16.f7+=addend; s16.f8+=addend; s16.f9+=addend; s16.f10+=addend; s16.f11+=addend; s16.f12+=addend; s16.f13+=addend; s16.f14+=addend; s16.f15+=addend; s16.f16+=addend; 
+       return s16;
+}
+
+typedef struct {
+       char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17;
+} sbyte17;
+
+LIBTEST_API sbyte17 STDCALL
+mono_return_sbyte17 (sbyte17 s17, int addend) {
+       if (s17.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f1: got %d but expected %d\n", s17.f1, 1);
+       }
+       if (s17.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f2: got %d but expected %d\n", s17.f2, 2);
+       }
+       if (s17.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f3: got %d but expected %d\n", s17.f3, 3);
+       }
+       if (s17.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f4: got %d but expected %d\n", s17.f4, 4);
+       }
+       if (s17.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f5: got %d but expected %d\n", s17.f5, 5);
+       }
+       if (s17.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f6: got %d but expected %d\n", s17.f6, 6);
+       }
+       if (s17.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f7: got %d but expected %d\n", s17.f7, 7);
+       }
+       if (s17.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f8: got %d but expected %d\n", s17.f8, 8);
+       }
+       if (s17.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f9: got %d but expected %d\n", s17.f9, 9);
+       }
+       if (s17.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f10: got %d but expected %d\n", s17.f10, 10);
+       }
+       if (s17.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f11: got %d but expected %d\n", s17.f11, 11);
+       }
+       if (s17.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f12: got %d but expected %d\n", s17.f12, 12);
+       }
+       if (s17.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f13: got %d but expected %d\n", s17.f13, 13);
+       }
+       if (s17.f14 != 14) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f14: got %d but expected %d\n", s17.f14, 14);
+       }
+       if (s17.f15 != 15) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f15: got %d but expected %d\n", s17.f15, 15);
+       }
+       if (s17.f16 != 16) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f16: got %d but expected %d\n", s17.f16, 16);
+       }
+       if (s17.f17 != 17) {
+               fprintf(stderr, "mono_return_sbyte17 s17.f17: got %d but expected %d\n", s17.f17, 17);
+       }
+       s17.f1+=addend; s17.f2+=addend; s17.f3+=addend; s17.f4+=addend; s17.f5+=addend; s17.f6+=addend; s17.f7+=addend; s17.f8+=addend; s17.f9+=addend; s17.f10+=addend; s17.f11+=addend; s17.f12+=addend; s17.f13+=addend; s17.f14+=addend; s17.f15+=addend; s17.f16+=addend; s17.f17+=addend; 
+       return s17;
+}
+
+typedef struct {
+       struct {
+               char f1;
+       } nested1;
+       char f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
+       struct {
+               char f16;
+       } nested2;
+} sbyte16_nested;
+
+LIBTEST_API sbyte16_nested STDCALL
+mono_return_sbyte16_nested (sbyte16_nested sn16, int addend) {
+       if (sn16.nested1.f1 != 1) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.nested1.f1: got %d but expected %d\n", sn16.nested1.f1, 1);
+       }
+       if (sn16.f2 != 2) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f2: got %d but expected %d\n", sn16.f2, 2);
+       }
+       if (sn16.f3 != 3) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f3: got %d but expected %d\n", sn16.f3, 3);
+       }
+       if (sn16.f4 != 4) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f4: got %d but expected %d\n", sn16.f4, 4);
+       }
+       if (sn16.f5 != 5) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f5: got %d but expected %d\n", sn16.f5, 5);
+       }
+       if (sn16.f6 != 6) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f6: got %d but expected %d\n", sn16.f6, 6);
+       }
+       if (sn16.f7 != 7) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f7: got %d but expected %d\n", sn16.f7, 7);
+       }
+       if (sn16.f8 != 8) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f8: got %d but expected %d\n", sn16.f8, 8);
+       }
+       if (sn16.f9 != 9) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f9: got %d but expected %d\n", sn16.f9, 9);
+       }
+       if (sn16.f10 != 10) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f10: got %d but expected %d\n", sn16.f10, 10);
+       }
+       if (sn16.f11 != 11) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f11: got %d but expected %d\n", sn16.f11, 11);
+       }
+       if (sn16.f12 != 12) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f12: got %d but expected %d\n", sn16.f12, 12);
+       }
+       if (sn16.f13 != 13) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f13: got %d but expected %d\n", sn16.f13, 13);
+       }
+       if (sn16.f14 != 14) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f14: got %d but expected %d\n", sn16.f14, 14);
+       }
+       if (sn16.f15 != 15) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.f15: got %d but expected %d\n", sn16.f15, 15);
+       }
+       if (sn16.nested2.f16 != 16) {
+               fprintf(stderr, "mono_return_sbyte16_nested sn16.nested2.f16: got %d but expected %d\n", sn16.nested2.f16, 16);
+       }
+       sn16.nested1.f1+=addend; sn16.f2+=addend; sn16.f3+=addend; sn16.f4+=addend; sn16.f5+=addend; sn16.f6+=addend; sn16.f7+=addend; sn16.f8+=addend; sn16.f9+=addend; sn16.f10+=addend; sn16.f11+=addend; sn16.f12+=addend; sn16.f13+=addend; sn16.f14+=addend; sn16.f15+=addend; sn16.nested2.f16+=addend; 
+       return sn16;
+}
+
+
+typedef struct {
+       short f1;
+} short1;
+
+LIBTEST_API short1 STDCALL
+mono_return_short1 (short1 s1, int addend) {
+       if (s1.f1 != 1) {
+               fprintf(stderr, "mono_return_short1 s1.f1: got %d but expected %d\n", s1.f1, 1);
+       }
+       s1.f1+=addend; 
+       return s1;
+}
+
+typedef struct {
+       short f1,f2;
+} short2;
+
+LIBTEST_API short2 STDCALL
+mono_return_short2 (short2 s2, int addend) {
+       if (s2.f1 != 1) {
+               fprintf(stderr, "mono_return_short2 s2.f1: got %d but expected %d\n", s2.f1, 1);
+       }
+       if (s2.f2 != 2) {
+               fprintf(stderr, "mono_return_short2 s2.f2: got %d but expected %d\n", s2.f2, 2);
+       }
+       s2.f1+=addend; s2.f2+=addend; 
+       return s2;
+}
+
+typedef struct {
+       short f1,f2,f3;
+} short3;
+
+LIBTEST_API short3 STDCALL
+mono_return_short3 (short3 s3, int addend) {
+       if (s3.f1 != 1) {
+               fprintf(stderr, "mono_return_short3 s3.f1: got %d but expected %d\n", s3.f1, 1);
+       }
+       if (s3.f2 != 2) {
+               fprintf(stderr, "mono_return_short3 s3.f2: got %d but expected %d\n", s3.f2, 2);
+       }
+       if (s3.f3 != 3) {
+               fprintf(stderr, "mono_return_short3 s3.f3: got %d but expected %d\n", s3.f3, 3);
+       }
+       s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
+       return s3;
+}
+
+typedef struct {
+       short f1,f2,f3,f4;
+} short4;
+
+LIBTEST_API short4 STDCALL
+mono_return_short4 (short4 s4, int addend) {
+       if (s4.f1 != 1) {
+               fprintf(stderr, "mono_return_short4 s4.f1: got %d but expected %d\n", s4.f1, 1);
+       }
+       if (s4.f2 != 2) {
+               fprintf(stderr, "mono_return_short4 s4.f2: got %d but expected %d\n", s4.f2, 2);
+       }
+       if (s4.f3 != 3) {
+               fprintf(stderr, "mono_return_short4 s4.f3: got %d but expected %d\n", s4.f3, 3);
+       }
+       if (s4.f4 != 4) {
+               fprintf(stderr, "mono_return_short4 s4.f4: got %d but expected %d\n", s4.f4, 4);
+       }
+       s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
+       return s4;
+}
+
+typedef struct {
+       short f1,f2,f3,f4,f5;
+} short5;
+
+LIBTEST_API short5 STDCALL
+mono_return_short5 (short5 s5, int addend) {
+       if (s5.f1 != 1) {
+               fprintf(stderr, "mono_return_short5 s5.f1: got %d but expected %d\n", s5.f1, 1);
+       }
+       if (s5.f2 != 2) {
+               fprintf(stderr, "mono_return_short5 s5.f2: got %d but expected %d\n", s5.f2, 2);
+       }
+       if (s5.f3 != 3) {
+               fprintf(stderr, "mono_return_short5 s5.f3: got %d but expected %d\n", s5.f3, 3);
+       }
+       if (s5.f4 != 4) {
+               fprintf(stderr, "mono_return_short5 s5.f4: got %d but expected %d\n", s5.f4, 4);
+       }
+       if (s5.f5 != 5) {
+               fprintf(stderr, "mono_return_short5 s5.f5: got %d but expected %d\n", s5.f5, 5);
+       }
+       s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
+       return s5;
+}
+
+typedef struct {
+       short f1,f2,f3,f4,f5,f6;
+} short6;
+
+LIBTEST_API short6 STDCALL
+mono_return_short6 (short6 s6, int addend) {
+       if (s6.f1 != 1) {
+               fprintf(stderr, "mono_return_short6 s6.f1: got %d but expected %d\n", s6.f1, 1);
+       }
+       if (s6.f2 != 2) {
+               fprintf(stderr, "mono_return_short6 s6.f2: got %d but expected %d\n", s6.f2, 2);
+       }
+       if (s6.f3 != 3) {
+               fprintf(stderr, "mono_return_short6 s6.f3: got %d but expected %d\n", s6.f3, 3);
+       }
+       if (s6.f4 != 4) {
+               fprintf(stderr, "mono_return_short6 s6.f4: got %d but expected %d\n", s6.f4, 4);
+       }
+       if (s6.f5 != 5) {
+               fprintf(stderr, "mono_return_short6 s6.f5: got %d but expected %d\n", s6.f5, 5);
+       }
+       if (s6.f6 != 6) {
+               fprintf(stderr, "mono_return_short6 s6.f6: got %d but expected %d\n", s6.f6, 6);
+       }
+       s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
+       return s6;
+}
+
+typedef struct {
+       short f1,f2,f3,f4,f5,f6,f7;
+} short7;
+
+LIBTEST_API short7 STDCALL
+mono_return_short7 (short7 s7, int addend) {
+       if (s7.f1 != 1) {
+               fprintf(stderr, "mono_return_short7 s7.f1: got %d but expected %d\n", s7.f1, 1);
+       }
+       if (s7.f2 != 2) {
+               fprintf(stderr, "mono_return_short7 s7.f2: got %d but expected %d\n", s7.f2, 2);
+       }
+       if (s7.f3 != 3) {
+               fprintf(stderr, "mono_return_short7 s7.f3: got %d but expected %d\n", s7.f3, 3);
+       }
+       if (s7.f4 != 4) {
+               fprintf(stderr, "mono_return_short7 s7.f4: got %d but expected %d\n", s7.f4, 4);
+       }
+       if (s7.f5 != 5) {
+               fprintf(stderr, "mono_return_short7 s7.f5: got %d but expected %d\n", s7.f5, 5);
+       }
+       if (s7.f6 != 6) {
+               fprintf(stderr, "mono_return_short7 s7.f6: got %d but expected %d\n", s7.f6, 6);
+       }
+       if (s7.f7 != 7) {
+               fprintf(stderr, "mono_return_short7 s7.f7: got %d but expected %d\n", s7.f7, 7);
+       }
+       s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
+       return s7;
+}
+
+typedef struct {
+       short f1,f2,f3,f4,f5,f6,f7,f8;
+} short8;
+
+LIBTEST_API short8 STDCALL
+mono_return_short8 (short8 s8, int addend) {
+       if (s8.f1 != 1) {
+               fprintf(stderr, "mono_return_short8 s8.f1: got %d but expected %d\n", s8.f1, 1);
+       }
+       if (s8.f2 != 2) {
+               fprintf(stderr, "mono_return_short8 s8.f2: got %d but expected %d\n", s8.f2, 2);
+       }
+       if (s8.f3 != 3) {
+               fprintf(stderr, "mono_return_short8 s8.f3: got %d but expected %d\n", s8.f3, 3);
+       }
+       if (s8.f4 != 4) {
+               fprintf(stderr, "mono_return_short8 s8.f4: got %d but expected %d\n", s8.f4, 4);
+       }
+       if (s8.f5 != 5) {
+               fprintf(stderr, "mono_return_short8 s8.f5: got %d but expected %d\n", s8.f5, 5);
+       }
+       if (s8.f6 != 6) {
+               fprintf(stderr, "mono_return_short8 s8.f6: got %d but expected %d\n", s8.f6, 6);
+       }
+       if (s8.f7 != 7) {
+               fprintf(stderr, "mono_return_short8 s8.f7: got %d but expected %d\n", s8.f7, 7);
+       }
+       if (s8.f8 != 8) {
+               fprintf(stderr, "mono_return_short8 s8.f8: got %d but expected %d\n", s8.f8, 8);
+       }
+       s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
+       return s8;
+}
+
+typedef struct {
+       short f1,f2,f3,f4,f5,f6,f7,f8,f9;
+} short9;
+
+LIBTEST_API short9 STDCALL
+mono_return_short9 (short9 s9, int addend) {
+       if (s9.f1 != 1) {
+               fprintf(stderr, "mono_return_short9 s9.f1: got %d but expected %d\n", s9.f1, 1);
+       }
+       if (s9.f2 != 2) {
+               fprintf(stderr, "mono_return_short9 s9.f2: got %d but expected %d\n", s9.f2, 2);
+       }
+       if (s9.f3 != 3) {
+               fprintf(stderr, "mono_return_short9 s9.f3: got %d but expected %d\n", s9.f3, 3);
+       }
+       if (s9.f4 != 4) {
+               fprintf(stderr, "mono_return_short9 s9.f4: got %d but expected %d\n", s9.f4, 4);
+       }
+       if (s9.f5 != 5) {
+               fprintf(stderr, "mono_return_short9 s9.f5: got %d but expected %d\n", s9.f5, 5);
+       }
+       if (s9.f6 != 6) {
+               fprintf(stderr, "mono_return_short9 s9.f6: got %d but expected %d\n", s9.f6, 6);
+       }
+       if (s9.f7 != 7) {
+               fprintf(stderr, "mono_return_short9 s9.f7: got %d but expected %d\n", s9.f7, 7);
+       }
+       if (s9.f8 != 8) {
+               fprintf(stderr, "mono_return_short9 s9.f8: got %d but expected %d\n", s9.f8, 8);
+       }
+       if (s9.f9 != 9) {
+               fprintf(stderr, "mono_return_short9 s9.f9: got %d but expected %d\n", s9.f9, 9);
+       }
+       s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
+       return s9;
+}
+
+typedef struct {
+       struct {
+               short f1;
+       } nested1;
+       short f2,f3,f4,f5,f6,f7;
+       struct {
+               short f8;
+       } nested2;
+} short8_nested;
+
+LIBTEST_API short8_nested STDCALL
+mono_return_short8_nested (short8_nested sn8, int addend) {
+       if (sn8.nested1.f1 != 1) {
+               fprintf(stderr, "mono_return_short8_nested sn8.nested1.f1: got %d but expected %d\n", sn8.nested1.f1, 1);
+       }
+       if (sn8.f2 != 2) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f2: got %d but expected %d\n", sn8.f2, 2);
+       }
+       if (sn8.f3 != 3) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f3: got %d but expected %d\n", sn8.f3, 3);
+       }
+       if (sn8.f4 != 4) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f4: got %d but expected %d\n", sn8.f4, 4);
+       }
+       if (sn8.f5 != 5) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f5: got %d but expected %d\n", sn8.f5, 5);
+       }
+       if (sn8.f6 != 6) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f6: got %d but expected %d\n", sn8.f6, 6);
+       }
+       if (sn8.f7 != 7) {
+               fprintf(stderr, "mono_return_short8_nested sn8.f7: got %d but expected %d\n", sn8.f7, 7);
+       }
+       if (sn8.nested2.f8 != 8) {
+               fprintf(stderr, "mono_return_short8_nested sn8.nested2.f8: got %d but expected %d\n", sn8.nested2.f8, 8);
+       }
+       sn8.nested1.f1+=addend; sn8.f2+=addend; sn8.f3+=addend; sn8.f4+=addend; sn8.f5+=addend; sn8.f6+=addend; sn8.f7+=addend; sn8.nested2.f8+=addend; 
+       return sn8;
+}
+
+
+typedef struct {
+       int f1;
+} int1;
+
+LIBTEST_API int1 STDCALL
+mono_return_int1 (int1 s1, int addend) {
+       if (s1.f1 != 1) {
+               fprintf(stderr, "mono_return_int1 s1.f1: got %d but expected %d\n", s1.f1, 1);
+       }
+       s1.f1+=addend; 
+       return s1;
+}
+
+typedef struct {
+       int f1,f2;
+} int2;
+
+LIBTEST_API int2 STDCALL
+mono_return_int2 (int2 s2, int addend) {
+       if (s2.f1 != 1) {
+               fprintf(stderr, "mono_return_int2 s2.f1: got %d but expected %d\n", s2.f1, 1);
+       }
+       if (s2.f2 != 2) {
+               fprintf(stderr, "mono_return_int2 s2.f2: got %d but expected %d\n", s2.f2, 2);
+       }
+       s2.f1+=addend; s2.f2+=addend; 
+       return s2;
+}
+
+typedef struct {
+       int f1,f2,f3;
+} int3;
+
+LIBTEST_API int3 STDCALL
+mono_return_int3 (int3 s3, int addend) {
+       if (s3.f1 != 1) {
+               fprintf(stderr, "mono_return_int3 s3.f1: got %d but expected %d\n", s3.f1, 1);
+       }
+       if (s3.f2 != 2) {
+               fprintf(stderr, "mono_return_int3 s3.f2: got %d but expected %d\n", s3.f2, 2);
+       }
+       if (s3.f3 != 3) {
+               fprintf(stderr, "mono_return_int3 s3.f3: got %d but expected %d\n", s3.f3, 3);
+       }
+       s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
+       return s3;
+}
+
+typedef struct {
+       int f1,f2,f3,f4;
+} int4;
+
+LIBTEST_API int4 STDCALL
+mono_return_int4 (int4 s4, int addend) {
+       if (s4.f1 != 1) {
+               fprintf(stderr, "mono_return_int4 s4.f1: got %d but expected %d\n", s4.f1, 1);
+       }
+       if (s4.f2 != 2) {
+               fprintf(stderr, "mono_return_int4 s4.f2: got %d but expected %d\n", s4.f2, 2);
+       }
+       if (s4.f3 != 3) {
+               fprintf(stderr, "mono_return_int4 s4.f3: got %d but expected %d\n", s4.f3, 3);
+       }
+       if (s4.f4 != 4) {
+               fprintf(stderr, "mono_return_int4 s4.f4: got %d but expected %d\n", s4.f4, 4);
+       }
+       s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
+       return s4;
+}
+
+typedef struct {
+       int f1,f2,f3,f4,f5;
+} int5;
+
+LIBTEST_API int5 STDCALL
+mono_return_int5 (int5 s5, int addend) {
+       if (s5.f1 != 1) {
+               fprintf(stderr, "mono_return_int5 s5.f1: got %d but expected %d\n", s5.f1, 1);
+       }
+       if (s5.f2 != 2) {
+               fprintf(stderr, "mono_return_int5 s5.f2: got %d but expected %d\n", s5.f2, 2);
+       }
+       if (s5.f3 != 3) {
+               fprintf(stderr, "mono_return_int5 s5.f3: got %d but expected %d\n", s5.f3, 3);
+       }
+       if (s5.f4 != 4) {
+               fprintf(stderr, "mono_return_int5 s5.f4: got %d but expected %d\n", s5.f4, 4);
+       }
+       if (s5.f5 != 5) {
+               fprintf(stderr, "mono_return_int5 s5.f5: got %d but expected %d\n", s5.f5, 5);
+       }
+       s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
+       return s5;
+}
+
+typedef struct {
+       struct {
+               int f1;
+       } nested1;
+       int f2,f3;
+       struct {
+               int f4;
+       } nested2;
+} int4_nested;
+
+LIBTEST_API int4_nested STDCALL
+mono_return_int4_nested (int4_nested sn4, int addend) {
+       if (sn4.nested1.f1 != 1) {
+               fprintf(stderr, "mono_return_int4_nested sn4.nested1.f1: got %d but expected %d\n", sn4.nested1.f1, 1);
+       }
+       if (sn4.f2 != 2) {
+               fprintf(stderr, "mono_return_int4_nested sn4.f2: got %d but expected %d\n", sn4.f2, 2);
+       }
+       if (sn4.f3 != 3) {
+               fprintf(stderr, "mono_return_int4_nested sn4.f3: got %d but expected %d\n", sn4.f3, 3);
+       }
+       if (sn4.nested2.f4 != 4) {
+               fprintf(stderr, "mono_return_int4_nested sn4.nested2.f4: got %d but expected %d\n", sn4.nested2.f4, 4);
+       }
+       sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend; 
+       return sn4;
+}
+
+typedef struct {
+       float f1;
+} float1;
+
+LIBTEST_API float1 STDCALL
+mono_return_float1 (float1 s1, int addend) {
+       if (s1.f1 != 1) {
+               fprintf(stderr, "mono_return_float1 s1.f1: got %f but expected %d\n", s1.f1, 1);
+       }
+       s1.f1+=addend; 
+       return s1;
+}
+
+typedef struct {
+       float f1,f2;
+} float2;
+
+LIBTEST_API float2 STDCALL
+mono_return_float2 (float2 s2, int addend) {
+       if (s2.f1 != 1) {
+               fprintf(stderr, "mono_return_float2 s2.f1: got %f but expected %d\n", s2.f1, 1);
+       }
+       if (s2.f2 != 2) {
+               fprintf(stderr, "mono_return_float2 s2.f2: got %f but expected %d\n", s2.f2, 2);
+       }
+       s2.f1+=addend; s2.f2+=addend; 
+       return s2;
+}
+
+typedef struct {
+       float f1,f2,f3;
+} float3;
+
+LIBTEST_API float3 STDCALL
+mono_return_float3 (float3 s3, int addend) {
+       if (s3.f1 != 1) {
+               fprintf(stderr, "mono_return_float3 s3.f1: got %f but expected %d\n", s3.f1, 1);
+       }
+       if (s3.f2 != 2) {
+               fprintf(stderr, "mono_return_float3 s3.f2: got %f but expected %d\n", s3.f2, 2);
+       }
+       if (s3.f3 != 3) {
+               fprintf(stderr, "mono_return_float3 s3.f3: got %f but expected %d\n", s3.f3, 3);
+       }
+       s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
+       return s3;
+}
+
+typedef struct {
+       float f1,f2,f3,f4;
+} float4;
+
+LIBTEST_API float4 STDCALL
+mono_return_float4 (float4 s4, int addend) {
+       if (s4.f1 != 1) {
+               fprintf(stderr, "mono_return_float4 s4.f1: got %f but expected %d\n", s4.f1, 1);
+       }
+       if (s4.f2 != 2) {
+               fprintf(stderr, "mono_return_float4 s4.f2: got %f but expected %d\n", s4.f2, 2);
+       }
+       if (s4.f3 != 3) {
+               fprintf(stderr, "mono_return_float4 s4.f3: got %f but expected %d\n", s4.f3, 3);
+       }
+       if (s4.f4 != 4) {
+               fprintf(stderr, "mono_return_float4 s4.f4: got %f but expected %d\n", s4.f4, 4);
+       }
+       s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
+       return s4;
+}
+
+typedef struct {
+       float f1,f2,f3,f4,f5;
+} float5;
+
+LIBTEST_API float5 STDCALL
+mono_return_float5 (float5 s5, int addend) {
+       if (s5.f1 != 1) {
+               fprintf(stderr, "mono_return_float5 s5.f1: got %f but expected %d\n", s5.f1, 1);
+       }
+       if (s5.f2 != 2) {
+               fprintf(stderr, "mono_return_float5 s5.f2: got %f but expected %d\n", s5.f2, 2);
+       }
+       if (s5.f3 != 3) {
+               fprintf(stderr, "mono_return_float5 s5.f3: got %f but expected %d\n", s5.f3, 3);
+       }
+       if (s5.f4 != 4) {
+               fprintf(stderr, "mono_return_float5 s5.f4: got %f but expected %d\n", s5.f4, 4);
+       }
+       if (s5.f5 != 5) {
+               fprintf(stderr, "mono_return_float5 s5.f5: got %f but expected %d\n", s5.f5, 5);
+       }
+       s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
+       return s5;
+}
+
+typedef struct {
+       float f1,f2,f3,f4,f5,f6;
+} float6;
+
+LIBTEST_API float6 STDCALL
+mono_return_float6 (float6 s6, int addend) {
+       if (s6.f1 != 1) {
+               fprintf(stderr, "mono_return_float6 s6.f1: got %f but expected %d\n", s6.f1, 1);
+       }
+       if (s6.f2 != 2) {
+               fprintf(stderr, "mono_return_float6 s6.f2: got %f but expected %d\n", s6.f2, 2);
+       }
+       if (s6.f3 != 3) {
+               fprintf(stderr, "mono_return_float6 s6.f3: got %f but expected %d\n", s6.f3, 3);
+       }
+       if (s6.f4 != 4) {
+               fprintf(stderr, "mono_return_float6 s6.f4: got %f but expected %d\n", s6.f4, 4);
+       }
+       if (s6.f5 != 5) {
+               fprintf(stderr, "mono_return_float6 s6.f5: got %f but expected %d\n", s6.f5, 5);
+       }
+       if (s6.f6 != 6) {
+               fprintf(stderr, "mono_return_float6 s6.f6: got %f but expected %d\n", s6.f6, 6);
+       }
+       s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
+       return s6;
+}
+
+typedef struct {
+       float f1,f2,f3,f4,f5,f6,f7;
+} float7;
+
+LIBTEST_API float7 STDCALL
+mono_return_float7 (float7 s7, int addend) {
+       if (s7.f1 != 1) {
+               fprintf(stderr, "mono_return_float7 s7.f1: got %f but expected %d\n", s7.f1, 1);
+       }
+       if (s7.f2 != 2) {
+               fprintf(stderr, "mono_return_float7 s7.f2: got %f but expected %d\n", s7.f2, 2);
+       }
+       if (s7.f3 != 3) {
+               fprintf(stderr, "mono_return_float7 s7.f3: got %f but expected %d\n", s7.f3, 3);
+       }
+       if (s7.f4 != 4) {
+               fprintf(stderr, "mono_return_float7 s7.f4: got %f but expected %d\n", s7.f4, 4);
+       }
+       if (s7.f5 != 5) {
+               fprintf(stderr, "mono_return_float7 s7.f5: got %f but expected %d\n", s7.f5, 5);
+       }
+       if (s7.f6 != 6) {
+               fprintf(stderr, "mono_return_float7 s7.f6: got %f but expected %d\n", s7.f6, 6);
+       }
+       if (s7.f7 != 7) {
+               fprintf(stderr, "mono_return_float7 s7.f7: got %f but expected %d\n", s7.f7, 7);
+       }
+       s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
+       return s7;
+}
+
+typedef struct {
+       float f1,f2,f3,f4,f5,f6,f7,f8;
+} float8;
+
+LIBTEST_API float8 STDCALL
+mono_return_float8 (float8 s8, int addend) {
+       if (s8.f1 != 1) {
+               fprintf(stderr, "mono_return_float8 s8.f1: got %f but expected %d\n", s8.f1, 1);
+       }
+       if (s8.f2 != 2) {
+               fprintf(stderr, "mono_return_float8 s8.f2: got %f but expected %d\n", s8.f2, 2);
+       }
+       if (s8.f3 != 3) {
+               fprintf(stderr, "mono_return_float8 s8.f3: got %f but expected %d\n", s8.f3, 3);
+       }
+       if (s8.f4 != 4) {
+               fprintf(stderr, "mono_return_float8 s8.f4: got %f but expected %d\n", s8.f4, 4);
+       }
+       if (s8.f5 != 5) {
+               fprintf(stderr, "mono_return_float8 s8.f5: got %f but expected %d\n", s8.f5, 5);
+       }
+       if (s8.f6 != 6) {
+               fprintf(stderr, "mono_return_float8 s8.f6: got %f but expected %d\n", s8.f6, 6);
+       }
+       if (s8.f7 != 7) {
+               fprintf(stderr, "mono_return_float8 s8.f7: got %f but expected %d\n", s8.f7, 7);
+       }
+       if (s8.f8 != 8) {
+               fprintf(stderr, "mono_return_float8 s8.f8: got %f but expected %d\n", s8.f8, 8);
+       }
+       s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
+       return s8;
+}
+
+typedef struct {
+       float f1,f2,f3,f4,f5,f6,f7,f8,f9;
+} float9;
+
+LIBTEST_API float9 STDCALL
+mono_return_float9 (float9 s9, int addend) {
+       if (s9.f1 != 1) {
+               fprintf(stderr, "mono_return_float9 s9.f1: got %f but expected %d\n", s9.f1, 1);
+       }
+       if (s9.f2 != 2) {
+               fprintf(stderr, "mono_return_float9 s9.f2: got %f but expected %d\n", s9.f2, 2);
+       }
+       if (s9.f3 != 3) {
+               fprintf(stderr, "mono_return_float9 s9.f3: got %f but expected %d\n", s9.f3, 3);
+       }
+       if (s9.f4 != 4) {
+               fprintf(stderr, "mono_return_float9 s9.f4: got %f but expected %d\n", s9.f4, 4);
+       }
+       if (s9.f5 != 5) {
+               fprintf(stderr, "mono_return_float9 s9.f5: got %f but expected %d\n", s9.f5, 5);
+       }
+       if (s9.f6 != 6) {
+               fprintf(stderr, "mono_return_float9 s9.f6: got %f but expected %d\n", s9.f6, 6);
+       }
+       if (s9.f7 != 7) {
+               fprintf(stderr, "mono_return_float9 s9.f7: got %f but expected %d\n", s9.f7, 7);
+       }
+       if (s9.f8 != 8) {
+               fprintf(stderr, "mono_return_float9 s9.f8: got %f but expected %d\n", s9.f8, 8);
+       }
+       if (s9.f9 != 9) {
+               fprintf(stderr, "mono_return_float9 s9.f9: got %f but expected %d\n", s9.f9, 9);
+       }
+       s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
+       return s9;
+}
+
+typedef struct {
+       struct {
+               float f1;
+       } nested1;
+       float f2,f3;
+       struct {
+               float f4;
+       } nested2;
+} float4_nested;
+
+LIBTEST_API float4_nested STDCALL
+mono_return_float4_nested (float4_nested sn4, int addend) {
+       if (sn4.nested1.f1 != 1) {
+               fprintf(stderr, "mono_return_float4_nested sn4.nested1.f1: got %f but expected %d\n", sn4.nested1.f1, 1);
+       }
+       if (sn4.f2 != 2) {
+               fprintf(stderr, "mono_return_float4_nested sn4.f2: got %f but expected %d\n", sn4.f2, 2);
+       }
+       if (sn4.f3 != 3) {
+               fprintf(stderr, "mono_return_float4_nested sn4.f3: got %f but expected %d\n", sn4.f3, 3);
+       }
+       if (sn4.nested2.f4 != 4) {
+               fprintf(stderr, "mono_return_float4_nested sn4.nested2.f4: got %f but expected %d\n", sn4.nested2.f4, 4);
+       }
+       sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend; 
+       return sn4;
+}
+
+typedef struct {
+       double f1;
+} double1;
+
+LIBTEST_API double1 STDCALL
+mono_return_double1 (double1 s1, int addend) {
+       if (s1.f1 != 1) {
+               fprintf(stderr, "mono_return_double1 s1.f1: got %f but expected %d\n", s1.f1, 1);
+       }
+       s1.f1+=addend; 
+       return s1;
+}
+
+typedef struct {
+       double f1,f2;
+} double2;
+
+LIBTEST_API double2 STDCALL
+mono_return_double2 (double2 s2, int addend) {
+       if (s2.f1 != 1) {
+               fprintf(stderr, "mono_return_double2 s2.f1: got %f but expected %d\n", s2.f1, 1);
+       }
+       if (s2.f2 != 2) {
+               fprintf(stderr, "mono_return_double2 s2.f2: got %f but expected %d\n", s2.f2, 2);
+       }
+       s2.f1+=addend; s2.f2+=addend; 
+       return s2;
+}
+
+typedef struct {
+       double f1,f2,f3;
+} double3;
+
+LIBTEST_API double3 STDCALL
+mono_return_double3 (double3 s3, int addend) {
+       if (s3.f1 != 1) {
+               fprintf(stderr, "mono_return_double3 s3.f1: got %f but expected %d\n", s3.f1, 1);
+       }
+       if (s3.f2 != 2) {
+               fprintf(stderr, "mono_return_double3 s3.f2: got %f but expected %d\n", s3.f2, 2);
+       }
+       if (s3.f3 != 3) {
+               fprintf(stderr, "mono_return_double3 s3.f3: got %f but expected %d\n", s3.f3, 3);
+       }
+       s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
+       return s3;
+}
+
+typedef struct {
+       double f1,f2,f3,f4;
+} double4;
+
+LIBTEST_API double4 STDCALL
+mono_return_double4 (double4 s4, int addend) {
+       if (s4.f1 != 1) {
+               fprintf(stderr, "mono_return_double4 s4.f1: got %f but expected %d\n", s4.f1, 1);
+       }
+       if (s4.f2 != 2) {
+               fprintf(stderr, "mono_return_double4 s4.f2: got %f but expected %d\n", s4.f2, 2);
+       }
+       if (s4.f3 != 3) {
+               fprintf(stderr, "mono_return_double4 s4.f3: got %f but expected %d\n", s4.f3, 3);
+       }
+       if (s4.f4 != 4) {
+               fprintf(stderr, "mono_return_double4 s4.f4: got %f but expected %d\n", s4.f4, 4);
+       }
+       s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
+       return s4;
+}
+
+typedef struct {
+       double f1,f2,f3,f4,f5;
+} double5;
+
+LIBTEST_API double5 STDCALL
+mono_return_double5 (double5 s5, int addend) {
+       if (s5.f1 != 1) {
+               fprintf(stderr, "mono_return_double5 s5.f1: got %f but expected %d\n", s5.f1, 1);
+       }
+       if (s5.f2 != 2) {
+               fprintf(stderr, "mono_return_double5 s5.f2: got %f but expected %d\n", s5.f2, 2);
+       }
+       if (s5.f3 != 3) {
+               fprintf(stderr, "mono_return_double5 s5.f3: got %f but expected %d\n", s5.f3, 3);
+       }
+       if (s5.f4 != 4) {
+               fprintf(stderr, "mono_return_double5 s5.f4: got %f but expected %d\n", s5.f4, 4);
+       }
+       if (s5.f5 != 5) {
+               fprintf(stderr, "mono_return_double5 s5.f5: got %f but expected %d\n", s5.f5, 5);
+       }
+       s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
+       return s5;
+}
+
+typedef struct {
+       double f1,f2,f3,f4,f5,f6;
+} double6;
+
+LIBTEST_API double6 STDCALL
+mono_return_double6 (double6 s6, int addend) {
+       if (s6.f1 != 1) {
+               fprintf(stderr, "mono_return_double6 s6.f1: got %f but expected %d\n", s6.f1, 1);
+       }
+       if (s6.f2 != 2) {
+               fprintf(stderr, "mono_return_double6 s6.f2: got %f but expected %d\n", s6.f2, 2);
+       }
+       if (s6.f3 != 3) {
+               fprintf(stderr, "mono_return_double6 s6.f3: got %f but expected %d\n", s6.f3, 3);
+       }
+       if (s6.f4 != 4) {
+               fprintf(stderr, "mono_return_double6 s6.f4: got %f but expected %d\n", s6.f4, 4);
+       }
+       if (s6.f5 != 5) {
+               fprintf(stderr, "mono_return_double6 s6.f5: got %f but expected %d\n", s6.f5, 5);
+       }
+       if (s6.f6 != 6) {
+               fprintf(stderr, "mono_return_double6 s6.f6: got %f but expected %d\n", s6.f6, 6);
+       }
+       s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
+       return s6;
+}
+
+typedef struct {
+       double f1,f2,f3,f4,f5,f6,f7;
+} double7;
+
+LIBTEST_API double7 STDCALL
+mono_return_double7 (double7 s7, int addend) {
+       if (s7.f1 != 1) {
+               fprintf(stderr, "mono_return_double7 s7.f1: got %f but expected %d\n", s7.f1, 1);
+       }
+       if (s7.f2 != 2) {
+               fprintf(stderr, "mono_return_double7 s7.f2: got %f but expected %d\n", s7.f2, 2);
+       }
+       if (s7.f3 != 3) {
+               fprintf(stderr, "mono_return_double7 s7.f3: got %f but expected %d\n", s7.f3, 3);
+       }
+       if (s7.f4 != 4) {
+               fprintf(stderr, "mono_return_double7 s7.f4: got %f but expected %d\n", s7.f4, 4);
+       }
+       if (s7.f5 != 5) {
+               fprintf(stderr, "mono_return_double7 s7.f5: got %f but expected %d\n", s7.f5, 5);
+       }
+       if (s7.f6 != 6) {
+               fprintf(stderr, "mono_return_double7 s7.f6: got %f but expected %d\n", s7.f6, 6);
+       }
+       if (s7.f7 != 7) {
+               fprintf(stderr, "mono_return_double7 s7.f7: got %f but expected %d\n", s7.f7, 7);
+       }
+       s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
+       return s7;
+}
+
+typedef struct {
+       double f1,f2,f3,f4,f5,f6,f7,f8;
+} double8;
+
+LIBTEST_API double8 STDCALL
+mono_return_double8 (double8 s8, int addend) {
+       if (s8.f1 != 1) {
+               fprintf(stderr, "mono_return_double8 s8.f1: got %f but expected %d\n", s8.f1, 1);
+       }
+       if (s8.f2 != 2) {
+               fprintf(stderr, "mono_return_double8 s8.f2: got %f but expected %d\n", s8.f2, 2);
+       }
+       if (s8.f3 != 3) {
+               fprintf(stderr, "mono_return_double8 s8.f3: got %f but expected %d\n", s8.f3, 3);
+       }
+       if (s8.f4 != 4) {
+               fprintf(stderr, "mono_return_double8 s8.f4: got %f but expected %d\n", s8.f4, 4);
+       }
+       if (s8.f5 != 5) {
+               fprintf(stderr, "mono_return_double8 s8.f5: got %f but expected %d\n", s8.f5, 5);
+       }
+       if (s8.f6 != 6) {
+               fprintf(stderr, "mono_return_double8 s8.f6: got %f but expected %d\n", s8.f6, 6);
+       }
+       if (s8.f7 != 7) {
+               fprintf(stderr, "mono_return_double8 s8.f7: got %f but expected %d\n", s8.f7, 7);
+       }
+       if (s8.f8 != 8) {
+               fprintf(stderr, "mono_return_double8 s8.f8: got %f but expected %d\n", s8.f8, 8);
+       }
+       s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
+       return s8;
+}
+
+typedef struct {
+       double f1,f2,f3,f4,f5,f6,f7,f8,f9;
+} double9;
+
+LIBTEST_API double9 STDCALL
+mono_return_double9 (double9 s9, int addend) {
+       if (s9.f1 != 1) {
+               fprintf(stderr, "mono_return_double9 s9.f1: got %f but expected %d\n", s9.f1, 1);
+       }
+       if (s9.f2 != 2) {
+               fprintf(stderr, "mono_return_double9 s9.f2: got %f but expected %d\n", s9.f2, 2);
+       }
+       if (s9.f3 != 3) {
+               fprintf(stderr, "mono_return_double9 s9.f3: got %f but expected %d\n", s9.f3, 3);
+       }
+       if (s9.f4 != 4) {
+               fprintf(stderr, "mono_return_double9 s9.f4: got %f but expected %d\n", s9.f4, 4);
+       }
+       if (s9.f5 != 5) {
+               fprintf(stderr, "mono_return_double9 s9.f5: got %f but expected %d\n", s9.f5, 5);
+       }
+       if (s9.f6 != 6) {
+               fprintf(stderr, "mono_return_double9 s9.f6: got %f but expected %d\n", s9.f6, 6);
+       }
+       if (s9.f7 != 7) {
+               fprintf(stderr, "mono_return_double9 s9.f7: got %f but expected %d\n", s9.f7, 7);
+       }
+       if (s9.f8 != 8) {
+               fprintf(stderr, "mono_return_double9 s9.f8: got %f but expected %d\n", s9.f8, 8);
+       }
+       if (s9.f9 != 9) {
+               fprintf(stderr, "mono_return_double9 s9.f9: got %f but expected %d\n", s9.f9, 9);
+       }
+       s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
+       return s9;
+}
+
+typedef struct {
+       struct {
+               double f1;
+       } nested1;
+       struct {
+               double f2;
+       } nested2;
+} double2_nested;
+
+LIBTEST_API double2_nested STDCALL
+mono_return_double2_nested (double2_nested sn2, int addend) {
+       if (sn2.nested1.f1 != 1) {
+               fprintf(stderr, "mono_return_double2_nested sn2.nested1.f1: got %f but expected %d\n", sn2.nested1.f1, 1);
+       }
+       if (sn2.nested2.f2 != 2) {
+               fprintf(stderr, "mono_return_double2_nested sn2.nested2.f2: got %f but expected %d\n", sn2.nested2.f2, 2);
+       }
+       sn2.nested1.f1+=addend; sn2.nested2.f2+=addend; 
+       return sn2;
+}
+
+
+
+typedef struct {
+       double f1[4];
+} double_array4;
+
+LIBTEST_API double_array4 STDCALL
+mono_return_double_array4 (double_array4 sa4, int addend) {
+       if (sa4.f1[0] != 1) {
+               fprintf(stderr, "mono_return_double_array4 sa4.f1[0]: got %f but expected %d\n", sa4.f1[0], 1);
+       }
+       if (sa4.f1[1] != 2) {
+               fprintf(stderr, "mono_return_double_array4 sa4.f1[1]: got %f but expected %d\n", sa4.f1[1], 2);
+       }
+       if (sa4.f1[2] != 3) {
+               fprintf(stderr, "mono_return_double_array4 sa4.f1[2]: got %f but expected %d\n", sa4.f1[2], 3);
+       }
+       if (sa4.f1[3] != 4) {
+               fprintf(stderr, "mono_return_double_array4 sa4.f1[3]: got %f but expected %d\n", sa4.f1[3], 4);
+       }
+       sa4.f1[0]+=addend; sa4.f1[1]+=addend; sa4.f1[2]+=addend; sa4.f1[3]+=addend; 
+       return sa4;
+}
+