Majorly beef up this test:

* test all wrapped-function arities from 0 to 12

* try hard to run both callers and callees out of integer registers,
  so as to detect problems where the CALL_FN_* macros do not
  properly save registers around the call

This will cause failure in building the regtests on all non-x86
platforms.  Will fix shortly.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5747 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 3b4949e..ea3f23e 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -173,6 +173,7 @@
 vcpu_fbench_CFLAGS	= $(AM_FLAG_M3264_PRI) $(AM_CFLAGS) -O2 -g
 vcpu_fnfns_CFLAGS	= $(AM_FLAG_M3264_PRI) $(AM_CFLAGS) -O2 -g
 vcpu_fnfns_LDADD	= -lm
+wrap6_CFLAGS		= $(AM_FLAG_M3264_PRI) $(AM_CFLAGS) -O2 -g
 
 # Don't allow GCC to inline memcpy(), because then we can't intercept it
 overlap_CFLAGS		= $(AM_CFLAGS) -fno-builtin-memcpy
diff --git a/memcheck/tests/wrap6.c b/memcheck/tests/wrap6.c
index 85994ff..f249f48 100644
--- a/memcheck/tests/wrap6.c
+++ b/memcheck/tests/wrap6.c
@@ -1,6 +1,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <assert.h>
 #include "valgrind.h"
 
 /* Program that checks all numbers of args (0 through 12) work for
@@ -14,21 +15,21 @@
 
 #define TRASH_IREGS(_rlval, _vec) \
    do { \
-      UInt* vec = (_vec);   \
+      register UInt* vec = (_vec);   \
       /* x86 spills for v > 4, amd64 for v > 12. */   \
-      UInt i, sum = 0;   \
-      UInt v1 = vec[1-1];   \
-      UInt v2 = vec[2-1];   \
-      UInt v3 = vec[3-1];   \
-      UInt v4 = vec[4-1];   \
-      UInt v5 = vec[5-1];   \
-      UInt v6 = vec[6-1];   \
-      UInt v7 = vec[7-1];   \
-      UInt v8 = vec[8-1];   \
-      UInt v9 = vec[9-1];   \
-      UInt v10 = vec[10-1];   \
-      UInt v11 = vec[11-1];   \
-      UInt v12 = vec[12-1];   \
+      register UInt i, sum = 0;   \
+      register UInt v1 = vec[1-1];   \
+      register UInt v2 = vec[2-1];   \
+      register UInt v3 = vec[3-1];   \
+      register UInt v4 = vec[4-1];   \
+      register UInt v5 = vec[5-1];   \
+      register UInt v6 = vec[6-1];   \
+      register UInt v7 = vec[7-1];   \
+      register UInt v8 = vec[8-1];   \
+      register UInt v9 = vec[9-1];   \
+      register UInt v10 = vec[10-1];   \
+      register UInt v11 = vec[11-1];   \
+      register UInt v12 = vec[12-1];   \
       for (i = 0; i < 50; i++) {   \
          v1 = ROL(v1,1);   \
          v2 = ROL(v2,2);   \
@@ -57,6 +58,69 @@
       _rlval = sum;   \
    } while (0)
 
+
+/* Returns one, in a way that gcc probably can't constant fold out */
+
+volatile int one_actual_return_value = 0; /* the value one() returns */
+
+ __attribute__((noinline))
+int one ( void )
+{
+   int i, sum, a[7];
+   for (i = 0; i < 7; i++)
+      a[i] = i;
+   a[3] = 3+one_actual_return_value;
+   sum = 0;
+   for (i = 7-1; i >= 0; i--)
+      sum += a[i] - i;
+   return sum;
+}
+
+#define LOOPS_START                                                \
+   { register int len = one();                                     \
+     register int x0; for (x0 = 0x1000; x0 < 0x1000+len; x0++) {   \
+     register int x1; for (x1 = 0x1100; x1 < 0x1100+len; x1++) {   \
+     register int x2; for (x2 = 0x1200; x2 < 0x1200+len; x2++) {   \
+     register int x3; for (x3 = 0x1300; x3 < 0x1300+len; x3++) {   \
+     register int x4; for (x4 = 0x1400; x4 < 0x1400+len; x4++) {   \
+     register int x5; for (x5 = 0x1500; x5 < 0x1500+len; x5++) {   \
+     register int x6; for (x6 = 0x1600; x6 < 0x1600+len; x6++) {   \
+     register int x7; for (x7 = 0x1700; x7 < 0x1700+len; x7++) {   \
+     register int x8; for (x8 = 0x1800; x8 < 0x1800+len; x8++) {   \
+     register int x9; for (x9 = 0x1900; x9 < 0x1900+len; x9++) {   \
+     register int xA; for (xA = 0x1A00; xA < 0x1A00+len; xA++) {   \
+     register int xB; for (xB = 0x1B00; xB < 0x1B00+len; xB++) {   \
+     register int xC; for (xC = 0x1C00; xC < 0x1C00+len; xC++) {   \
+     register int xD; for (xD = 0x1D00; xD < 0x1D00+len; xD++) {   \
+     register int xE; for (xE = 0x1E00; xE < 0x1E00+len; xE++) {   \
+     register int xF; for (xF = 0x1F00; xF < 0x1F00+len; xF++) {   \
+     /* */
+
+#define LOOPS_END \
+     assert(xF >= 0x1F00 && xF <= 0x1F00+len); }                   \
+     assert(xE >= 0x1E00 && xE <= 0x1E00+len); }                   \
+     assert(xD >= 0x1D00 && xD <= 0x1D00+len); }                   \
+     assert(xC >= 0x1C00 && xC <= 0x1C00+len); }                   \
+     assert(xB >= 0x1B00 && xB <= 0x1B00+len); }                   \
+     assert(xA >= 0x1A00 && xA <= 0x1A00+len); }                   \
+     assert(x9 >= 0x1900 && x9 <= 0x1900+len); }                   \
+     assert(x8 >= 0x1800 && x8 <= 0x1800+len); }                   \
+     assert(x7 >= 0x1700 && x7 <= 0x1700+len); }                   \
+     assert(x6 >= 0x1600 && x6 <= 0x1600+len); }                   \
+     assert(x5 >= 0x1500 && x5 <= 0x1500+len); }                   \
+     assert(x4 >= 0x1400 && x4 <= 0x1400+len); }                   \
+     assert(x3 >= 0x1300 && x3 <= 0x1300+len); }                   \
+     assert(x2 >= 0x1200 && x2 <= 0x1200+len); }                   \
+     assert(x1 >= 0x1100 && x1 <= 0x1100+len); }                   \
+     assert(x0 >= 0x1000 && x0 <= 0x1000+len); }                   \
+   }
+
+/* General idea is for the wrappers to use LOOPS_START / LOOPS_END to
+   soak up lots of int registers.  And the orig fn uses TRASH_IREGS to
+   do the same.  If there is insufficient saving of caller-saves regs
+   by the CALL_FN_* macros, then hopefully the assertions in LOOPS_END
+   will fail. */
+
 /* --------------- 0 --------------- */  
 
 UInt fn_0 ( void )
@@ -70,14 +134,16 @@
 
 UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_0) ( UInt a1 )
 {
-   UInt   r;
+   UInt   r = 0;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   printf("fn_0  wrapper pre ()\n");
-   CALL_FN_W_v(r, fn);
-   printf("fn_0  wrapper post1 = %d\n", (int)r);
-   CALL_FN_v_v(fn);
-   printf("fn_0  wrapper post2 = %d\n", (int)r);
+   LOOPS_START
+    printf("fn_0  wrapper pre ()\n");
+    CALL_FN_W_v(r, fn);
+    printf("fn_0  wrapper post1 = %d\n", (int)r);
+    CALL_FN_v_v(fn);
+    printf("fn_0  wrapper post2 = %d\n", (int)r);
+   LOOPS_END
    return r;
 }
 
@@ -95,14 +161,16 @@
 
 UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_1) ( UInt a1 )
 {
-   UInt   r;
+   UInt   r = 0;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   printf("fn_1  wrapper pre ( %d )\n", (int)a1);
-   CALL_FN_W_W(r, fn, a1);
-   printf("fn_1  wrapper post1 = %d\n", (int)r);
-   CALL_FN_v_W(fn, a1);
-   printf("fn_1  wrapper post2 = %d\n", (int)r);
+   LOOPS_START
+    printf("fn_1  wrapper pre ( %d )\n", (int)a1);
+    CALL_FN_W_W(r, fn, a1);
+    printf("fn_1  wrapper post1 = %d\n", (int)r);
+    CALL_FN_v_W(fn, a1);
+    printf("fn_1  wrapper post2 = %d\n", (int)r);
+   LOOPS_END
    return r;
 }
 
@@ -110,7 +178,7 @@
 
 UInt fn_2 ( UInt a1, UInt a2 )
 {
-   UInt r;
+   UInt r = 0;
    UInt* words = calloc(200, sizeof(UInt));
    words[1-1] = a1;
    words[2-1] = a2;
@@ -121,14 +189,370 @@
 
 UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_2) ( UInt a1, UInt a2 )
 {
-   UInt   r;
+   UInt   r = 0;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
-   printf("fn_2  wrapper pre ( %d, %d )\n", (int)a1, (int)a2);
-   CALL_FN_W_WW(r, fn, a1, a2);
-   printf("fn_2  wrapper post1 = %d\n", (int)r);
-   CALL_FN_v_WW(fn, a1, a2);
-   printf("fn_2  wrapper post2 = %d\n", (int)r);
+   LOOPS_START
+    printf("fn_2  wrapper pre ( %d, %d )\n", (int)a1, (int)a2);
+    CALL_FN_W_WW(r, fn, a1, a2);
+    printf("fn_2  wrapper post1 = %d\n", (int)r);
+    CALL_FN_v_WW(fn, a1, a2);
+    printf("fn_2  wrapper post2 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 3 --------------- */  
+
+UInt fn_3 ( UInt a1, UInt a2, UInt a3 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_3) ( UInt a1, UInt a2, UInt a3 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_3  wrapper pre ( %d, %d, %d )\n", (int)a1, (int)a2, (int)a3);
+    CALL_FN_W_WWW(r, fn, a1, a2, a3);
+    printf("fn_3  wrapper post1 = %d\n", (int)r);
+    CALL_FN_v_WWW(fn, a1, a2, a3);
+    printf("fn_3  wrapper post2 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 4 --------------- */  
+
+UInt fn_4 ( UInt a1, UInt a2, UInt a3, UInt a4 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_4) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_4  wrapper pre ( %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4);
+    CALL_FN_W_WWWW(r, fn, a1, a2, a3, a4);
+    printf("fn_4  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 5 --------------- */  
+
+UInt fn_5 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_5) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_5  wrapper pre ( %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5);
+    CALL_FN_W_5W(r, fn, a1, a2, a3, a4, a5);
+    printf("fn_5  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 6 --------------- */  
+
+UInt fn_6 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_6) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_6  wrapper pre ( %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6);
+    CALL_FN_W_6W(r, fn, a1, a2, a3, a4, a5, a6);
+    printf("fn_6  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 7 --------------- */  
+
+UInt fn_7 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+            UInt a7 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_7) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_7  wrapper pre ( %d, %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7);
+    CALL_FN_W_7W(r, fn, a1, a2, a3, a4, a5, a6, a7);
+    printf("fn_7  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 8 --------------- */  
+
+UInt fn_8 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+            UInt a7, UInt a8 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   words[8-1] = a8;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_8) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7, UInt a8 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_8  wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7, (int)a8);
+    CALL_FN_W_8W(r, fn, a1, a2, a3, a4, a5, a6, a7, a8);
+    printf("fn_8  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 9 --------------- */  
+
+UInt fn_9 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+            UInt a7, UInt a8, UInt a9 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   words[8-1] = a8;
+   words[9-1] = a9;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_9) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7, UInt a8, UInt a9 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_9  wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7, (int)a8, (int)a9);
+    CALL_FN_W_9W(r, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+    printf("fn_9  wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 10 --------------- */  
+
+UInt fn_10 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+             UInt a7, UInt a8, UInt a9, UInt a10 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   words[8-1] = a8;
+   words[9-1] = a9;
+   words[10-1] = a10;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_10) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7, UInt a8, UInt a9, UInt a10 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_10 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7, (int)a8, (int)a9, (int)a10);
+    CALL_FN_W_10W(r, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+    printf("fn_10 wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 11 --------------- */  
+
+UInt fn_11 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+             UInt a7, UInt a8, UInt a9, UInt a10, UInt a11 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   words[8-1] = a8;
+   words[9-1] = a9;
+   words[10-1] = a10;
+   words[11-1] = a11;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_11) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7, UInt a8, UInt a9, UInt a10, UInt a11 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_11 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7, (int)a8, (int)a9, (int)a10, (int)a11);
+    CALL_FN_W_11W(r, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+    printf("fn_11 wrapper post1 = %d\n", (int)r);
+   LOOPS_END
+   return r;
+}
+
+/* --------------- 12 --------------- */  
+
+UInt fn_12 ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+             UInt a7, UInt a8, UInt a9, UInt a10, UInt a11, UInt a12 )
+{
+   UInt r;
+   UInt* words = calloc(200, sizeof(UInt));
+   words[1-1] = a1;
+   words[2-1] = a2;
+   words[3-1] = a3;
+   words[4-1] = a4;
+   words[5-1] = a5;
+   words[6-1] = a6;
+   words[7-1] = a7;
+   words[8-1] = a8;
+   words[9-1] = a9;
+   words[10-1] = a10;
+   words[11-1] = a11;
+   words[12-1] = a12;
+   TRASH_IREGS(r, words);
+   free(words);
+   return r;
+}
+
+UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_12) 
+   ( UInt a1, UInt a2, UInt a3, UInt a4, UInt a5, UInt a6,
+     UInt a7, UInt a8, UInt a9, UInt a10, UInt a11, UInt a12 )
+{
+   UInt   r = 0;
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   LOOPS_START
+    printf("fn_12 wrapper pre ( %d, %d, %d, %d, %d, %d, "
+                               "%d, %d, %d, %d, %d, %d )\n", 
+           (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6,
+           (int)a7, (int)a8, (int)a9, (int)a10, (int)a11, (int)a12);
+    CALL_FN_W_12W(r, fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
+    printf("fn_12 wrapper post1 = %d\n", (int)r);
+   LOOPS_END
    return r;
 }
 
@@ -138,6 +562,8 @@
 {
    UInt w;
 
+   one_actual_return_value = 1;
+
    printf("fn_0  ...\n");
    w = fn_0();
    printf("      ...  %d\n\n", (int)w);
@@ -150,6 +576,45 @@
    w = fn_2(42,43);
    printf("      ...  %d\n\n", (int)w);
 
+   printf("fn_3  ...\n");
+   w = fn_3(42,43,44);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_4  ...\n");
+   w = fn_4(42,43,44,45);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_5  ...\n");
+   w = fn_5(42,43,44,45,46);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_6  ...\n");
+   w = fn_6(42,43,44,45,46,47);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_7  ...\n");
+   w = fn_7(42,43,44,45,46,47,48);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_8  ...\n");
+   w = fn_8(42,43,44,45,46,47,48,49);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_9  ...\n");
+   w = fn_9(42,43,44,45,46,47,48,49,50);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_10 ...\n");
+   w = fn_10(42,43,44,45,46,47,48,49,50,51);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_11 ...\n");
+   w = fn_11(42,43,44,45,46,47,48,49,50,51,52);
+   printf("      ...  %d\n\n", (int)w);
+
+   printf("fn_12 ...\n");
+   w = fn_12(42,43,44,45,46,47,48,49,50,51,52,53);
+   printf("      ...  %d\n\n", (int)w);
+
    return 0;
 }
-
diff --git a/memcheck/tests/wrap6.stdout.exp b/memcheck/tests/wrap6.stdout.exp
index d98608e..708b6fe 100644
--- a/memcheck/tests/wrap6.stdout.exp
+++ b/memcheck/tests/wrap6.stdout.exp
@@ -16,3 +16,54 @@
 fn_2  wrapper post2 = 201956282
       ...  201956282
 
+fn_3  ...
+fn_3  wrapper pre ( 42, 43, 44 )
+fn_3  wrapper post1 = -1985342033
+fn_3  wrapper post2 = -1985342033
+      ...  -1985342033
+
+fn_4  ...
+fn_4  wrapper pre ( 42, 43, 44, 45 )
+fn_4  wrapper post1 = 1119208547
+      ...  1119208547
+
+fn_5  ...
+fn_5  wrapper pre ( 42, 43, 44, 45, 46 )
+fn_5  wrapper post1 = -1638411058
+      ...  -1638411058
+
+fn_6  ...
+fn_6  wrapper pre ( 42, 43, 44, 45, 46, 47 )
+fn_6  wrapper post1 = 379190336
+      ...  379190336
+
+fn_7  ...
+fn_7  wrapper pre ( 42, 43, 44, 45, 46, 47, 48 )
+fn_7  wrapper post1 = -1634577206
+      ...  -1634577206
+
+fn_8  ...
+fn_8  wrapper pre ( 42, 43, 44, 45, 46, 47, 48, 49 )
+fn_8  wrapper post1 = 1977785290
+      ...  1977785290
+
+fn_9  ...
+fn_9  wrapper pre ( 42, 43, 44, 45, 46, 47, 48, 49, 50 )
+fn_9  wrapper post1 = -892905021
+      ...  -892905021
+
+fn_10 ...
+fn_10 wrapper pre ( 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 )
+fn_10 wrapper post1 = -726791237
+      ...  -726791237
+
+fn_11 ...
+fn_11 wrapper pre ( 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 )
+fn_11 wrapper post1 = 951678589
+      ...  951678589
+
+fn_12 ...
+fn_12 wrapper pre ( 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 )
+fn_12 wrapper post1 = 1071266195
+      ...  1071266195
+