Fix the GObject Visual Studio Projects
[platform/upstream/glib.git] / glib / valgrind.h
1 /* -*- c -*-
2    ----------------------------------------------------------------
3
4    Notice that the following BSD-style license applies to this one
5    file (valgrind.h) only.  The rest of Valgrind is licensed under the
6    terms of the GNU General Public License, version 2, unless
7    otherwise indicated.  See the COPYING file in the source
8    distribution for details.
9
10    ----------------------------------------------------------------
11
12    This file is part of Valgrind, a dynamic binary instrumentation
13    framework.
14
15    Copyright (C) 2000-2012 Julian Seward.  All rights reserved.
16
17    Redistribution and use in source and binary forms, with or without
18    modification, are permitted provided that the following conditions
19    are met:
20
21    1. Redistributions of source code must retain the above copyright
22       notice, this list of conditions and the following disclaimer.
23
24    2. The origin of this software must not be misrepresented; you must 
25       not claim that you wrote the original software.  If you use this 
26       software in a product, an acknowledgment in the product 
27       documentation would be appreciated but is not required.
28
29    3. Altered source versions must be plainly marked as such, and must
30       not be misrepresented as being the original software.
31
32    4. The name of the author may not be used to endorse or promote 
33       products derived from this software without specific prior written 
34       permission.
35
36    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48    ----------------------------------------------------------------
49
50    Notice that the above BSD-style license applies to this one file
51    (valgrind.h) only.  The entire rest of Valgrind is licensed under
52    the terms of the GNU General Public License, version 2.  See the
53    COPYING file in the source distribution for details.
54
55    ---------------------------------------------------------------- 
56 */
57
58
59 /* This file is for inclusion into client (your!) code.
60
61    You can use these macros to manipulate and query Valgrind's 
62    execution inside your own programs.
63
64    The resulting executables will still run without Valgrind, just a
65    little bit more slowly than they otherwise would, but otherwise
66    unchanged.  When not running on valgrind, each client request
67    consumes very few (eg. 7) instructions, so the resulting performance
68    loss is negligible unless you plan to execute client requests
69    millions of times per second.  Nevertheless, if that is still a
70    problem, you can compile with the NVALGRIND symbol defined (gcc
71    -DNVALGRIND) so that client requests are not even compiled in.  */
72
73 #ifndef __VALGRIND_H
74 #define __VALGRIND_H
75
76
77 /* ------------------------------------------------------------------ */
78 /* VERSION NUMBER OF VALGRIND                                         */
79 /* ------------------------------------------------------------------ */
80
81 /* Specify Valgrind's version number, so that user code can
82    conditionally compile based on our version number.  Note that these
83    were introduced at version 3.6 and so do not exist in version 3.5
84    or earlier.  The recommended way to use them to check for "version
85    X.Y or later" is (eg)
86
87 #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
88     && (__VALGRIND_MAJOR__ > 3                                   \
89         || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
90 */
91 #define __VALGRIND_MAJOR__    3
92 #define __VALGRIND_MINOR__    8
93
94
95 #include <stdarg.h>
96
97 /* Nb: this file might be included in a file compiled with -ansi.  So
98    we can't use C++ style "//" comments nor the "asm" keyword (instead
99    use "__asm__"). */
100
101 /* Derive some tags indicating what the target platform is.  Note
102    that in this file we're using the compiler's CPP symbols for
103    identifying architectures, which are different to the ones we use
104    within the rest of Valgrind.  Note, __powerpc__ is active for both
105    32 and 64-bit PPC, whereas __powerpc64__ is only active for the
106    latter (on Linux, that is).
107
108    Misc note: how to find out what's predefined in gcc by default:
109    gcc -Wp,-dM somefile.c
110 */
111 #undef PLAT_x86_darwin
112 #undef PLAT_amd64_darwin
113 #undef PLAT_x86_win32
114 #undef PLAT_x86_linux
115 #undef PLAT_amd64_linux
116 #undef PLAT_ppc32_linux
117 #undef PLAT_ppc64_linux
118 #undef PLAT_arm_linux
119 #undef PLAT_s390x_linux
120 #undef PLAT_mips32_linux
121
122
123 #if defined(__APPLE__) && defined(__i386__)
124 #  define PLAT_x86_darwin 1
125 #elif defined(__APPLE__) && defined(__x86_64__)
126 #  define PLAT_amd64_darwin 1
127 #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
128       || (defined(_WIN32) && defined(_M_IX86))
129 #  define PLAT_x86_win32 1
130 #elif defined(__linux__) && defined(__i386__)
131 #  define PLAT_x86_linux 1
132 #elif defined(__linux__) && defined(__x86_64__)
133 #  define PLAT_amd64_linux 1
134 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
135 #  define PLAT_ppc32_linux 1
136 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
137 #  define PLAT_ppc64_linux 1
138 #elif defined(__linux__) && defined(__arm__)
139 #  define PLAT_arm_linux 1
140 #elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
141 #  define PLAT_s390x_linux 1
142 #elif defined(__linux__) && defined(__mips__)
143 #  define PLAT_mips32_linux 1
144 #else
145 /* If we're not compiling for our target platform, don't generate
146    any inline asms.  */
147 #  if !defined(NVALGRIND)
148 #    define NVALGRIND 1
149 #  endif
150 #endif
151
152
153 /* ------------------------------------------------------------------ */
154 /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
155 /* in here of use to end-users -- skip to the next section.           */
156 /* ------------------------------------------------------------------ */
157
158 /*
159  * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
160  * request. Accepts both pointers and integers as arguments.
161  *
162  * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
163  * client request that does not return a value.
164
165  * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
166  * client request and whose value equals the client request result.  Accepts
167  * both pointers and integers as arguments.  Note that such calls are not
168  * necessarily pure functions -- they may have side effects.
169  */
170
171 #define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
172                                    _zzq_request, _zzq_arg1, _zzq_arg2,  \
173                                    _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
174   do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
175                         (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
176                         (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
177
178 #define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
179                            _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
180   do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
181                     (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
182                     (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
183
184 #if defined(NVALGRIND)
185
186 /* Define NVALGRIND to completely remove the Valgrind magic sequence
187    from the compiled code (analogous to NDEBUG's effects on
188    assert()) */
189 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
190         _zzq_default, _zzq_request,                               \
191         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
192       (_zzq_default)
193
194 #else  /* ! NVALGRIND */
195
196 /* The following defines the magic code sequences which the JITter
197    spots and handles magically.  Don't look too closely at them as
198    they will rot your brain.
199
200    The assembly code sequences for all architectures is in this one
201    file.  This is because this file must be stand-alone, and we don't
202    want to have multiple files.
203
204    For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
205    value gets put in the return slot, so that everything works when
206    this is executed not under Valgrind.  Args are passed in a memory
207    block, and so there's no intrinsic limit to the number that could
208    be passed, but it's currently five.
209    
210    The macro args are: 
211       _zzq_rlval    result lvalue
212       _zzq_default  default value (result returned when running on real CPU)
213       _zzq_request  request code
214       _zzq_arg1..5  request params
215
216    The other two macros are used to support function wrapping, and are
217    a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
218    guest's NRADDR pseudo-register and whatever other information is
219    needed to safely run the call original from the wrapper: on
220    ppc64-linux, the R2 value at the divert point is also needed.  This
221    information is abstracted into a user-visible type, OrigFn.
222
223    VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
224    guest, but guarantees that the branch instruction will not be
225    redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
226    branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
227    complete inline asm, since it needs to be combined with more magic
228    inline asm stuff to be useful.
229 */
230
231 /* ------------------------- x86-{linux,darwin} ---------------- */
232
233 #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
234     ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
235
236 typedef
237    struct { 
238       unsigned int nraddr; /* where's the code? */
239    }
240    OrigFn;
241
242 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
243                      "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
244                      "roll $29, %%edi ; roll $19, %%edi\n\t"
245
246 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
247         _zzq_default, _zzq_request,                               \
248         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
249   __extension__                                                   \
250   ({volatile unsigned int _zzq_args[6];                           \
251     volatile unsigned int _zzq_result;                            \
252     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
253     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
254     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
255     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
256     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
257     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
258     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
259                      /* %EDX = client_request ( %EAX ) */         \
260                      "xchgl %%ebx,%%ebx"                          \
261                      : "=d" (_zzq_result)                         \
262                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
263                      : "cc", "memory"                             \
264                     );                                            \
265     _zzq_result;                                                  \
266   })
267
268 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
269   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
270     volatile unsigned int __addr;                                 \
271     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
272                      /* %EAX = guest_NRADDR */                    \
273                      "xchgl %%ecx,%%ecx"                          \
274                      : "=a" (__addr)                              \
275                      :                                            \
276                      : "cc", "memory"                             \
277                     );                                            \
278     _zzq_orig->nraddr = __addr;                                   \
279   }
280
281 #define VALGRIND_CALL_NOREDIR_EAX                                 \
282                      __SPECIAL_INSTRUCTION_PREAMBLE               \
283                      /* call-noredir *%EAX */                     \
284                      "xchgl %%edx,%%edx\n\t"
285 #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
286
287 /* ------------------------- x86-Win32 ------------------------- */
288
289 #if defined(PLAT_x86_win32) && !defined(__GNUC__)
290
291 typedef
292    struct { 
293       unsigned int nraddr; /* where's the code? */
294    }
295    OrigFn;
296
297 #if defined(_MSC_VER)
298
299 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
300                      __asm rol edi, 3  __asm rol edi, 13          \
301                      __asm rol edi, 29 __asm rol edi, 19
302
303 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
304         _zzq_default, _zzq_request,                               \
305         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
306     valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
307         (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
308         (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
309         (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
310
311 static __inline uintptr_t
312 valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
313                                 uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
314                                 uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
315                                 uintptr_t _zzq_arg5)
316 {
317     volatile uintptr_t _zzq_args[6];
318     volatile unsigned int _zzq_result;
319     _zzq_args[0] = (uintptr_t)(_zzq_request);
320     _zzq_args[1] = (uintptr_t)(_zzq_arg1);
321     _zzq_args[2] = (uintptr_t)(_zzq_arg2);
322     _zzq_args[3] = (uintptr_t)(_zzq_arg3);
323     _zzq_args[4] = (uintptr_t)(_zzq_arg4);
324     _zzq_args[5] = (uintptr_t)(_zzq_arg5);
325     __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
326             __SPECIAL_INSTRUCTION_PREAMBLE
327             /* %EDX = client_request ( %EAX ) */
328             __asm xchg ebx,ebx
329             __asm mov _zzq_result, edx
330     }
331     return _zzq_result;
332 }
333
334 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
335   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
336     volatile unsigned int __addr;                                 \
337     __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
338             /* %EAX = guest_NRADDR */                             \
339             __asm xchg ecx,ecx                                    \
340             __asm mov __addr, eax                                 \
341     }                                                             \
342     _zzq_orig->nraddr = __addr;                                   \
343   }
344
345 #define VALGRIND_CALL_NOREDIR_EAX ERROR
346
347 #else
348 #error Unsupported compiler.
349 #endif
350
351 #endif /* PLAT_x86_win32 */
352
353 /* ------------------------ amd64-{linux,darwin} --------------- */
354
355 #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
356
357 typedef
358    struct { 
359       unsigned long long int nraddr; /* where's the code? */
360    }
361    OrigFn;
362
363 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
364                      "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
365                      "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
366
367 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
368         _zzq_default, _zzq_request,                               \
369         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
370     __extension__                                                 \
371     ({ volatile unsigned long long int _zzq_args[6];              \
372     volatile unsigned long long int _zzq_result;                  \
373     _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
374     _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
375     _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
376     _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
377     _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
378     _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
379     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
380                      /* %RDX = client_request ( %RAX ) */         \
381                      "xchgq %%rbx,%%rbx"                          \
382                      : "=d" (_zzq_result)                         \
383                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
384                      : "cc", "memory"                             \
385                     );                                            \
386     _zzq_result;                                                  \
387     })
388
389 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
390   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
391     volatile unsigned long long int __addr;                       \
392     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
393                      /* %RAX = guest_NRADDR */                    \
394                      "xchgq %%rcx,%%rcx"                          \
395                      : "=a" (__addr)                              \
396                      :                                            \
397                      : "cc", "memory"                             \
398                     );                                            \
399     _zzq_orig->nraddr = __addr;                                   \
400   }
401
402 #define VALGRIND_CALL_NOREDIR_RAX                                 \
403                      __SPECIAL_INSTRUCTION_PREAMBLE               \
404                      /* call-noredir *%RAX */                     \
405                      "xchgq %%rdx,%%rdx\n\t"
406 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
407
408 /* ------------------------ ppc32-linux ------------------------ */
409
410 #if defined(PLAT_ppc32_linux)
411
412 typedef
413    struct { 
414       unsigned int nraddr; /* where's the code? */
415    }
416    OrigFn;
417
418 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
419                      "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
420                      "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
421
422 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
423         _zzq_default, _zzq_request,                               \
424         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
425                                                                   \
426     __extension__                                                 \
427   ({         unsigned int  _zzq_args[6];                          \
428              unsigned int  _zzq_result;                           \
429              unsigned int* _zzq_ptr;                              \
430     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
431     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
432     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
433     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
434     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
435     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
436     _zzq_ptr = _zzq_args;                                         \
437     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
438                      "mr 4,%2\n\t" /*ptr*/                        \
439                      __SPECIAL_INSTRUCTION_PREAMBLE               \
440                      /* %R3 = client_request ( %R4 ) */           \
441                      "or 1,1,1\n\t"                               \
442                      "mr %0,3"     /*result*/                     \
443                      : "=b" (_zzq_result)                         \
444                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
445                      : "cc", "memory", "r3", "r4");               \
446     _zzq_result;                                                  \
447     })
448
449 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
450   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
451     unsigned int __addr;                                          \
452     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
453                      /* %R3 = guest_NRADDR */                     \
454                      "or 2,2,2\n\t"                               \
455                      "mr %0,3"                                    \
456                      : "=b" (__addr)                              \
457                      :                                            \
458                      : "cc", "memory", "r3"                       \
459                     );                                            \
460     _zzq_orig->nraddr = __addr;                                   \
461   }
462
463 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
464                      __SPECIAL_INSTRUCTION_PREAMBLE               \
465                      /* branch-and-link-to-noredir *%R11 */       \
466                      "or 3,3,3\n\t"
467 #endif /* PLAT_ppc32_linux */
468
469 /* ------------------------ ppc64-linux ------------------------ */
470
471 #if defined(PLAT_ppc64_linux)
472
473 typedef
474    struct { 
475       unsigned long long int nraddr; /* where's the code? */
476       unsigned long long int r2;  /* what tocptr do we need? */
477    }
478    OrigFn;
479
480 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
481                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
482                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
483
484 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
485         _zzq_default, _zzq_request,                               \
486         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
487                                                                   \
488   __extension__                                                   \
489   ({         unsigned long long int  _zzq_args[6];                \
490              unsigned long long int  _zzq_result;                 \
491              unsigned long long int* _zzq_ptr;                    \
492     _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
493     _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
494     _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
495     _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
496     _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
497     _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
498     _zzq_ptr = _zzq_args;                                         \
499     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
500                      "mr 4,%2\n\t" /*ptr*/                        \
501                      __SPECIAL_INSTRUCTION_PREAMBLE               \
502                      /* %R3 = client_request ( %R4 ) */           \
503                      "or 1,1,1\n\t"                               \
504                      "mr %0,3"     /*result*/                     \
505                      : "=b" (_zzq_result)                         \
506                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
507                      : "cc", "memory", "r3", "r4");               \
508     _zzq_result;                                                  \
509   })
510
511 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
512   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
513     unsigned long long int __addr;                                \
514     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
515                      /* %R3 = guest_NRADDR */                     \
516                      "or 2,2,2\n\t"                               \
517                      "mr %0,3"                                    \
518                      : "=b" (__addr)                              \
519                      :                                            \
520                      : "cc", "memory", "r3"                       \
521                     );                                            \
522     _zzq_orig->nraddr = __addr;                                   \
523     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
524                      /* %R3 = guest_NRADDR_GPR2 */                \
525                      "or 4,4,4\n\t"                               \
526                      "mr %0,3"                                    \
527                      : "=b" (__addr)                              \
528                      :                                            \
529                      : "cc", "memory", "r3"                       \
530                     );                                            \
531     _zzq_orig->r2 = __addr;                                       \
532   }
533
534 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
535                      __SPECIAL_INSTRUCTION_PREAMBLE               \
536                      /* branch-and-link-to-noredir *%R11 */       \
537                      "or 3,3,3\n\t"
538
539 #endif /* PLAT_ppc64_linux */
540
541 /* ------------------------- arm-linux ------------------------- */
542
543 #if defined(PLAT_arm_linux)
544
545 typedef
546    struct { 
547       unsigned int nraddr; /* where's the code? */
548    }
549    OrigFn;
550
551 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
552             "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
553             "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
554
555 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
556         _zzq_default, _zzq_request,                               \
557         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
558                                                                   \
559   __extension__                                                   \
560   ({volatile unsigned int  _zzq_args[6];                          \
561     volatile unsigned int  _zzq_result;                           \
562     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
563     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
564     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
565     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
566     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
567     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
568     __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
569                      "mov r4, %2\n\t" /*ptr*/                     \
570                      __SPECIAL_INSTRUCTION_PREAMBLE               \
571                      /* R3 = client_request ( R4 ) */             \
572                      "orr r10, r10, r10\n\t"                      \
573                      "mov %0, r3"     /*result*/                  \
574                      : "=r" (_zzq_result)                         \
575                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
576                      : "cc","memory", "r3", "r4");                \
577     _zzq_result;                                                  \
578   })
579
580 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
581   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
582     unsigned int __addr;                                          \
583     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
584                      /* R3 = guest_NRADDR */                      \
585                      "orr r11, r11, r11\n\t"                      \
586                      "mov %0, r3"                                 \
587                      : "=r" (__addr)                              \
588                      :                                            \
589                      : "cc", "memory", "r3"                       \
590                     );                                            \
591     _zzq_orig->nraddr = __addr;                                   \
592   }
593
594 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
595                      __SPECIAL_INSTRUCTION_PREAMBLE               \
596                      /* branch-and-link-to-noredir *%R4 */        \
597                      "orr r12, r12, r12\n\t"
598
599 #endif /* PLAT_arm_linux */
600
601 /* ------------------------ s390x-linux ------------------------ */
602
603 #if defined(PLAT_s390x_linux)
604
605 typedef
606   struct {
607      unsigned long long int nraddr; /* where's the code? */
608   }
609   OrigFn;
610
611 /* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
612  * code. This detection is implemented in platform specific toIR.c
613  * (e.g. VEX/priv/guest_s390_decoder.c).
614  */
615 #define __SPECIAL_INSTRUCTION_PREAMBLE                           \
616                      "lr 15,15\n\t"                              \
617                      "lr 1,1\n\t"                                \
618                      "lr 2,2\n\t"                                \
619                      "lr 3,3\n\t"
620
621 #define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
622 #define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
623 #define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
624
625 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
626        _zzq_default, _zzq_request,                               \
627        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
628   __extension__                                                  \
629  ({volatile unsigned long long int _zzq_args[6];                 \
630    volatile unsigned long long int _zzq_result;                  \
631    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
632    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
633    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
634    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
635    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
636    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
637    __asm__ volatile(/* r2 = args */                              \
638                     "lgr 2,%1\n\t"                               \
639                     /* r3 = default */                           \
640                     "lgr 3,%2\n\t"                               \
641                     __SPECIAL_INSTRUCTION_PREAMBLE               \
642                     __CLIENT_REQUEST_CODE                        \
643                     /* results = r3 */                           \
644                     "lgr %0, 3\n\t"                              \
645                     : "=d" (_zzq_result)                         \
646                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
647                     : "cc", "2", "3", "memory"                   \
648                    );                                            \
649    _zzq_result;                                                  \
650  })
651
652 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
653  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
654    volatile unsigned long long int __addr;                       \
655    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
656                     __GET_NR_CONTEXT_CODE                        \
657                     "lgr %0, 3\n\t"                              \
658                     : "=a" (__addr)                              \
659                     :                                            \
660                     : "cc", "3", "memory"                        \
661                    );                                            \
662    _zzq_orig->nraddr = __addr;                                   \
663  }
664
665 #define VALGRIND_CALL_NOREDIR_R1                                 \
666                     __SPECIAL_INSTRUCTION_PREAMBLE               \
667                     __CALL_NO_REDIR_CODE
668
669 #endif /* PLAT_s390x_linux */
670
671 /* ------------------------- mips32-linux ---------------- */
672
673 #if defined(PLAT_mips32_linux)
674
675 typedef
676    struct { 
677       unsigned int nraddr; /* where's the code? */
678    }
679    OrigFn;
680
681 /* .word  0x342
682  * .word  0x742
683  * .word  0xC2
684  * .word  0x4C2*/
685 #define __SPECIAL_INSTRUCTION_PREAMBLE          \
686                      "srl $0, $0, 13\n\t"       \
687                      "srl $0, $0, 29\n\t"       \
688                      "srl $0, $0, 3\n\t"        \
689                      "srl $0, $0, 19\n\t"
690                     
691 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
692        _zzq_default, _zzq_request,                                \
693        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
694   __extension__                                                   \
695   ({ volatile unsigned int _zzq_args[6];                          \
696     volatile unsigned int _zzq_result;                            \
697     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
698     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
699     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
700     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
701     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
702     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
703         __asm__ volatile("move $11, %1\n\t" /*default*/           \
704                      "move $12, %2\n\t" /*ptr*/                   \
705                      __SPECIAL_INSTRUCTION_PREAMBLE               \
706                      /* T3 = client_request ( T4 ) */             \
707                      "or $13, $13, $13\n\t"                       \
708                      "move %0, $11\n\t"     /*result*/            \
709                      : "=r" (_zzq_result)                         \
710                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
711                      : "cc","memory", "t3", "t4");                \
712     _zzq_result;                                                  \
713   })
714
715 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
716   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
717     volatile unsigned int __addr;                                 \
718     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
719                      /* %t9 = guest_NRADDR */                     \
720                      "or $14, $14, $14\n\t"                       \
721                      "move %0, $11"     /*result*/                \
722                      : "=r" (__addr)                              \
723                      :                                            \
724                      : "cc", "memory" , "t3"                      \
725                     );                                            \
726     _zzq_orig->nraddr = __addr;                                   \
727   }
728
729 #define VALGRIND_CALL_NOREDIR_T9                                 \
730                      __SPECIAL_INSTRUCTION_PREAMBLE              \
731                      /* call-noredir *%t9 */                     \
732                      "or $15, $15, $15\n\t"                                             
733 #endif /* PLAT_mips32_linux */
734
735 /* Insert assembly code for other platforms here... */
736
737 #endif /* NVALGRIND */
738
739
740 /* ------------------------------------------------------------------ */
741 /* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
742 /* ugly.  It's the least-worst tradeoff I can think of.               */
743 /* ------------------------------------------------------------------ */
744
745 /* This section defines magic (a.k.a appalling-hack) macros for doing
746    guaranteed-no-redirection macros, so as to get from function
747    wrappers to the functions they are wrapping.  The whole point is to
748    construct standard call sequences, but to do the call itself with a
749    special no-redirect call pseudo-instruction that the JIT
750    understands and handles specially.  This section is long and
751    repetitious, and I can't see a way to make it shorter.
752
753    The naming scheme is as follows:
754
755       CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
756
757    'W' stands for "word" and 'v' for "void".  Hence there are
758    different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
759    and for each, the possibility of returning a word-typed result, or
760    no result.
761 */
762
763 /* Use these to write the name of your wrapper.  NOTE: duplicates
764    VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
765    the default behaviour equivalance class tag "0000" into the name.
766    See pub_tool_redir.h for details -- normally you don't need to
767    think about this, though. */
768
769 /* Use an extra level of macroisation so as to ensure the soname/fnname
770    args are fully macro-expanded before pasting them together. */
771 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
772
773 #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
774    VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
775
776 #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
777    VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
778
779 /* Use this macro from within a wrapper function to collect the
780    context (address and possibly other info) of the original function.
781    Once you have that you can then use it in one of the CALL_FN_
782    macros.  The type of the argument _lval is OrigFn. */
783 #define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
784
785 /* Also provide end-user facilities for function replacement, rather
786    than wrapping.  A replacement function differs from a wrapper in
787    that it has no way to get hold of the original function being
788    called, and hence no way to call onwards to it.  In a replacement
789    function, VALGRIND_GET_ORIG_FN always returns zero. */
790
791 #define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
792    VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
793
794 #define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
795    VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
796
797 /* Derivatives of the main macros below, for calling functions
798    returning void. */
799
800 #define CALL_FN_v_v(fnptr)                                        \
801    do { volatile unsigned long _junk;                             \
802         CALL_FN_W_v(_junk,fnptr); } while (0)
803
804 #define CALL_FN_v_W(fnptr, arg1)                                  \
805    do { volatile unsigned long _junk;                             \
806         CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
807
808 #define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
809    do { volatile unsigned long _junk;                             \
810         CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
811
812 #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
813    do { volatile unsigned long _junk;                             \
814         CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
815
816 #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
817    do { volatile unsigned long _junk;                             \
818         CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
819
820 #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
821    do { volatile unsigned long _junk;                             \
822         CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
823
824 #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
825    do { volatile unsigned long _junk;                             \
826         CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
827
828 #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
829    do { volatile unsigned long _junk;                             \
830         CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
831
832 /* ------------------------- x86-{linux,darwin} ---------------- */
833
834 #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
835
836 /* These regs are trashed by the hidden call.  No need to mention eax
837    as gcc can already see that, plus causes gcc to bomb. */
838 #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
839
840 /* Macros to save and align the stack before making a function
841    call and restore it afterwards as gcc may not keep the stack
842    pointer aligned if it doesn't realise calls are being made
843    to other functions. */
844
845 #define VALGRIND_ALIGN_STACK               \
846       "movl %%esp,%%edi\n\t"               \
847       "andl $0xfffffff0,%%esp\n\t"
848 #define VALGRIND_RESTORE_STACK             \
849       "movl %%edi,%%esp\n\t"
850
851 /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
852    long) == 4. */
853
854 #define CALL_FN_W_v(lval, orig)                                   \
855    do {                                                           \
856       volatile OrigFn        _orig = (orig);                      \
857       volatile unsigned long _argvec[1];                          \
858       volatile unsigned long _res;                                \
859       _argvec[0] = (unsigned long)_orig.nraddr;                   \
860       __asm__ volatile(                                           \
861          VALGRIND_ALIGN_STACK                                     \
862          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
863          VALGRIND_CALL_NOREDIR_EAX                                \
864          VALGRIND_RESTORE_STACK                                   \
865          : /*out*/   "=a" (_res)                                  \
866          : /*in*/    "a" (&_argvec[0])                            \
867          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
868       );                                                          \
869       lval = (__typeof__(lval)) _res;                             \
870    } while (0)
871
872 #define CALL_FN_W_W(lval, orig, arg1)                             \
873    do {                                                           \
874       volatile OrigFn        _orig = (orig);                      \
875       volatile unsigned long _argvec[2];                          \
876       volatile unsigned long _res;                                \
877       _argvec[0] = (unsigned long)_orig.nraddr;                   \
878       _argvec[1] = (unsigned long)(arg1);                         \
879       __asm__ volatile(                                           \
880          VALGRIND_ALIGN_STACK                                     \
881          "subl $12, %%esp\n\t"                                    \
882          "pushl 4(%%eax)\n\t"                                     \
883          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
884          VALGRIND_CALL_NOREDIR_EAX                                \
885          VALGRIND_RESTORE_STACK                                   \
886          : /*out*/   "=a" (_res)                                  \
887          : /*in*/    "a" (&_argvec[0])                            \
888          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
889       );                                                          \
890       lval = (__typeof__(lval)) _res;                             \
891    } while (0)
892
893 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
894    do {                                                           \
895       volatile OrigFn        _orig = (orig);                      \
896       volatile unsigned long _argvec[3];                          \
897       volatile unsigned long _res;                                \
898       _argvec[0] = (unsigned long)_orig.nraddr;                   \
899       _argvec[1] = (unsigned long)(arg1);                         \
900       _argvec[2] = (unsigned long)(arg2);                         \
901       __asm__ volatile(                                           \
902          VALGRIND_ALIGN_STACK                                     \
903          "subl $8, %%esp\n\t"                                     \
904          "pushl 8(%%eax)\n\t"                                     \
905          "pushl 4(%%eax)\n\t"                                     \
906          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
907          VALGRIND_CALL_NOREDIR_EAX                                \
908          VALGRIND_RESTORE_STACK                                   \
909          : /*out*/   "=a" (_res)                                  \
910          : /*in*/    "a" (&_argvec[0])                            \
911          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
912       );                                                          \
913       lval = (__typeof__(lval)) _res;                             \
914    } while (0)
915
916 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
917    do {                                                           \
918       volatile OrigFn        _orig = (orig);                      \
919       volatile unsigned long _argvec[4];                          \
920       volatile unsigned long _res;                                \
921       _argvec[0] = (unsigned long)_orig.nraddr;                   \
922       _argvec[1] = (unsigned long)(arg1);                         \
923       _argvec[2] = (unsigned long)(arg2);                         \
924       _argvec[3] = (unsigned long)(arg3);                         \
925       __asm__ volatile(                                           \
926          VALGRIND_ALIGN_STACK                                     \
927          "subl $4, %%esp\n\t"                                     \
928          "pushl 12(%%eax)\n\t"                                    \
929          "pushl 8(%%eax)\n\t"                                     \
930          "pushl 4(%%eax)\n\t"                                     \
931          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
932          VALGRIND_CALL_NOREDIR_EAX                                \
933          VALGRIND_RESTORE_STACK                                   \
934          : /*out*/   "=a" (_res)                                  \
935          : /*in*/    "a" (&_argvec[0])                            \
936          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
937       );                                                          \
938       lval = (__typeof__(lval)) _res;                             \
939    } while (0)
940
941 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
942    do {                                                           \
943       volatile OrigFn        _orig = (orig);                      \
944       volatile unsigned long _argvec[5];                          \
945       volatile unsigned long _res;                                \
946       _argvec[0] = (unsigned long)_orig.nraddr;                   \
947       _argvec[1] = (unsigned long)(arg1);                         \
948       _argvec[2] = (unsigned long)(arg2);                         \
949       _argvec[3] = (unsigned long)(arg3);                         \
950       _argvec[4] = (unsigned long)(arg4);                         \
951       __asm__ volatile(                                           \
952          VALGRIND_ALIGN_STACK                                     \
953          "pushl 16(%%eax)\n\t"                                    \
954          "pushl 12(%%eax)\n\t"                                    \
955          "pushl 8(%%eax)\n\t"                                     \
956          "pushl 4(%%eax)\n\t"                                     \
957          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
958          VALGRIND_CALL_NOREDIR_EAX                                \
959          VALGRIND_RESTORE_STACK                                   \
960          : /*out*/   "=a" (_res)                                  \
961          : /*in*/    "a" (&_argvec[0])                            \
962          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
963       );                                                          \
964       lval = (__typeof__(lval)) _res;                             \
965    } while (0)
966
967 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
968    do {                                                           \
969       volatile OrigFn        _orig = (orig);                      \
970       volatile unsigned long _argvec[6];                          \
971       volatile unsigned long _res;                                \
972       _argvec[0] = (unsigned long)_orig.nraddr;                   \
973       _argvec[1] = (unsigned long)(arg1);                         \
974       _argvec[2] = (unsigned long)(arg2);                         \
975       _argvec[3] = (unsigned long)(arg3);                         \
976       _argvec[4] = (unsigned long)(arg4);                         \
977       _argvec[5] = (unsigned long)(arg5);                         \
978       __asm__ volatile(                                           \
979          VALGRIND_ALIGN_STACK                                     \
980          "subl $12, %%esp\n\t"                                    \
981          "pushl 20(%%eax)\n\t"                                    \
982          "pushl 16(%%eax)\n\t"                                    \
983          "pushl 12(%%eax)\n\t"                                    \
984          "pushl 8(%%eax)\n\t"                                     \
985          "pushl 4(%%eax)\n\t"                                     \
986          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
987          VALGRIND_CALL_NOREDIR_EAX                                \
988          VALGRIND_RESTORE_STACK                                   \
989          : /*out*/   "=a" (_res)                                  \
990          : /*in*/    "a" (&_argvec[0])                            \
991          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
992       );                                                          \
993       lval = (__typeof__(lval)) _res;                             \
994    } while (0)
995
996 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
997    do {                                                           \
998       volatile OrigFn        _orig = (orig);                      \
999       volatile unsigned long _argvec[7];                          \
1000       volatile unsigned long _res;                                \
1001       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1002       _argvec[1] = (unsigned long)(arg1);                         \
1003       _argvec[2] = (unsigned long)(arg2);                         \
1004       _argvec[3] = (unsigned long)(arg3);                         \
1005       _argvec[4] = (unsigned long)(arg4);                         \
1006       _argvec[5] = (unsigned long)(arg5);                         \
1007       _argvec[6] = (unsigned long)(arg6);                         \
1008       __asm__ volatile(                                           \
1009          VALGRIND_ALIGN_STACK                                     \
1010          "subl $8, %%esp\n\t"                                     \
1011          "pushl 24(%%eax)\n\t"                                    \
1012          "pushl 20(%%eax)\n\t"                                    \
1013          "pushl 16(%%eax)\n\t"                                    \
1014          "pushl 12(%%eax)\n\t"                                    \
1015          "pushl 8(%%eax)\n\t"                                     \
1016          "pushl 4(%%eax)\n\t"                                     \
1017          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1018          VALGRIND_CALL_NOREDIR_EAX                                \
1019          VALGRIND_RESTORE_STACK                                   \
1020          : /*out*/   "=a" (_res)                                  \
1021          : /*in*/    "a" (&_argvec[0])                            \
1022          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1023       );                                                          \
1024       lval = (__typeof__(lval)) _res;                             \
1025    } while (0)
1026
1027 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1028                                  arg7)                            \
1029    do {                                                           \
1030       volatile OrigFn        _orig = (orig);                      \
1031       volatile unsigned long _argvec[8];                          \
1032       volatile unsigned long _res;                                \
1033       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1034       _argvec[1] = (unsigned long)(arg1);                         \
1035       _argvec[2] = (unsigned long)(arg2);                         \
1036       _argvec[3] = (unsigned long)(arg3);                         \
1037       _argvec[4] = (unsigned long)(arg4);                         \
1038       _argvec[5] = (unsigned long)(arg5);                         \
1039       _argvec[6] = (unsigned long)(arg6);                         \
1040       _argvec[7] = (unsigned long)(arg7);                         \
1041       __asm__ volatile(                                           \
1042          VALGRIND_ALIGN_STACK                                     \
1043          "subl $4, %%esp\n\t"                                     \
1044          "pushl 28(%%eax)\n\t"                                    \
1045          "pushl 24(%%eax)\n\t"                                    \
1046          "pushl 20(%%eax)\n\t"                                    \
1047          "pushl 16(%%eax)\n\t"                                    \
1048          "pushl 12(%%eax)\n\t"                                    \
1049          "pushl 8(%%eax)\n\t"                                     \
1050          "pushl 4(%%eax)\n\t"                                     \
1051          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1052          VALGRIND_CALL_NOREDIR_EAX                                \
1053          VALGRIND_RESTORE_STACK                                   \
1054          : /*out*/   "=a" (_res)                                  \
1055          : /*in*/    "a" (&_argvec[0])                            \
1056          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1057       );                                                          \
1058       lval = (__typeof__(lval)) _res;                             \
1059    } while (0)
1060
1061 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1062                                  arg7,arg8)                       \
1063    do {                                                           \
1064       volatile OrigFn        _orig = (orig);                      \
1065       volatile unsigned long _argvec[9];                          \
1066       volatile unsigned long _res;                                \
1067       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1068       _argvec[1] = (unsigned long)(arg1);                         \
1069       _argvec[2] = (unsigned long)(arg2);                         \
1070       _argvec[3] = (unsigned long)(arg3);                         \
1071       _argvec[4] = (unsigned long)(arg4);                         \
1072       _argvec[5] = (unsigned long)(arg5);                         \
1073       _argvec[6] = (unsigned long)(arg6);                         \
1074       _argvec[7] = (unsigned long)(arg7);                         \
1075       _argvec[8] = (unsigned long)(arg8);                         \
1076       __asm__ volatile(                                           \
1077          VALGRIND_ALIGN_STACK                                     \
1078          "pushl 32(%%eax)\n\t"                                    \
1079          "pushl 28(%%eax)\n\t"                                    \
1080          "pushl 24(%%eax)\n\t"                                    \
1081          "pushl 20(%%eax)\n\t"                                    \
1082          "pushl 16(%%eax)\n\t"                                    \
1083          "pushl 12(%%eax)\n\t"                                    \
1084          "pushl 8(%%eax)\n\t"                                     \
1085          "pushl 4(%%eax)\n\t"                                     \
1086          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1087          VALGRIND_CALL_NOREDIR_EAX                                \
1088          VALGRIND_RESTORE_STACK                                   \
1089          : /*out*/   "=a" (_res)                                  \
1090          : /*in*/    "a" (&_argvec[0])                            \
1091          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1092       );                                                          \
1093       lval = (__typeof__(lval)) _res;                             \
1094    } while (0)
1095
1096 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1097                                  arg7,arg8,arg9)                  \
1098    do {                                                           \
1099       volatile OrigFn        _orig = (orig);                      \
1100       volatile unsigned long _argvec[10];                         \
1101       volatile unsigned long _res;                                \
1102       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1103       _argvec[1] = (unsigned long)(arg1);                         \
1104       _argvec[2] = (unsigned long)(arg2);                         \
1105       _argvec[3] = (unsigned long)(arg3);                         \
1106       _argvec[4] = (unsigned long)(arg4);                         \
1107       _argvec[5] = (unsigned long)(arg5);                         \
1108       _argvec[6] = (unsigned long)(arg6);                         \
1109       _argvec[7] = (unsigned long)(arg7);                         \
1110       _argvec[8] = (unsigned long)(arg8);                         \
1111       _argvec[9] = (unsigned long)(arg9);                         \
1112       __asm__ volatile(                                           \
1113          VALGRIND_ALIGN_STACK                                     \
1114          "subl $12, %%esp\n\t"                                    \
1115          "pushl 36(%%eax)\n\t"                                    \
1116          "pushl 32(%%eax)\n\t"                                    \
1117          "pushl 28(%%eax)\n\t"                                    \
1118          "pushl 24(%%eax)\n\t"                                    \
1119          "pushl 20(%%eax)\n\t"                                    \
1120          "pushl 16(%%eax)\n\t"                                    \
1121          "pushl 12(%%eax)\n\t"                                    \
1122          "pushl 8(%%eax)\n\t"                                     \
1123          "pushl 4(%%eax)\n\t"                                     \
1124          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1125          VALGRIND_CALL_NOREDIR_EAX                                \
1126          VALGRIND_RESTORE_STACK                                   \
1127          : /*out*/   "=a" (_res)                                  \
1128          : /*in*/    "a" (&_argvec[0])                            \
1129          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1130       );                                                          \
1131       lval = (__typeof__(lval)) _res;                             \
1132    } while (0)
1133
1134 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1135                                   arg7,arg8,arg9,arg10)           \
1136    do {                                                           \
1137       volatile OrigFn        _orig = (orig);                      \
1138       volatile unsigned long _argvec[11];                         \
1139       volatile unsigned long _res;                                \
1140       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1141       _argvec[1] = (unsigned long)(arg1);                         \
1142       _argvec[2] = (unsigned long)(arg2);                         \
1143       _argvec[3] = (unsigned long)(arg3);                         \
1144       _argvec[4] = (unsigned long)(arg4);                         \
1145       _argvec[5] = (unsigned long)(arg5);                         \
1146       _argvec[6] = (unsigned long)(arg6);                         \
1147       _argvec[7] = (unsigned long)(arg7);                         \
1148       _argvec[8] = (unsigned long)(arg8);                         \
1149       _argvec[9] = (unsigned long)(arg9);                         \
1150       _argvec[10] = (unsigned long)(arg10);                       \
1151       __asm__ volatile(                                           \
1152          VALGRIND_ALIGN_STACK                                     \
1153          "subl $8, %%esp\n\t"                                     \
1154          "pushl 40(%%eax)\n\t"                                    \
1155          "pushl 36(%%eax)\n\t"                                    \
1156          "pushl 32(%%eax)\n\t"                                    \
1157          "pushl 28(%%eax)\n\t"                                    \
1158          "pushl 24(%%eax)\n\t"                                    \
1159          "pushl 20(%%eax)\n\t"                                    \
1160          "pushl 16(%%eax)\n\t"                                    \
1161          "pushl 12(%%eax)\n\t"                                    \
1162          "pushl 8(%%eax)\n\t"                                     \
1163          "pushl 4(%%eax)\n\t"                                     \
1164          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1165          VALGRIND_CALL_NOREDIR_EAX                                \
1166          VALGRIND_RESTORE_STACK                                   \
1167          : /*out*/   "=a" (_res)                                  \
1168          : /*in*/    "a" (&_argvec[0])                            \
1169          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1170       );                                                          \
1171       lval = (__typeof__(lval)) _res;                             \
1172    } while (0)
1173
1174 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
1175                                   arg6,arg7,arg8,arg9,arg10,      \
1176                                   arg11)                          \
1177    do {                                                           \
1178       volatile OrigFn        _orig = (orig);                      \
1179       volatile unsigned long _argvec[12];                         \
1180       volatile unsigned long _res;                                \
1181       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1182       _argvec[1] = (unsigned long)(arg1);                         \
1183       _argvec[2] = (unsigned long)(arg2);                         \
1184       _argvec[3] = (unsigned long)(arg3);                         \
1185       _argvec[4] = (unsigned long)(arg4);                         \
1186       _argvec[5] = (unsigned long)(arg5);                         \
1187       _argvec[6] = (unsigned long)(arg6);                         \
1188       _argvec[7] = (unsigned long)(arg7);                         \
1189       _argvec[8] = (unsigned long)(arg8);                         \
1190       _argvec[9] = (unsigned long)(arg9);                         \
1191       _argvec[10] = (unsigned long)(arg10);                       \
1192       _argvec[11] = (unsigned long)(arg11);                       \
1193       __asm__ volatile(                                           \
1194          VALGRIND_ALIGN_STACK                                     \
1195          "subl $4, %%esp\n\t"                                     \
1196          "pushl 44(%%eax)\n\t"                                    \
1197          "pushl 40(%%eax)\n\t"                                    \
1198          "pushl 36(%%eax)\n\t"                                    \
1199          "pushl 32(%%eax)\n\t"                                    \
1200          "pushl 28(%%eax)\n\t"                                    \
1201          "pushl 24(%%eax)\n\t"                                    \
1202          "pushl 20(%%eax)\n\t"                                    \
1203          "pushl 16(%%eax)\n\t"                                    \
1204          "pushl 12(%%eax)\n\t"                                    \
1205          "pushl 8(%%eax)\n\t"                                     \
1206          "pushl 4(%%eax)\n\t"                                     \
1207          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1208          VALGRIND_CALL_NOREDIR_EAX                                \
1209          VALGRIND_RESTORE_STACK                                   \
1210          : /*out*/   "=a" (_res)                                  \
1211          : /*in*/    "a" (&_argvec[0])                            \
1212          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1213       );                                                          \
1214       lval = (__typeof__(lval)) _res;                             \
1215    } while (0)
1216
1217 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
1218                                   arg6,arg7,arg8,arg9,arg10,      \
1219                                   arg11,arg12)                    \
1220    do {                                                           \
1221       volatile OrigFn        _orig = (orig);                      \
1222       volatile unsigned long _argvec[13];                         \
1223       volatile unsigned long _res;                                \
1224       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1225       _argvec[1] = (unsigned long)(arg1);                         \
1226       _argvec[2] = (unsigned long)(arg2);                         \
1227       _argvec[3] = (unsigned long)(arg3);                         \
1228       _argvec[4] = (unsigned long)(arg4);                         \
1229       _argvec[5] = (unsigned long)(arg5);                         \
1230       _argvec[6] = (unsigned long)(arg6);                         \
1231       _argvec[7] = (unsigned long)(arg7);                         \
1232       _argvec[8] = (unsigned long)(arg8);                         \
1233       _argvec[9] = (unsigned long)(arg9);                         \
1234       _argvec[10] = (unsigned long)(arg10);                       \
1235       _argvec[11] = (unsigned long)(arg11);                       \
1236       _argvec[12] = (unsigned long)(arg12);                       \
1237       __asm__ volatile(                                           \
1238          VALGRIND_ALIGN_STACK                                     \
1239          "pushl 48(%%eax)\n\t"                                    \
1240          "pushl 44(%%eax)\n\t"                                    \
1241          "pushl 40(%%eax)\n\t"                                    \
1242          "pushl 36(%%eax)\n\t"                                    \
1243          "pushl 32(%%eax)\n\t"                                    \
1244          "pushl 28(%%eax)\n\t"                                    \
1245          "pushl 24(%%eax)\n\t"                                    \
1246          "pushl 20(%%eax)\n\t"                                    \
1247          "pushl 16(%%eax)\n\t"                                    \
1248          "pushl 12(%%eax)\n\t"                                    \
1249          "pushl 8(%%eax)\n\t"                                     \
1250          "pushl 4(%%eax)\n\t"                                     \
1251          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1252          VALGRIND_CALL_NOREDIR_EAX                                \
1253          VALGRIND_RESTORE_STACK                                   \
1254          : /*out*/   "=a" (_res)                                  \
1255          : /*in*/    "a" (&_argvec[0])                            \
1256          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1257       );                                                          \
1258       lval = (__typeof__(lval)) _res;                             \
1259    } while (0)
1260
1261 #endif /* PLAT_x86_linux || PLAT_x86_darwin */
1262
1263 /* ------------------------ amd64-{linux,darwin} --------------- */
1264
1265 #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
1266
1267 /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1268
1269 /* These regs are trashed by the hidden call. */
1270 #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
1271                             "rdi", "r8", "r9", "r10", "r11"
1272
1273 /* This is all pretty complex.  It's so as to make stack unwinding
1274    work reliably.  See bug 243270.  The basic problem is the sub and
1275    add of 128 of %rsp in all of the following macros.  If gcc believes
1276    the CFA is in %rsp, then unwinding may fail, because what's at the
1277    CFA is not what gcc "expected" when it constructs the CFIs for the
1278    places where the macros are instantiated.
1279
1280    But we can't just add a CFI annotation to increase the CFA offset
1281    by 128, to match the sub of 128 from %rsp, because we don't know
1282    whether gcc has chosen %rsp as the CFA at that point, or whether it
1283    has chosen some other register (eg, %rbp).  In the latter case,
1284    adding a CFI annotation to change the CFA offset is simply wrong.
1285
1286    So the solution is to get hold of the CFA using
1287    __builtin_dwarf_cfa(), put it in a known register, and add a
1288    CFI annotation to say what the register is.  We choose %rbp for
1289    this (perhaps perversely), because:
1290
1291    (1) %rbp is already subject to unwinding.  If a new register was
1292        chosen then the unwinder would have to unwind it in all stack
1293        traces, which is expensive, and
1294
1295    (2) %rbp is already subject to precise exception updates in the
1296        JIT.  If a new register was chosen, we'd have to have precise
1297        exceptions for it too, which reduces performance of the
1298        generated code.
1299
1300    However .. one extra complication.  We can't just whack the result
1301    of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1302    list of trashed registers at the end of the inline assembly
1303    fragments; gcc won't allow %rbp to appear in that list.  Hence
1304    instead we need to stash %rbp in %r15 for the duration of the asm,
1305    and say that %r15 is trashed instead.  gcc seems happy to go with
1306    that.
1307
1308    Oh .. and this all needs to be conditionalised so that it is
1309    unchanged from before this commit, when compiled with older gccs
1310    that don't support __builtin_dwarf_cfa.  Furthermore, since
1311    this header file is freestanding, it has to be independent of
1312    config.h, and so the following conditionalisation cannot depend on
1313    configure time checks.
1314
1315    Although it's not clear from
1316    'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
1317    this expression excludes Darwin.
1318    .cfi directives in Darwin assembly appear to be completely
1319    different and I haven't investigated how they work.
1320
1321    For even more entertainment value, note we have to use the
1322    completely undocumented __builtin_dwarf_cfa(), which appears to
1323    really compute the CFA, whereas __builtin_frame_address(0) claims
1324    to but actually doesn't.  See
1325    https://bugs.kde.org/show_bug.cgi?id=243270#c47
1326 */
1327 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1328 #  define __FRAME_POINTER                                         \
1329       ,"r"(__builtin_dwarf_cfa())
1330 #  define VALGRIND_CFI_PROLOGUE                                   \
1331       "movq %%rbp, %%r15\n\t"                                     \
1332       "movq %2, %%rbp\n\t"                                        \
1333       ".cfi_remember_state\n\t"                                   \
1334       ".cfi_def_cfa rbp, 0\n\t"
1335 #  define VALGRIND_CFI_EPILOGUE                                   \
1336       "movq %%r15, %%rbp\n\t"                                     \
1337       ".cfi_restore_state\n\t"
1338 #else
1339 #  define __FRAME_POINTER
1340 #  define VALGRIND_CFI_PROLOGUE
1341 #  define VALGRIND_CFI_EPILOGUE
1342 #endif
1343
1344 /* Macros to save and align the stack before making a function
1345    call and restore it afterwards as gcc may not keep the stack
1346    pointer aligned if it doesn't realise calls are being made
1347    to other functions. */
1348
1349 #define VALGRIND_ALIGN_STACK               \
1350       "movq %%rsp,%%r14\n\t"               \
1351       "andq $0xfffffffffffffff0,%%rsp\n\t"
1352 #define VALGRIND_RESTORE_STACK             \
1353       "movq %%r14,%%rsp\n\t"
1354
1355 /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1356    long) == 8. */
1357
1358 /* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1359    macros.  In order not to trash the stack redzone, we need to drop
1360    %rsp by 128 before the hidden call, and restore afterwards.  The
1361    nastyness is that it is only by luck that the stack still appears
1362    to be unwindable during the hidden call - since then the behaviour
1363    of any routine using this macro does not match what the CFI data
1364    says.  Sigh.
1365
1366    Why is this important?  Imagine that a wrapper has a stack
1367    allocated local, and passes to the hidden call, a pointer to it.
1368    Because gcc does not know about the hidden call, it may allocate
1369    that local in the redzone.  Unfortunately the hidden call may then
1370    trash it before it comes to use it.  So we must step clear of the
1371    redzone, for the duration of the hidden call, to make it safe.
1372
1373    Probably the same problem afflicts the other redzone-style ABIs too
1374    (ppc64-linux); but for those, the stack is
1375    self describing (none of this CFI nonsense) so at least messing
1376    with the stack pointer doesn't give a danger of non-unwindable
1377    stack. */
1378
1379 #define CALL_FN_W_v(lval, orig)                                        \
1380    do {                                                                \
1381       volatile OrigFn        _orig = (orig);                           \
1382       volatile unsigned long _argvec[1];                               \
1383       volatile unsigned long _res;                                     \
1384       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1385       __asm__ volatile(                                                \
1386          VALGRIND_CFI_PROLOGUE                                         \
1387          VALGRIND_ALIGN_STACK                                          \
1388          "subq $128,%%rsp\n\t"                                         \
1389          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1390          VALGRIND_CALL_NOREDIR_RAX                                     \
1391          VALGRIND_RESTORE_STACK                                        \
1392          VALGRIND_CFI_EPILOGUE                                         \
1393          : /*out*/   "=a" (_res)                                       \
1394          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1395          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1396       );                                                               \
1397       lval = (__typeof__(lval)) _res;                                  \
1398    } while (0)
1399
1400 #define CALL_FN_W_W(lval, orig, arg1)                                  \
1401    do {                                                                \
1402       volatile OrigFn        _orig = (orig);                           \
1403       volatile unsigned long _argvec[2];                               \
1404       volatile unsigned long _res;                                     \
1405       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1406       _argvec[1] = (unsigned long)(arg1);                              \
1407       __asm__ volatile(                                                \
1408          VALGRIND_CFI_PROLOGUE                                         \
1409          VALGRIND_ALIGN_STACK                                          \
1410          "subq $128,%%rsp\n\t"                                         \
1411          "movq 8(%%rax), %%rdi\n\t"                                    \
1412          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1413          VALGRIND_CALL_NOREDIR_RAX                                     \
1414          VALGRIND_RESTORE_STACK                                        \
1415          VALGRIND_CFI_EPILOGUE                                         \
1416          : /*out*/   "=a" (_res)                                       \
1417          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1418          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1419       );                                                               \
1420       lval = (__typeof__(lval)) _res;                                  \
1421    } while (0)
1422
1423 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
1424    do {                                                                \
1425       volatile OrigFn        _orig = (orig);                           \
1426       volatile unsigned long _argvec[3];                               \
1427       volatile unsigned long _res;                                     \
1428       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1429       _argvec[1] = (unsigned long)(arg1);                              \
1430       _argvec[2] = (unsigned long)(arg2);                              \
1431       __asm__ volatile(                                                \
1432          VALGRIND_CFI_PROLOGUE                                         \
1433          VALGRIND_ALIGN_STACK                                          \
1434          "subq $128,%%rsp\n\t"                                         \
1435          "movq 16(%%rax), %%rsi\n\t"                                   \
1436          "movq 8(%%rax), %%rdi\n\t"                                    \
1437          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1438          VALGRIND_CALL_NOREDIR_RAX                                     \
1439          VALGRIND_RESTORE_STACK                                        \
1440          VALGRIND_CFI_EPILOGUE                                         \
1441          : /*out*/   "=a" (_res)                                       \
1442          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1443          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1444       );                                                               \
1445       lval = (__typeof__(lval)) _res;                                  \
1446    } while (0)
1447
1448 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
1449    do {                                                                \
1450       volatile OrigFn        _orig = (orig);                           \
1451       volatile unsigned long _argvec[4];                               \
1452       volatile unsigned long _res;                                     \
1453       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1454       _argvec[1] = (unsigned long)(arg1);                              \
1455       _argvec[2] = (unsigned long)(arg2);                              \
1456       _argvec[3] = (unsigned long)(arg3);                              \
1457       __asm__ volatile(                                                \
1458          VALGRIND_CFI_PROLOGUE                                         \
1459          VALGRIND_ALIGN_STACK                                          \
1460          "subq $128,%%rsp\n\t"                                         \
1461          "movq 24(%%rax), %%rdx\n\t"                                   \
1462          "movq 16(%%rax), %%rsi\n\t"                                   \
1463          "movq 8(%%rax), %%rdi\n\t"                                    \
1464          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1465          VALGRIND_CALL_NOREDIR_RAX                                     \
1466          VALGRIND_RESTORE_STACK                                        \
1467          VALGRIND_CFI_EPILOGUE                                         \
1468          : /*out*/   "=a" (_res)                                       \
1469          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1470          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1471       );                                                               \
1472       lval = (__typeof__(lval)) _res;                                  \
1473    } while (0)
1474
1475 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
1476    do {                                                                \
1477       volatile OrigFn        _orig = (orig);                           \
1478       volatile unsigned long _argvec[5];                               \
1479       volatile unsigned long _res;                                     \
1480       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1481       _argvec[1] = (unsigned long)(arg1);                              \
1482       _argvec[2] = (unsigned long)(arg2);                              \
1483       _argvec[3] = (unsigned long)(arg3);                              \
1484       _argvec[4] = (unsigned long)(arg4);                              \
1485       __asm__ volatile(                                                \
1486          VALGRIND_CFI_PROLOGUE                                         \
1487          VALGRIND_ALIGN_STACK                                          \
1488          "subq $128,%%rsp\n\t"                                         \
1489          "movq 32(%%rax), %%rcx\n\t"                                   \
1490          "movq 24(%%rax), %%rdx\n\t"                                   \
1491          "movq 16(%%rax), %%rsi\n\t"                                   \
1492          "movq 8(%%rax), %%rdi\n\t"                                    \
1493          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1494          VALGRIND_CALL_NOREDIR_RAX                                     \
1495          VALGRIND_RESTORE_STACK                                        \
1496          VALGRIND_CFI_EPILOGUE                                         \
1497          : /*out*/   "=a" (_res)                                       \
1498          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1499          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1500       );                                                               \
1501       lval = (__typeof__(lval)) _res;                                  \
1502    } while (0)
1503
1504 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
1505    do {                                                                \
1506       volatile OrigFn        _orig = (orig);                           \
1507       volatile unsigned long _argvec[6];                               \
1508       volatile unsigned long _res;                                     \
1509       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1510       _argvec[1] = (unsigned long)(arg1);                              \
1511       _argvec[2] = (unsigned long)(arg2);                              \
1512       _argvec[3] = (unsigned long)(arg3);                              \
1513       _argvec[4] = (unsigned long)(arg4);                              \
1514       _argvec[5] = (unsigned long)(arg5);                              \
1515       __asm__ volatile(                                                \
1516          VALGRIND_CFI_PROLOGUE                                         \
1517          VALGRIND_ALIGN_STACK                                          \
1518          "subq $128,%%rsp\n\t"                                         \
1519          "movq 40(%%rax), %%r8\n\t"                                    \
1520          "movq 32(%%rax), %%rcx\n\t"                                   \
1521          "movq 24(%%rax), %%rdx\n\t"                                   \
1522          "movq 16(%%rax), %%rsi\n\t"                                   \
1523          "movq 8(%%rax), %%rdi\n\t"                                    \
1524          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1525          VALGRIND_CALL_NOREDIR_RAX                                     \
1526          VALGRIND_RESTORE_STACK                                        \
1527          VALGRIND_CFI_EPILOGUE                                         \
1528          : /*out*/   "=a" (_res)                                       \
1529          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1530          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1531       );                                                               \
1532       lval = (__typeof__(lval)) _res;                                  \
1533    } while (0)
1534
1535 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
1536    do {                                                                \
1537       volatile OrigFn        _orig = (orig);                           \
1538       volatile unsigned long _argvec[7];                               \
1539       volatile unsigned long _res;                                     \
1540       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1541       _argvec[1] = (unsigned long)(arg1);                              \
1542       _argvec[2] = (unsigned long)(arg2);                              \
1543       _argvec[3] = (unsigned long)(arg3);                              \
1544       _argvec[4] = (unsigned long)(arg4);                              \
1545       _argvec[5] = (unsigned long)(arg5);                              \
1546       _argvec[6] = (unsigned long)(arg6);                              \
1547       __asm__ volatile(                                                \
1548          VALGRIND_CFI_PROLOGUE                                         \
1549          VALGRIND_ALIGN_STACK                                          \
1550          "subq $128,%%rsp\n\t"                                         \
1551          "movq 48(%%rax), %%r9\n\t"                                    \
1552          "movq 40(%%rax), %%r8\n\t"                                    \
1553          "movq 32(%%rax), %%rcx\n\t"                                   \
1554          "movq 24(%%rax), %%rdx\n\t"                                   \
1555          "movq 16(%%rax), %%rsi\n\t"                                   \
1556          "movq 8(%%rax), %%rdi\n\t"                                    \
1557          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1558          VALGRIND_CALL_NOREDIR_RAX                                     \
1559          VALGRIND_RESTORE_STACK                                        \
1560          VALGRIND_CFI_EPILOGUE                                         \
1561          : /*out*/   "=a" (_res)                                       \
1562          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1563          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1564       );                                                               \
1565       lval = (__typeof__(lval)) _res;                                  \
1566    } while (0)
1567
1568 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1569                                  arg7)                                 \
1570    do {                                                                \
1571       volatile OrigFn        _orig = (orig);                           \
1572       volatile unsigned long _argvec[8];                               \
1573       volatile unsigned long _res;                                     \
1574       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1575       _argvec[1] = (unsigned long)(arg1);                              \
1576       _argvec[2] = (unsigned long)(arg2);                              \
1577       _argvec[3] = (unsigned long)(arg3);                              \
1578       _argvec[4] = (unsigned long)(arg4);                              \
1579       _argvec[5] = (unsigned long)(arg5);                              \
1580       _argvec[6] = (unsigned long)(arg6);                              \
1581       _argvec[7] = (unsigned long)(arg7);                              \
1582       __asm__ volatile(                                                \
1583          VALGRIND_CFI_PROLOGUE                                         \
1584          VALGRIND_ALIGN_STACK                                          \
1585          "subq $136,%%rsp\n\t"                                         \
1586          "pushq 56(%%rax)\n\t"                                         \
1587          "movq 48(%%rax), %%r9\n\t"                                    \
1588          "movq 40(%%rax), %%r8\n\t"                                    \
1589          "movq 32(%%rax), %%rcx\n\t"                                   \
1590          "movq 24(%%rax), %%rdx\n\t"                                   \
1591          "movq 16(%%rax), %%rsi\n\t"                                   \
1592          "movq 8(%%rax), %%rdi\n\t"                                    \
1593          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1594          VALGRIND_CALL_NOREDIR_RAX                                     \
1595          VALGRIND_RESTORE_STACK                                        \
1596          VALGRIND_CFI_EPILOGUE                                         \
1597          : /*out*/   "=a" (_res)                                       \
1598          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1599          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1600       );                                                               \
1601       lval = (__typeof__(lval)) _res;                                  \
1602    } while (0)
1603
1604 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1605                                  arg7,arg8)                            \
1606    do {                                                                \
1607       volatile OrigFn        _orig = (orig);                           \
1608       volatile unsigned long _argvec[9];                               \
1609       volatile unsigned long _res;                                     \
1610       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1611       _argvec[1] = (unsigned long)(arg1);                              \
1612       _argvec[2] = (unsigned long)(arg2);                              \
1613       _argvec[3] = (unsigned long)(arg3);                              \
1614       _argvec[4] = (unsigned long)(arg4);                              \
1615       _argvec[5] = (unsigned long)(arg5);                              \
1616       _argvec[6] = (unsigned long)(arg6);                              \
1617       _argvec[7] = (unsigned long)(arg7);                              \
1618       _argvec[8] = (unsigned long)(arg8);                              \
1619       __asm__ volatile(                                                \
1620          VALGRIND_CFI_PROLOGUE                                         \
1621          VALGRIND_ALIGN_STACK                                          \
1622          "subq $128,%%rsp\n\t"                                         \
1623          "pushq 64(%%rax)\n\t"                                         \
1624          "pushq 56(%%rax)\n\t"                                         \
1625          "movq 48(%%rax), %%r9\n\t"                                    \
1626          "movq 40(%%rax), %%r8\n\t"                                    \
1627          "movq 32(%%rax), %%rcx\n\t"                                   \
1628          "movq 24(%%rax), %%rdx\n\t"                                   \
1629          "movq 16(%%rax), %%rsi\n\t"                                   \
1630          "movq 8(%%rax), %%rdi\n\t"                                    \
1631          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1632          VALGRIND_CALL_NOREDIR_RAX                                     \
1633          VALGRIND_RESTORE_STACK                                        \
1634          VALGRIND_CFI_EPILOGUE                                         \
1635          : /*out*/   "=a" (_res)                                       \
1636          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1637          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1638       );                                                               \
1639       lval = (__typeof__(lval)) _res;                                  \
1640    } while (0)
1641
1642 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1643                                  arg7,arg8,arg9)                       \
1644    do {                                                                \
1645       volatile OrigFn        _orig = (orig);                           \
1646       volatile unsigned long _argvec[10];                              \
1647       volatile unsigned long _res;                                     \
1648       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1649       _argvec[1] = (unsigned long)(arg1);                              \
1650       _argvec[2] = (unsigned long)(arg2);                              \
1651       _argvec[3] = (unsigned long)(arg3);                              \
1652       _argvec[4] = (unsigned long)(arg4);                              \
1653       _argvec[5] = (unsigned long)(arg5);                              \
1654       _argvec[6] = (unsigned long)(arg6);                              \
1655       _argvec[7] = (unsigned long)(arg7);                              \
1656       _argvec[8] = (unsigned long)(arg8);                              \
1657       _argvec[9] = (unsigned long)(arg9);                              \
1658       __asm__ volatile(                                                \
1659          VALGRIND_CFI_PROLOGUE                                         \
1660          VALGRIND_ALIGN_STACK                                          \
1661          "subq $136,%%rsp\n\t"                                         \
1662          "pushq 72(%%rax)\n\t"                                         \
1663          "pushq 64(%%rax)\n\t"                                         \
1664          "pushq 56(%%rax)\n\t"                                         \
1665          "movq 48(%%rax), %%r9\n\t"                                    \
1666          "movq 40(%%rax), %%r8\n\t"                                    \
1667          "movq 32(%%rax), %%rcx\n\t"                                   \
1668          "movq 24(%%rax), %%rdx\n\t"                                   \
1669          "movq 16(%%rax), %%rsi\n\t"                                   \
1670          "movq 8(%%rax), %%rdi\n\t"                                    \
1671          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1672          VALGRIND_CALL_NOREDIR_RAX                                     \
1673          VALGRIND_RESTORE_STACK                                        \
1674          VALGRIND_CFI_EPILOGUE                                         \
1675          : /*out*/   "=a" (_res)                                       \
1676          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1677          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1678       );                                                               \
1679       lval = (__typeof__(lval)) _res;                                  \
1680    } while (0)
1681
1682 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1683                                   arg7,arg8,arg9,arg10)                \
1684    do {                                                                \
1685       volatile OrigFn        _orig = (orig);                           \
1686       volatile unsigned long _argvec[11];                              \
1687       volatile unsigned long _res;                                     \
1688       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1689       _argvec[1] = (unsigned long)(arg1);                              \
1690       _argvec[2] = (unsigned long)(arg2);                              \
1691       _argvec[3] = (unsigned long)(arg3);                              \
1692       _argvec[4] = (unsigned long)(arg4);                              \
1693       _argvec[5] = (unsigned long)(arg5);                              \
1694       _argvec[6] = (unsigned long)(arg6);                              \
1695       _argvec[7] = (unsigned long)(arg7);                              \
1696       _argvec[8] = (unsigned long)(arg8);                              \
1697       _argvec[9] = (unsigned long)(arg9);                              \
1698       _argvec[10] = (unsigned long)(arg10);                            \
1699       __asm__ volatile(                                                \
1700          VALGRIND_CFI_PROLOGUE                                         \
1701          VALGRIND_ALIGN_STACK                                          \
1702          "subq $128,%%rsp\n\t"                                         \
1703          "pushq 80(%%rax)\n\t"                                         \
1704          "pushq 72(%%rax)\n\t"                                         \
1705          "pushq 64(%%rax)\n\t"                                         \
1706          "pushq 56(%%rax)\n\t"                                         \
1707          "movq 48(%%rax), %%r9\n\t"                                    \
1708          "movq 40(%%rax), %%r8\n\t"                                    \
1709          "movq 32(%%rax), %%rcx\n\t"                                   \
1710          "movq 24(%%rax), %%rdx\n\t"                                   \
1711          "movq 16(%%rax), %%rsi\n\t"                                   \
1712          "movq 8(%%rax), %%rdi\n\t"                                    \
1713          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1714          VALGRIND_CALL_NOREDIR_RAX                                     \
1715          VALGRIND_RESTORE_STACK                                        \
1716          VALGRIND_CFI_EPILOGUE                                         \
1717          : /*out*/   "=a" (_res)                                       \
1718          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1719          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1720       );                                                               \
1721       lval = (__typeof__(lval)) _res;                                  \
1722    } while (0)
1723
1724 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1725                                   arg7,arg8,arg9,arg10,arg11)          \
1726    do {                                                                \
1727       volatile OrigFn        _orig = (orig);                           \
1728       volatile unsigned long _argvec[12];                              \
1729       volatile unsigned long _res;                                     \
1730       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1731       _argvec[1] = (unsigned long)(arg1);                              \
1732       _argvec[2] = (unsigned long)(arg2);                              \
1733       _argvec[3] = (unsigned long)(arg3);                              \
1734       _argvec[4] = (unsigned long)(arg4);                              \
1735       _argvec[5] = (unsigned long)(arg5);                              \
1736       _argvec[6] = (unsigned long)(arg6);                              \
1737       _argvec[7] = (unsigned long)(arg7);                              \
1738       _argvec[8] = (unsigned long)(arg8);                              \
1739       _argvec[9] = (unsigned long)(arg9);                              \
1740       _argvec[10] = (unsigned long)(arg10);                            \
1741       _argvec[11] = (unsigned long)(arg11);                            \
1742       __asm__ volatile(                                                \
1743          VALGRIND_CFI_PROLOGUE                                         \
1744          VALGRIND_ALIGN_STACK                                          \
1745          "subq $136,%%rsp\n\t"                                         \
1746          "pushq 88(%%rax)\n\t"                                         \
1747          "pushq 80(%%rax)\n\t"                                         \
1748          "pushq 72(%%rax)\n\t"                                         \
1749          "pushq 64(%%rax)\n\t"                                         \
1750          "pushq 56(%%rax)\n\t"                                         \
1751          "movq 48(%%rax), %%r9\n\t"                                    \
1752          "movq 40(%%rax), %%r8\n\t"                                    \
1753          "movq 32(%%rax), %%rcx\n\t"                                   \
1754          "movq 24(%%rax), %%rdx\n\t"                                   \
1755          "movq 16(%%rax), %%rsi\n\t"                                   \
1756          "movq 8(%%rax), %%rdi\n\t"                                    \
1757          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1758          VALGRIND_CALL_NOREDIR_RAX                                     \
1759          VALGRIND_RESTORE_STACK                                        \
1760          VALGRIND_CFI_EPILOGUE                                         \
1761          : /*out*/   "=a" (_res)                                       \
1762          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1763          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1764       );                                                               \
1765       lval = (__typeof__(lval)) _res;                                  \
1766    } while (0)
1767
1768 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1769                                 arg7,arg8,arg9,arg10,arg11,arg12)      \
1770    do {                                                                \
1771       volatile OrigFn        _orig = (orig);                           \
1772       volatile unsigned long _argvec[13];                              \
1773       volatile unsigned long _res;                                     \
1774       _argvec[0] = (unsigned long)_orig.nraddr;                        \
1775       _argvec[1] = (unsigned long)(arg1);                              \
1776       _argvec[2] = (unsigned long)(arg2);                              \
1777       _argvec[3] = (unsigned long)(arg3);                              \
1778       _argvec[4] = (unsigned long)(arg4);                              \
1779       _argvec[5] = (unsigned long)(arg5);                              \
1780       _argvec[6] = (unsigned long)(arg6);                              \
1781       _argvec[7] = (unsigned long)(arg7);                              \
1782       _argvec[8] = (unsigned long)(arg8);                              \
1783       _argvec[9] = (unsigned long)(arg9);                              \
1784       _argvec[10] = (unsigned long)(arg10);                            \
1785       _argvec[11] = (unsigned long)(arg11);                            \
1786       _argvec[12] = (unsigned long)(arg12);                            \
1787       __asm__ volatile(                                                \
1788          VALGRIND_CFI_PROLOGUE                                         \
1789          VALGRIND_ALIGN_STACK                                          \
1790          "subq $128,%%rsp\n\t"                                         \
1791          "pushq 96(%%rax)\n\t"                                         \
1792          "pushq 88(%%rax)\n\t"                                         \
1793          "pushq 80(%%rax)\n\t"                                         \
1794          "pushq 72(%%rax)\n\t"                                         \
1795          "pushq 64(%%rax)\n\t"                                         \
1796          "pushq 56(%%rax)\n\t"                                         \
1797          "movq 48(%%rax), %%r9\n\t"                                    \
1798          "movq 40(%%rax), %%r8\n\t"                                    \
1799          "movq 32(%%rax), %%rcx\n\t"                                   \
1800          "movq 24(%%rax), %%rdx\n\t"                                   \
1801          "movq 16(%%rax), %%rsi\n\t"                                   \
1802          "movq 8(%%rax), %%rdi\n\t"                                    \
1803          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1804          VALGRIND_CALL_NOREDIR_RAX                                     \
1805          VALGRIND_RESTORE_STACK                                        \
1806          VALGRIND_CFI_EPILOGUE                                         \
1807          : /*out*/   "=a" (_res)                                       \
1808          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1809          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1810       );                                                               \
1811       lval = (__typeof__(lval)) _res;                                  \
1812    } while (0)
1813
1814 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
1815
1816 /* ------------------------ ppc32-linux ------------------------ */
1817
1818 #if defined(PLAT_ppc32_linux)
1819
1820 /* This is useful for finding out about the on-stack stuff:
1821
1822    extern int f9  ( int,int,int,int,int,int,int,int,int );
1823    extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1824    extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1825    extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1826
1827    int g9 ( void ) {
1828       return f9(11,22,33,44,55,66,77,88,99);
1829    }
1830    int g10 ( void ) {
1831       return f10(11,22,33,44,55,66,77,88,99,110);
1832    }
1833    int g11 ( void ) {
1834       return f11(11,22,33,44,55,66,77,88,99,110,121);
1835    }
1836    int g12 ( void ) {
1837       return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1838    }
1839 */
1840
1841 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1842
1843 /* These regs are trashed by the hidden call. */
1844 #define __CALLER_SAVED_REGS                                       \
1845    "lr", "ctr", "xer",                                            \
1846    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1847    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1848    "r11", "r12", "r13"
1849
1850 /* Macros to save and align the stack before making a function
1851    call and restore it afterwards as gcc may not keep the stack
1852    pointer aligned if it doesn't realise calls are being made
1853    to other functions. */
1854
1855 #define VALGRIND_ALIGN_STACK               \
1856       "mr 28,1\n\t"                        \
1857       "rlwinm 1,1,0,0,27\n\t"
1858 #define VALGRIND_RESTORE_STACK             \
1859       "mr 1,28\n\t"
1860
1861 /* These CALL_FN_ macros assume that on ppc32-linux, 
1862    sizeof(unsigned long) == 4. */
1863
1864 #define CALL_FN_W_v(lval, orig)                                   \
1865    do {                                                           \
1866       volatile OrigFn        _orig = (orig);                      \
1867       volatile unsigned long _argvec[1];                          \
1868       volatile unsigned long _res;                                \
1869       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1870       __asm__ volatile(                                           \
1871          VALGRIND_ALIGN_STACK                                     \
1872          "mr 11,%1\n\t"                                           \
1873          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1874          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1875          VALGRIND_RESTORE_STACK                                   \
1876          "mr %0,3"                                                \
1877          : /*out*/   "=r" (_res)                                  \
1878          : /*in*/    "r" (&_argvec[0])                            \
1879          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1880       );                                                          \
1881       lval = (__typeof__(lval)) _res;                             \
1882    } while (0)
1883
1884 #define CALL_FN_W_W(lval, orig, arg1)                             \
1885    do {                                                           \
1886       volatile OrigFn        _orig = (orig);                      \
1887       volatile unsigned long _argvec[2];                          \
1888       volatile unsigned long _res;                                \
1889       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1890       _argvec[1] = (unsigned long)arg1;                           \
1891       __asm__ volatile(                                           \
1892          VALGRIND_ALIGN_STACK                                     \
1893          "mr 11,%1\n\t"                                           \
1894          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1895          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1896          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1897          VALGRIND_RESTORE_STACK                                   \
1898          "mr %0,3"                                                \
1899          : /*out*/   "=r" (_res)                                  \
1900          : /*in*/    "r" (&_argvec[0])                            \
1901          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1902       );                                                          \
1903       lval = (__typeof__(lval)) _res;                             \
1904    } while (0)
1905
1906 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
1907    do {                                                           \
1908       volatile OrigFn        _orig = (orig);                      \
1909       volatile unsigned long _argvec[3];                          \
1910       volatile unsigned long _res;                                \
1911       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1912       _argvec[1] = (unsigned long)arg1;                           \
1913       _argvec[2] = (unsigned long)arg2;                           \
1914       __asm__ volatile(                                           \
1915          VALGRIND_ALIGN_STACK                                     \
1916          "mr 11,%1\n\t"                                           \
1917          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1918          "lwz 4,8(11)\n\t"                                        \
1919          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1920          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1921          VALGRIND_RESTORE_STACK                                   \
1922          "mr %0,3"                                                \
1923          : /*out*/   "=r" (_res)                                  \
1924          : /*in*/    "r" (&_argvec[0])                            \
1925          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1926       );                                                          \
1927       lval = (__typeof__(lval)) _res;                             \
1928    } while (0)
1929
1930 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1931    do {                                                           \
1932       volatile OrigFn        _orig = (orig);                      \
1933       volatile unsigned long _argvec[4];                          \
1934       volatile unsigned long _res;                                \
1935       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1936       _argvec[1] = (unsigned long)arg1;                           \
1937       _argvec[2] = (unsigned long)arg2;                           \
1938       _argvec[3] = (unsigned long)arg3;                           \
1939       __asm__ volatile(                                           \
1940          VALGRIND_ALIGN_STACK                                     \
1941          "mr 11,%1\n\t"                                           \
1942          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1943          "lwz 4,8(11)\n\t"                                        \
1944          "lwz 5,12(11)\n\t"                                       \
1945          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1946          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1947          VALGRIND_RESTORE_STACK                                   \
1948          "mr %0,3"                                                \
1949          : /*out*/   "=r" (_res)                                  \
1950          : /*in*/    "r" (&_argvec[0])                            \
1951          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1952       );                                                          \
1953       lval = (__typeof__(lval)) _res;                             \
1954    } while (0)
1955
1956 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1957    do {                                                           \
1958       volatile OrigFn        _orig = (orig);                      \
1959       volatile unsigned long _argvec[5];                          \
1960       volatile unsigned long _res;                                \
1961       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1962       _argvec[1] = (unsigned long)arg1;                           \
1963       _argvec[2] = (unsigned long)arg2;                           \
1964       _argvec[3] = (unsigned long)arg3;                           \
1965       _argvec[4] = (unsigned long)arg4;                           \
1966       __asm__ volatile(                                           \
1967          VALGRIND_ALIGN_STACK                                     \
1968          "mr 11,%1\n\t"                                           \
1969          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1970          "lwz 4,8(11)\n\t"                                        \
1971          "lwz 5,12(11)\n\t"                                       \
1972          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1973          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1974          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1975          VALGRIND_RESTORE_STACK                                   \
1976          "mr %0,3"                                                \
1977          : /*out*/   "=r" (_res)                                  \
1978          : /*in*/    "r" (&_argvec[0])                            \
1979          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1980       );                                                          \
1981       lval = (__typeof__(lval)) _res;                             \
1982    } while (0)
1983
1984 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1985    do {                                                           \
1986       volatile OrigFn        _orig = (orig);                      \
1987       volatile unsigned long _argvec[6];                          \
1988       volatile unsigned long _res;                                \
1989       _argvec[0] = (unsigned long)_orig.nraddr;                   \
1990       _argvec[1] = (unsigned long)arg1;                           \
1991       _argvec[2] = (unsigned long)arg2;                           \
1992       _argvec[3] = (unsigned long)arg3;                           \
1993       _argvec[4] = (unsigned long)arg4;                           \
1994       _argvec[5] = (unsigned long)arg5;                           \
1995       __asm__ volatile(                                           \
1996          VALGRIND_ALIGN_STACK                                     \
1997          "mr 11,%1\n\t"                                           \
1998          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1999          "lwz 4,8(11)\n\t"                                        \
2000          "lwz 5,12(11)\n\t"                                       \
2001          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2002          "lwz 7,20(11)\n\t"                                       \
2003          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2004          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2005          VALGRIND_RESTORE_STACK                                   \
2006          "mr %0,3"                                                \
2007          : /*out*/   "=r" (_res)                                  \
2008          : /*in*/    "r" (&_argvec[0])                            \
2009          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2010       );                                                          \
2011       lval = (__typeof__(lval)) _res;                             \
2012    } while (0)
2013
2014 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2015    do {                                                           \
2016       volatile OrigFn        _orig = (orig);                      \
2017       volatile unsigned long _argvec[7];                          \
2018       volatile unsigned long _res;                                \
2019       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2020       _argvec[1] = (unsigned long)arg1;                           \
2021       _argvec[2] = (unsigned long)arg2;                           \
2022       _argvec[3] = (unsigned long)arg3;                           \
2023       _argvec[4] = (unsigned long)arg4;                           \
2024       _argvec[5] = (unsigned long)arg5;                           \
2025       _argvec[6] = (unsigned long)arg6;                           \
2026       __asm__ volatile(                                           \
2027          VALGRIND_ALIGN_STACK                                     \
2028          "mr 11,%1\n\t"                                           \
2029          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2030          "lwz 4,8(11)\n\t"                                        \
2031          "lwz 5,12(11)\n\t"                                       \
2032          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2033          "lwz 7,20(11)\n\t"                                       \
2034          "lwz 8,24(11)\n\t"                                       \
2035          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2036          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2037          VALGRIND_RESTORE_STACK                                   \
2038          "mr %0,3"                                                \
2039          : /*out*/   "=r" (_res)                                  \
2040          : /*in*/    "r" (&_argvec[0])                            \
2041          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2042       );                                                          \
2043       lval = (__typeof__(lval)) _res;                             \
2044    } while (0)
2045
2046 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2047                                  arg7)                            \
2048    do {                                                           \
2049       volatile OrigFn        _orig = (orig);                      \
2050       volatile unsigned long _argvec[8];                          \
2051       volatile unsigned long _res;                                \
2052       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2053       _argvec[1] = (unsigned long)arg1;                           \
2054       _argvec[2] = (unsigned long)arg2;                           \
2055       _argvec[3] = (unsigned long)arg3;                           \
2056       _argvec[4] = (unsigned long)arg4;                           \
2057       _argvec[5] = (unsigned long)arg5;                           \
2058       _argvec[6] = (unsigned long)arg6;                           \
2059       _argvec[7] = (unsigned long)arg7;                           \
2060       __asm__ volatile(                                           \
2061          VALGRIND_ALIGN_STACK                                     \
2062          "mr 11,%1\n\t"                                           \
2063          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2064          "lwz 4,8(11)\n\t"                                        \
2065          "lwz 5,12(11)\n\t"                                       \
2066          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2067          "lwz 7,20(11)\n\t"                                       \
2068          "lwz 8,24(11)\n\t"                                       \
2069          "lwz 9,28(11)\n\t"                                       \
2070          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2071          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2072          VALGRIND_RESTORE_STACK                                   \
2073          "mr %0,3"                                                \
2074          : /*out*/   "=r" (_res)                                  \
2075          : /*in*/    "r" (&_argvec[0])                            \
2076          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2077       );                                                          \
2078       lval = (__typeof__(lval)) _res;                             \
2079    } while (0)
2080
2081 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2082                                  arg7,arg8)                       \
2083    do {                                                           \
2084       volatile OrigFn        _orig = (orig);                      \
2085       volatile unsigned long _argvec[9];                          \
2086       volatile unsigned long _res;                                \
2087       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2088       _argvec[1] = (unsigned long)arg1;                           \
2089       _argvec[2] = (unsigned long)arg2;                           \
2090       _argvec[3] = (unsigned long)arg3;                           \
2091       _argvec[4] = (unsigned long)arg4;                           \
2092       _argvec[5] = (unsigned long)arg5;                           \
2093       _argvec[6] = (unsigned long)arg6;                           \
2094       _argvec[7] = (unsigned long)arg7;                           \
2095       _argvec[8] = (unsigned long)arg8;                           \
2096       __asm__ volatile(                                           \
2097          VALGRIND_ALIGN_STACK                                     \
2098          "mr 11,%1\n\t"                                           \
2099          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2100          "lwz 4,8(11)\n\t"                                        \
2101          "lwz 5,12(11)\n\t"                                       \
2102          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2103          "lwz 7,20(11)\n\t"                                       \
2104          "lwz 8,24(11)\n\t"                                       \
2105          "lwz 9,28(11)\n\t"                                       \
2106          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2107          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2108          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2109          VALGRIND_RESTORE_STACK                                   \
2110          "mr %0,3"                                                \
2111          : /*out*/   "=r" (_res)                                  \
2112          : /*in*/    "r" (&_argvec[0])                            \
2113          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2114       );                                                          \
2115       lval = (__typeof__(lval)) _res;                             \
2116    } while (0)
2117
2118 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2119                                  arg7,arg8,arg9)                  \
2120    do {                                                           \
2121       volatile OrigFn        _orig = (orig);                      \
2122       volatile unsigned long _argvec[10];                         \
2123       volatile unsigned long _res;                                \
2124       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2125       _argvec[1] = (unsigned long)arg1;                           \
2126       _argvec[2] = (unsigned long)arg2;                           \
2127       _argvec[3] = (unsigned long)arg3;                           \
2128       _argvec[4] = (unsigned long)arg4;                           \
2129       _argvec[5] = (unsigned long)arg5;                           \
2130       _argvec[6] = (unsigned long)arg6;                           \
2131       _argvec[7] = (unsigned long)arg7;                           \
2132       _argvec[8] = (unsigned long)arg8;                           \
2133       _argvec[9] = (unsigned long)arg9;                           \
2134       __asm__ volatile(                                           \
2135          VALGRIND_ALIGN_STACK                                     \
2136          "mr 11,%1\n\t"                                           \
2137          "addi 1,1,-16\n\t"                                       \
2138          /* arg9 */                                               \
2139          "lwz 3,36(11)\n\t"                                       \
2140          "stw 3,8(1)\n\t"                                         \
2141          /* args1-8 */                                            \
2142          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2143          "lwz 4,8(11)\n\t"                                        \
2144          "lwz 5,12(11)\n\t"                                       \
2145          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2146          "lwz 7,20(11)\n\t"                                       \
2147          "lwz 8,24(11)\n\t"                                       \
2148          "lwz 9,28(11)\n\t"                                       \
2149          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2150          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2151          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2152          VALGRIND_RESTORE_STACK                                   \
2153          "mr %0,3"                                                \
2154          : /*out*/   "=r" (_res)                                  \
2155          : /*in*/    "r" (&_argvec[0])                            \
2156          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2157       );                                                          \
2158       lval = (__typeof__(lval)) _res;                             \
2159    } while (0)
2160
2161 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2162                                   arg7,arg8,arg9,arg10)           \
2163    do {                                                           \
2164       volatile OrigFn        _orig = (orig);                      \
2165       volatile unsigned long _argvec[11];                         \
2166       volatile unsigned long _res;                                \
2167       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2168       _argvec[1] = (unsigned long)arg1;                           \
2169       _argvec[2] = (unsigned long)arg2;                           \
2170       _argvec[3] = (unsigned long)arg3;                           \
2171       _argvec[4] = (unsigned long)arg4;                           \
2172       _argvec[5] = (unsigned long)arg5;                           \
2173       _argvec[6] = (unsigned long)arg6;                           \
2174       _argvec[7] = (unsigned long)arg7;                           \
2175       _argvec[8] = (unsigned long)arg8;                           \
2176       _argvec[9] = (unsigned long)arg9;                           \
2177       _argvec[10] = (unsigned long)arg10;                         \
2178       __asm__ volatile(                                           \
2179          VALGRIND_ALIGN_STACK                                     \
2180          "mr 11,%1\n\t"                                           \
2181          "addi 1,1,-16\n\t"                                       \
2182          /* arg10 */                                              \
2183          "lwz 3,40(11)\n\t"                                       \
2184          "stw 3,12(1)\n\t"                                        \
2185          /* arg9 */                                               \
2186          "lwz 3,36(11)\n\t"                                       \
2187          "stw 3,8(1)\n\t"                                         \
2188          /* args1-8 */                                            \
2189          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2190          "lwz 4,8(11)\n\t"                                        \
2191          "lwz 5,12(11)\n\t"                                       \
2192          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2193          "lwz 7,20(11)\n\t"                                       \
2194          "lwz 8,24(11)\n\t"                                       \
2195          "lwz 9,28(11)\n\t"                                       \
2196          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2197          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2198          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2199          VALGRIND_RESTORE_STACK                                   \
2200          "mr %0,3"                                                \
2201          : /*out*/   "=r" (_res)                                  \
2202          : /*in*/    "r" (&_argvec[0])                            \
2203          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2204       );                                                          \
2205       lval = (__typeof__(lval)) _res;                             \
2206    } while (0)
2207
2208 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2209                                   arg7,arg8,arg9,arg10,arg11)     \
2210    do {                                                           \
2211       volatile OrigFn        _orig = (orig);                      \
2212       volatile unsigned long _argvec[12];                         \
2213       volatile unsigned long _res;                                \
2214       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2215       _argvec[1] = (unsigned long)arg1;                           \
2216       _argvec[2] = (unsigned long)arg2;                           \
2217       _argvec[3] = (unsigned long)arg3;                           \
2218       _argvec[4] = (unsigned long)arg4;                           \
2219       _argvec[5] = (unsigned long)arg5;                           \
2220       _argvec[6] = (unsigned long)arg6;                           \
2221       _argvec[7] = (unsigned long)arg7;                           \
2222       _argvec[8] = (unsigned long)arg8;                           \
2223       _argvec[9] = (unsigned long)arg9;                           \
2224       _argvec[10] = (unsigned long)arg10;                         \
2225       _argvec[11] = (unsigned long)arg11;                         \
2226       __asm__ volatile(                                           \
2227          VALGRIND_ALIGN_STACK                                     \
2228          "mr 11,%1\n\t"                                           \
2229          "addi 1,1,-32\n\t"                                       \
2230          /* arg11 */                                              \
2231          "lwz 3,44(11)\n\t"                                       \
2232          "stw 3,16(1)\n\t"                                        \
2233          /* arg10 */                                              \
2234          "lwz 3,40(11)\n\t"                                       \
2235          "stw 3,12(1)\n\t"                                        \
2236          /* arg9 */                                               \
2237          "lwz 3,36(11)\n\t"                                       \
2238          "stw 3,8(1)\n\t"                                         \
2239          /* args1-8 */                                            \
2240          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2241          "lwz 4,8(11)\n\t"                                        \
2242          "lwz 5,12(11)\n\t"                                       \
2243          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2244          "lwz 7,20(11)\n\t"                                       \
2245          "lwz 8,24(11)\n\t"                                       \
2246          "lwz 9,28(11)\n\t"                                       \
2247          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2248          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2249          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2250          VALGRIND_RESTORE_STACK                                   \
2251          "mr %0,3"                                                \
2252          : /*out*/   "=r" (_res)                                  \
2253          : /*in*/    "r" (&_argvec[0])                            \
2254          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2255       );                                                          \
2256       lval = (__typeof__(lval)) _res;                             \
2257    } while (0)
2258
2259 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2260                                 arg7,arg8,arg9,arg10,arg11,arg12) \
2261    do {                                                           \
2262       volatile OrigFn        _orig = (orig);                      \
2263       volatile unsigned long _argvec[13];                         \
2264       volatile unsigned long _res;                                \
2265       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2266       _argvec[1] = (unsigned long)arg1;                           \
2267       _argvec[2] = (unsigned long)arg2;                           \
2268       _argvec[3] = (unsigned long)arg3;                           \
2269       _argvec[4] = (unsigned long)arg4;                           \
2270       _argvec[5] = (unsigned long)arg5;                           \
2271       _argvec[6] = (unsigned long)arg6;                           \
2272       _argvec[7] = (unsigned long)arg7;                           \
2273       _argvec[8] = (unsigned long)arg8;                           \
2274       _argvec[9] = (unsigned long)arg9;                           \
2275       _argvec[10] = (unsigned long)arg10;                         \
2276       _argvec[11] = (unsigned long)arg11;                         \
2277       _argvec[12] = (unsigned long)arg12;                         \
2278       __asm__ volatile(                                           \
2279          VALGRIND_ALIGN_STACK                                     \
2280          "mr 11,%1\n\t"                                           \
2281          "addi 1,1,-32\n\t"                                       \
2282          /* arg12 */                                              \
2283          "lwz 3,48(11)\n\t"                                       \
2284          "stw 3,20(1)\n\t"                                        \
2285          /* arg11 */                                              \
2286          "lwz 3,44(11)\n\t"                                       \
2287          "stw 3,16(1)\n\t"                                        \
2288          /* arg10 */                                              \
2289          "lwz 3,40(11)\n\t"                                       \
2290          "stw 3,12(1)\n\t"                                        \
2291          /* arg9 */                                               \
2292          "lwz 3,36(11)\n\t"                                       \
2293          "stw 3,8(1)\n\t"                                         \
2294          /* args1-8 */                                            \
2295          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2296          "lwz 4,8(11)\n\t"                                        \
2297          "lwz 5,12(11)\n\t"                                       \
2298          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2299          "lwz 7,20(11)\n\t"                                       \
2300          "lwz 8,24(11)\n\t"                                       \
2301          "lwz 9,28(11)\n\t"                                       \
2302          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2303          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2304          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2305          VALGRIND_RESTORE_STACK                                   \
2306          "mr %0,3"                                                \
2307          : /*out*/   "=r" (_res)                                  \
2308          : /*in*/    "r" (&_argvec[0])                            \
2309          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2310       );                                                          \
2311       lval = (__typeof__(lval)) _res;                             \
2312    } while (0)
2313
2314 #endif /* PLAT_ppc32_linux */
2315
2316 /* ------------------------ ppc64-linux ------------------------ */
2317
2318 #if defined(PLAT_ppc64_linux)
2319
2320 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2321
2322 /* These regs are trashed by the hidden call. */
2323 #define __CALLER_SAVED_REGS                                       \
2324    "lr", "ctr", "xer",                                            \
2325    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2326    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2327    "r11", "r12", "r13"
2328
2329 /* Macros to save and align the stack before making a function
2330    call and restore it afterwards as gcc may not keep the stack
2331    pointer aligned if it doesn't realise calls are being made
2332    to other functions. */
2333
2334 #define VALGRIND_ALIGN_STACK               \
2335       "mr 28,1\n\t"                        \
2336       "rldicr 1,1,0,59\n\t"
2337 #define VALGRIND_RESTORE_STACK             \
2338       "mr 1,28\n\t"
2339
2340 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
2341    long) == 8. */
2342
2343 #define CALL_FN_W_v(lval, orig)                                   \
2344    do {                                                           \
2345       volatile OrigFn        _orig = (orig);                      \
2346       volatile unsigned long _argvec[3+0];                        \
2347       volatile unsigned long _res;                                \
2348       /* _argvec[0] holds current r2 across the call */           \
2349       _argvec[1] = (unsigned long)_orig.r2;                       \
2350       _argvec[2] = (unsigned long)_orig.nraddr;                   \
2351       __asm__ volatile(                                           \
2352          VALGRIND_ALIGN_STACK                                     \
2353          "mr 11,%1\n\t"                                           \
2354          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2355          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2356          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2357          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2358          "mr 11,%1\n\t"                                           \
2359          "mr %0,3\n\t"                                            \
2360          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2361          VALGRIND_RESTORE_STACK                                   \
2362          : /*out*/   "=r" (_res)                                  \
2363          : /*in*/    "r" (&_argvec[2])                            \
2364          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2365       );                                                          \
2366       lval = (__typeof__(lval)) _res;                             \
2367    } while (0)
2368
2369 #define CALL_FN_W_W(lval, orig, arg1)                             \
2370    do {                                                           \
2371       volatile OrigFn        _orig = (orig);                      \
2372       volatile unsigned long _argvec[3+1];                        \
2373       volatile unsigned long _res;                                \
2374       /* _argvec[0] holds current r2 across the call */           \
2375       _argvec[1]   = (unsigned long)_orig.r2;                     \
2376       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2377       _argvec[2+1] = (unsigned long)arg1;                         \
2378       __asm__ volatile(                                           \
2379          VALGRIND_ALIGN_STACK                                     \
2380          "mr 11,%1\n\t"                                           \
2381          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2382          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2383          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2384          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2385          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2386          "mr 11,%1\n\t"                                           \
2387          "mr %0,3\n\t"                                            \
2388          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2389          VALGRIND_RESTORE_STACK                                   \
2390          : /*out*/   "=r" (_res)                                  \
2391          : /*in*/    "r" (&_argvec[2])                            \
2392          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2393       );                                                          \
2394       lval = (__typeof__(lval)) _res;                             \
2395    } while (0)
2396
2397 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2398    do {                                                           \
2399       volatile OrigFn        _orig = (orig);                      \
2400       volatile unsigned long _argvec[3+2];                        \
2401       volatile unsigned long _res;                                \
2402       /* _argvec[0] holds current r2 across the call */           \
2403       _argvec[1]   = (unsigned long)_orig.r2;                     \
2404       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2405       _argvec[2+1] = (unsigned long)arg1;                         \
2406       _argvec[2+2] = (unsigned long)arg2;                         \
2407       __asm__ volatile(                                           \
2408          VALGRIND_ALIGN_STACK                                     \
2409          "mr 11,%1\n\t"                                           \
2410          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2411          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2412          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2413          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2414          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2415          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2416          "mr 11,%1\n\t"                                           \
2417          "mr %0,3\n\t"                                            \
2418          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2419          VALGRIND_RESTORE_STACK                                   \
2420          : /*out*/   "=r" (_res)                                  \
2421          : /*in*/    "r" (&_argvec[2])                            \
2422          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2423       );                                                          \
2424       lval = (__typeof__(lval)) _res;                             \
2425    } while (0)
2426
2427 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2428    do {                                                           \
2429       volatile OrigFn        _orig = (orig);                      \
2430       volatile unsigned long _argvec[3+3];                        \
2431       volatile unsigned long _res;                                \
2432       /* _argvec[0] holds current r2 across the call */           \
2433       _argvec[1]   = (unsigned long)_orig.r2;                     \
2434       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2435       _argvec[2+1] = (unsigned long)arg1;                         \
2436       _argvec[2+2] = (unsigned long)arg2;                         \
2437       _argvec[2+3] = (unsigned long)arg3;                         \
2438       __asm__ volatile(                                           \
2439          VALGRIND_ALIGN_STACK                                     \
2440          "mr 11,%1\n\t"                                           \
2441          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2442          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2443          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2444          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2445          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2446          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2447          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2448          "mr 11,%1\n\t"                                           \
2449          "mr %0,3\n\t"                                            \
2450          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2451          VALGRIND_RESTORE_STACK                                   \
2452          : /*out*/   "=r" (_res)                                  \
2453          : /*in*/    "r" (&_argvec[2])                            \
2454          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2455       );                                                          \
2456       lval = (__typeof__(lval)) _res;                             \
2457    } while (0)
2458
2459 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2460    do {                                                           \
2461       volatile OrigFn        _orig = (orig);                      \
2462       volatile unsigned long _argvec[3+4];                        \
2463       volatile unsigned long _res;                                \
2464       /* _argvec[0] holds current r2 across the call */           \
2465       _argvec[1]   = (unsigned long)_orig.r2;                     \
2466       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2467       _argvec[2+1] = (unsigned long)arg1;                         \
2468       _argvec[2+2] = (unsigned long)arg2;                         \
2469       _argvec[2+3] = (unsigned long)arg3;                         \
2470       _argvec[2+4] = (unsigned long)arg4;                         \
2471       __asm__ volatile(                                           \
2472          VALGRIND_ALIGN_STACK                                     \
2473          "mr 11,%1\n\t"                                           \
2474          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2475          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2476          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2477          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2478          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2479          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2480          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2481          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2482          "mr 11,%1\n\t"                                           \
2483          "mr %0,3\n\t"                                            \
2484          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2485          VALGRIND_RESTORE_STACK                                   \
2486          : /*out*/   "=r" (_res)                                  \
2487          : /*in*/    "r" (&_argvec[2])                            \
2488          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2489       );                                                          \
2490       lval = (__typeof__(lval)) _res;                             \
2491    } while (0)
2492
2493 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2494    do {                                                           \
2495       volatile OrigFn        _orig = (orig);                      \
2496       volatile unsigned long _argvec[3+5];                        \
2497       volatile unsigned long _res;                                \
2498       /* _argvec[0] holds current r2 across the call */           \
2499       _argvec[1]   = (unsigned long)_orig.r2;                     \
2500       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2501       _argvec[2+1] = (unsigned long)arg1;                         \
2502       _argvec[2+2] = (unsigned long)arg2;                         \
2503       _argvec[2+3] = (unsigned long)arg3;                         \
2504       _argvec[2+4] = (unsigned long)arg4;                         \
2505       _argvec[2+5] = (unsigned long)arg5;                         \
2506       __asm__ volatile(                                           \
2507          VALGRIND_ALIGN_STACK                                     \
2508          "mr 11,%1\n\t"                                           \
2509          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2510          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2511          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2512          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2513          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2514          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2515          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2516          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2517          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2518          "mr 11,%1\n\t"                                           \
2519          "mr %0,3\n\t"                                            \
2520          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2521          VALGRIND_RESTORE_STACK                                   \
2522          : /*out*/   "=r" (_res)                                  \
2523          : /*in*/    "r" (&_argvec[2])                            \
2524          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2525       );                                                          \
2526       lval = (__typeof__(lval)) _res;                             \
2527    } while (0)
2528
2529 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2530    do {                                                           \
2531       volatile OrigFn        _orig = (orig);                      \
2532       volatile unsigned long _argvec[3+6];                        \
2533       volatile unsigned long _res;                                \
2534       /* _argvec[0] holds current r2 across the call */           \
2535       _argvec[1]   = (unsigned long)_orig.r2;                     \
2536       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2537       _argvec[2+1] = (unsigned long)arg1;                         \
2538       _argvec[2+2] = (unsigned long)arg2;                         \
2539       _argvec[2+3] = (unsigned long)arg3;                         \
2540       _argvec[2+4] = (unsigned long)arg4;                         \
2541       _argvec[2+5] = (unsigned long)arg5;                         \
2542       _argvec[2+6] = (unsigned long)arg6;                         \
2543       __asm__ volatile(                                           \
2544          VALGRIND_ALIGN_STACK                                     \
2545          "mr 11,%1\n\t"                                           \
2546          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2547          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2548          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2549          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2550          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2551          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2552          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2553          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2554          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2555          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2556          "mr 11,%1\n\t"                                           \
2557          "mr %0,3\n\t"                                            \
2558          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2559          VALGRIND_RESTORE_STACK                                   \
2560          : /*out*/   "=r" (_res)                                  \
2561          : /*in*/    "r" (&_argvec[2])                            \
2562          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2563       );                                                          \
2564       lval = (__typeof__(lval)) _res;                             \
2565    } while (0)
2566
2567 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2568                                  arg7)                            \
2569    do {                                                           \
2570       volatile OrigFn        _orig = (orig);                      \
2571       volatile unsigned long _argvec[3+7];                        \
2572       volatile unsigned long _res;                                \
2573       /* _argvec[0] holds current r2 across the call */           \
2574       _argvec[1]   = (unsigned long)_orig.r2;                     \
2575       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2576       _argvec[2+1] = (unsigned long)arg1;                         \
2577       _argvec[2+2] = (unsigned long)arg2;                         \
2578       _argvec[2+3] = (unsigned long)arg3;                         \
2579       _argvec[2+4] = (unsigned long)arg4;                         \
2580       _argvec[2+5] = (unsigned long)arg5;                         \
2581       _argvec[2+6] = (unsigned long)arg6;                         \
2582       _argvec[2+7] = (unsigned long)arg7;                         \
2583       __asm__ volatile(                                           \
2584          VALGRIND_ALIGN_STACK                                     \
2585          "mr 11,%1\n\t"                                           \
2586          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2587          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2588          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2589          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2590          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2591          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2592          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2593          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2594          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2595          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2596          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2597          "mr 11,%1\n\t"                                           \
2598          "mr %0,3\n\t"                                            \
2599          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2600          VALGRIND_RESTORE_STACK                                   \
2601          : /*out*/   "=r" (_res)                                  \
2602          : /*in*/    "r" (&_argvec[2])                            \
2603          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2604       );                                                          \
2605       lval = (__typeof__(lval)) _res;                             \
2606    } while (0)
2607
2608 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2609                                  arg7,arg8)                       \
2610    do {                                                           \
2611       volatile OrigFn        _orig = (orig);                      \
2612       volatile unsigned long _argvec[3+8];                        \
2613       volatile unsigned long _res;                                \
2614       /* _argvec[0] holds current r2 across the call */           \
2615       _argvec[1]   = (unsigned long)_orig.r2;                     \
2616       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2617       _argvec[2+1] = (unsigned long)arg1;                         \
2618       _argvec[2+2] = (unsigned long)arg2;                         \
2619       _argvec[2+3] = (unsigned long)arg3;                         \
2620       _argvec[2+4] = (unsigned long)arg4;                         \
2621       _argvec[2+5] = (unsigned long)arg5;                         \
2622       _argvec[2+6] = (unsigned long)arg6;                         \
2623       _argvec[2+7] = (unsigned long)arg7;                         \
2624       _argvec[2+8] = (unsigned long)arg8;                         \
2625       __asm__ volatile(                                           \
2626          VALGRIND_ALIGN_STACK                                     \
2627          "mr 11,%1\n\t"                                           \
2628          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2629          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2630          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2631          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2632          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2633          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2634          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2635          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2636          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2637          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2638          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2639          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2640          "mr 11,%1\n\t"                                           \
2641          "mr %0,3\n\t"                                            \
2642          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2643          VALGRIND_RESTORE_STACK                                   \
2644          : /*out*/   "=r" (_res)                                  \
2645          : /*in*/    "r" (&_argvec[2])                            \
2646          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2647       );                                                          \
2648       lval = (__typeof__(lval)) _res;                             \
2649    } while (0)
2650
2651 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2652                                  arg7,arg8,arg9)                  \
2653    do {                                                           \
2654       volatile OrigFn        _orig = (orig);                      \
2655       volatile unsigned long _argvec[3+9];                        \
2656       volatile unsigned long _res;                                \
2657       /* _argvec[0] holds current r2 across the call */           \
2658       _argvec[1]   = (unsigned long)_orig.r2;                     \
2659       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2660       _argvec[2+1] = (unsigned long)arg1;                         \
2661       _argvec[2+2] = (unsigned long)arg2;                         \
2662       _argvec[2+3] = (unsigned long)arg3;                         \
2663       _argvec[2+4] = (unsigned long)arg4;                         \
2664       _argvec[2+5] = (unsigned long)arg5;                         \
2665       _argvec[2+6] = (unsigned long)arg6;                         \
2666       _argvec[2+7] = (unsigned long)arg7;                         \
2667       _argvec[2+8] = (unsigned long)arg8;                         \
2668       _argvec[2+9] = (unsigned long)arg9;                         \
2669       __asm__ volatile(                                           \
2670          VALGRIND_ALIGN_STACK                                     \
2671          "mr 11,%1\n\t"                                           \
2672          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2673          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2674          "addi 1,1,-128\n\t"  /* expand stack frame */            \
2675          /* arg9 */                                               \
2676          "ld  3,72(11)\n\t"                                       \
2677          "std 3,112(1)\n\t"                                       \
2678          /* args1-8 */                                            \
2679          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2680          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2681          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2682          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2683          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2684          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2685          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2686          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2687          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2688          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2689          "mr 11,%1\n\t"                                           \
2690          "mr %0,3\n\t"                                            \
2691          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2692          VALGRIND_RESTORE_STACK                                   \
2693          : /*out*/   "=r" (_res)                                  \
2694          : /*in*/    "r" (&_argvec[2])                            \
2695          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2696       );                                                          \
2697       lval = (__typeof__(lval)) _res;                             \
2698    } while (0)
2699
2700 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2701                                   arg7,arg8,arg9,arg10)           \
2702    do {                                                           \
2703       volatile OrigFn        _orig = (orig);                      \
2704       volatile unsigned long _argvec[3+10];                       \
2705       volatile unsigned long _res;                                \
2706       /* _argvec[0] holds current r2 across the call */           \
2707       _argvec[1]   = (unsigned long)_orig.r2;                     \
2708       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2709       _argvec[2+1] = (unsigned long)arg1;                         \
2710       _argvec[2+2] = (unsigned long)arg2;                         \
2711       _argvec[2+3] = (unsigned long)arg3;                         \
2712       _argvec[2+4] = (unsigned long)arg4;                         \
2713       _argvec[2+5] = (unsigned long)arg5;                         \
2714       _argvec[2+6] = (unsigned long)arg6;                         \
2715       _argvec[2+7] = (unsigned long)arg7;                         \
2716       _argvec[2+8] = (unsigned long)arg8;                         \
2717       _argvec[2+9] = (unsigned long)arg9;                         \
2718       _argvec[2+10] = (unsigned long)arg10;                       \
2719       __asm__ volatile(                                           \
2720          VALGRIND_ALIGN_STACK                                     \
2721          "mr 11,%1\n\t"                                           \
2722          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2723          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2724          "addi 1,1,-128\n\t"  /* expand stack frame */            \
2725          /* arg10 */                                              \
2726          "ld  3,80(11)\n\t"                                       \
2727          "std 3,120(1)\n\t"                                       \
2728          /* arg9 */                                               \
2729          "ld  3,72(11)\n\t"                                       \
2730          "std 3,112(1)\n\t"                                       \
2731          /* args1-8 */                                            \
2732          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2733          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2734          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2735          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2736          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2737          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2738          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2739          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2740          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2741          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2742          "mr 11,%1\n\t"                                           \
2743          "mr %0,3\n\t"                                            \
2744          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2745          VALGRIND_RESTORE_STACK                                   \
2746          : /*out*/   "=r" (_res)                                  \
2747          : /*in*/    "r" (&_argvec[2])                            \
2748          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2749       );                                                          \
2750       lval = (__typeof__(lval)) _res;                             \
2751    } while (0)
2752
2753 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2754                                   arg7,arg8,arg9,arg10,arg11)     \
2755    do {                                                           \
2756       volatile OrigFn        _orig = (orig);                      \
2757       volatile unsigned long _argvec[3+11];                       \
2758       volatile unsigned long _res;                                \
2759       /* _argvec[0] holds current r2 across the call */           \
2760       _argvec[1]   = (unsigned long)_orig.r2;                     \
2761       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2762       _argvec[2+1] = (unsigned long)arg1;                         \
2763       _argvec[2+2] = (unsigned long)arg2;                         \
2764       _argvec[2+3] = (unsigned long)arg3;                         \
2765       _argvec[2+4] = (unsigned long)arg4;                         \
2766       _argvec[2+5] = (unsigned long)arg5;                         \
2767       _argvec[2+6] = (unsigned long)arg6;                         \
2768       _argvec[2+7] = (unsigned long)arg7;                         \
2769       _argvec[2+8] = (unsigned long)arg8;                         \
2770       _argvec[2+9] = (unsigned long)arg9;                         \
2771       _argvec[2+10] = (unsigned long)arg10;                       \
2772       _argvec[2+11] = (unsigned long)arg11;                       \
2773       __asm__ volatile(                                           \
2774          VALGRIND_ALIGN_STACK                                     \
2775          "mr 11,%1\n\t"                                           \
2776          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2777          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2778          "addi 1,1,-144\n\t"  /* expand stack frame */            \
2779          /* arg11 */                                              \
2780          "ld  3,88(11)\n\t"                                       \
2781          "std 3,128(1)\n\t"                                       \
2782          /* arg10 */                                              \
2783          "ld  3,80(11)\n\t"                                       \
2784          "std 3,120(1)\n\t"                                       \
2785          /* arg9 */                                               \
2786          "ld  3,72(11)\n\t"                                       \
2787          "std 3,112(1)\n\t"                                       \
2788          /* args1-8 */                                            \
2789          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2790          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2791          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2792          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2793          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2794          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2795          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2796          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2797          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2798          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2799          "mr 11,%1\n\t"                                           \
2800          "mr %0,3\n\t"                                            \
2801          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2802          VALGRIND_RESTORE_STACK                                   \
2803          : /*out*/   "=r" (_res)                                  \
2804          : /*in*/    "r" (&_argvec[2])                            \
2805          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2806       );                                                          \
2807       lval = (__typeof__(lval)) _res;                             \
2808    } while (0)
2809
2810 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2811                                 arg7,arg8,arg9,arg10,arg11,arg12) \
2812    do {                                                           \
2813       volatile OrigFn        _orig = (orig);                      \
2814       volatile unsigned long _argvec[3+12];                       \
2815       volatile unsigned long _res;                                \
2816       /* _argvec[0] holds current r2 across the call */           \
2817       _argvec[1]   = (unsigned long)_orig.r2;                     \
2818       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2819       _argvec[2+1] = (unsigned long)arg1;                         \
2820       _argvec[2+2] = (unsigned long)arg2;                         \
2821       _argvec[2+3] = (unsigned long)arg3;                         \
2822       _argvec[2+4] = (unsigned long)arg4;                         \
2823       _argvec[2+5] = (unsigned long)arg5;                         \
2824       _argvec[2+6] = (unsigned long)arg6;                         \
2825       _argvec[2+7] = (unsigned long)arg7;                         \
2826       _argvec[2+8] = (unsigned long)arg8;                         \
2827       _argvec[2+9] = (unsigned long)arg9;                         \
2828       _argvec[2+10] = (unsigned long)arg10;                       \
2829       _argvec[2+11] = (unsigned long)arg11;                       \
2830       _argvec[2+12] = (unsigned long)arg12;                       \
2831       __asm__ volatile(                                           \
2832          VALGRIND_ALIGN_STACK                                     \
2833          "mr 11,%1\n\t"                                           \
2834          "std 2,-16(11)\n\t"  /* save tocptr */                   \
2835          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2836          "addi 1,1,-144\n\t"  /* expand stack frame */            \
2837          /* arg12 */                                              \
2838          "ld  3,96(11)\n\t"                                       \
2839          "std 3,136(1)\n\t"                                       \
2840          /* arg11 */                                              \
2841          "ld  3,88(11)\n\t"                                       \
2842          "std 3,128(1)\n\t"                                       \
2843          /* arg10 */                                              \
2844          "ld  3,80(11)\n\t"                                       \
2845          "std 3,120(1)\n\t"                                       \
2846          /* arg9 */                                               \
2847          "ld  3,72(11)\n\t"                                       \
2848          "std 3,112(1)\n\t"                                       \
2849          /* args1-8 */                                            \
2850          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2851          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2852          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2853          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2854          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2855          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2856          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2857          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2858          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2859          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2860          "mr 11,%1\n\t"                                           \
2861          "mr %0,3\n\t"                                            \
2862          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2863          VALGRIND_RESTORE_STACK                                   \
2864          : /*out*/   "=r" (_res)                                  \
2865          : /*in*/    "r" (&_argvec[2])                            \
2866          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2867       );                                                          \
2868       lval = (__typeof__(lval)) _res;                             \
2869    } while (0)
2870
2871 #endif /* PLAT_ppc64_linux */
2872
2873 /* ------------------------- arm-linux ------------------------- */
2874
2875 #if defined(PLAT_arm_linux)
2876
2877 /* These regs are trashed by the hidden call. */
2878 #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
2879
2880 /* Macros to save and align the stack before making a function
2881    call and restore it afterwards as gcc may not keep the stack
2882    pointer aligned if it doesn't realise calls are being made
2883    to other functions. */
2884
2885 /* This is a bit tricky.  We store the original stack pointer in r10
2886    as it is callee-saves.  gcc doesn't allow the use of r11 for some
2887    reason.  Also, we can't directly "bic" the stack pointer in thumb
2888    mode since r13 isn't an allowed register number in that context.
2889    So use r4 as a temporary, since that is about to get trashed
2890    anyway, just after each use of this macro.  Side effect is we need
2891    to be very careful about any future changes, since
2892    VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
2893 #define VALGRIND_ALIGN_STACK               \
2894       "mov r10, sp\n\t"                    \
2895       "mov r4,  sp\n\t"                    \
2896       "bic r4,  r4, #7\n\t"                \
2897       "mov sp,  r4\n\t"
2898 #define VALGRIND_RESTORE_STACK             \
2899       "mov sp,  r10\n\t"
2900
2901 /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
2902    long) == 4. */
2903
2904 #define CALL_FN_W_v(lval, orig)                                   \
2905    do {                                                           \
2906       volatile OrigFn        _orig = (orig);                      \
2907       volatile unsigned long _argvec[1];                          \
2908       volatile unsigned long _res;                                \
2909       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2910       __asm__ volatile(                                           \
2911          VALGRIND_ALIGN_STACK                                     \
2912          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2913          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2914          VALGRIND_RESTORE_STACK                                   \
2915          "mov %0, r0\n"                                           \
2916          : /*out*/   "=r" (_res)                                  \
2917          : /*in*/    "0" (&_argvec[0])                            \
2918          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2919       );                                                          \
2920       lval = (__typeof__(lval)) _res;                             \
2921    } while (0)
2922
2923 #define CALL_FN_W_W(lval, orig, arg1)                             \
2924    do {                                                           \
2925       volatile OrigFn        _orig = (orig);                      \
2926       volatile unsigned long _argvec[2];                          \
2927       volatile unsigned long _res;                                \
2928       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2929       _argvec[1] = (unsigned long)(arg1);                         \
2930       __asm__ volatile(                                           \
2931          VALGRIND_ALIGN_STACK                                     \
2932          "ldr r0, [%1, #4] \n\t"                                  \
2933          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2934          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2935          VALGRIND_RESTORE_STACK                                   \
2936          "mov %0, r0\n"                                           \
2937          : /*out*/   "=r" (_res)                                  \
2938          : /*in*/    "0" (&_argvec[0])                            \
2939          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2940       );                                                          \
2941       lval = (__typeof__(lval)) _res;                             \
2942    } while (0)
2943
2944 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2945    do {                                                           \
2946       volatile OrigFn        _orig = (orig);                      \
2947       volatile unsigned long _argvec[3];                          \
2948       volatile unsigned long _res;                                \
2949       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2950       _argvec[1] = (unsigned long)(arg1);                         \
2951       _argvec[2] = (unsigned long)(arg2);                         \
2952       __asm__ volatile(                                           \
2953          VALGRIND_ALIGN_STACK                                     \
2954          "ldr r0, [%1, #4] \n\t"                                  \
2955          "ldr r1, [%1, #8] \n\t"                                  \
2956          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2957          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2958          VALGRIND_RESTORE_STACK                                   \
2959          "mov %0, r0\n"                                           \
2960          : /*out*/   "=r" (_res)                                  \
2961          : /*in*/    "0" (&_argvec[0])                            \
2962          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2963       );                                                          \
2964       lval = (__typeof__(lval)) _res;                             \
2965    } while (0)
2966
2967 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2968    do {                                                           \
2969       volatile OrigFn        _orig = (orig);                      \
2970       volatile unsigned long _argvec[4];                          \
2971       volatile unsigned long _res;                                \
2972       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2973       _argvec[1] = (unsigned long)(arg1);                         \
2974       _argvec[2] = (unsigned long)(arg2);                         \
2975       _argvec[3] = (unsigned long)(arg3);                         \
2976       __asm__ volatile(                                           \
2977          VALGRIND_ALIGN_STACK                                     \
2978          "ldr r0, [%1, #4] \n\t"                                  \
2979          "ldr r1, [%1, #8] \n\t"                                  \
2980          "ldr r2, [%1, #12] \n\t"                                 \
2981          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2982          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2983          VALGRIND_RESTORE_STACK                                   \
2984          "mov %0, r0\n"                                           \
2985          : /*out*/   "=r" (_res)                                  \
2986          : /*in*/    "0" (&_argvec[0])                            \
2987          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2988       );                                                          \
2989       lval = (__typeof__(lval)) _res;                             \
2990    } while (0)
2991
2992 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2993    do {                                                           \
2994       volatile OrigFn        _orig = (orig);                      \
2995       volatile unsigned long _argvec[5];                          \
2996       volatile unsigned long _res;                                \
2997       _argvec[0] = (unsigned long)_orig.nraddr;                   \
2998       _argvec[1] = (unsigned long)(arg1);                         \
2999       _argvec[2] = (unsigned long)(arg2);                         \
3000       _argvec[3] = (unsigned long)(arg3);                         \
3001       _argvec[4] = (unsigned long)(arg4);                         \
3002       __asm__ volatile(                                           \
3003          VALGRIND_ALIGN_STACK                                     \
3004          "ldr r0, [%1, #4] \n\t"                                  \
3005          "ldr r1, [%1, #8] \n\t"                                  \
3006          "ldr r2, [%1, #12] \n\t"                                 \
3007          "ldr r3, [%1, #16] \n\t"                                 \
3008          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3009          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3010          VALGRIND_RESTORE_STACK                                   \
3011          "mov %0, r0"                                             \
3012          : /*out*/   "=r" (_res)                                  \
3013          : /*in*/    "0" (&_argvec[0])                            \
3014          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3015       );                                                          \
3016       lval = (__typeof__(lval)) _res;                             \
3017    } while (0)
3018
3019 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3020    do {                                                           \
3021       volatile OrigFn        _orig = (orig);                      \
3022       volatile unsigned long _argvec[6];                          \
3023       volatile unsigned long _res;                                \
3024       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3025       _argvec[1] = (unsigned long)(arg1);                         \
3026       _argvec[2] = (unsigned long)(arg2);                         \
3027       _argvec[3] = (unsigned long)(arg3);                         \
3028       _argvec[4] = (unsigned long)(arg4);                         \
3029       _argvec[5] = (unsigned long)(arg5);                         \
3030       __asm__ volatile(                                           \
3031          VALGRIND_ALIGN_STACK                                     \
3032          "sub sp, sp, #4 \n\t"                                    \
3033          "ldr r0, [%1, #20] \n\t"                                 \
3034          "push {r0} \n\t"                                         \
3035          "ldr r0, [%1, #4] \n\t"                                  \
3036          "ldr r1, [%1, #8] \n\t"                                  \
3037          "ldr r2, [%1, #12] \n\t"                                 \
3038          "ldr r3, [%1, #16] \n\t"                                 \
3039          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3040          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3041          VALGRIND_RESTORE_STACK                                   \
3042          "mov %0, r0"                                             \
3043          : /*out*/   "=r" (_res)                                  \
3044          : /*in*/    "0" (&_argvec[0])                            \
3045          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3046       );                                                          \
3047       lval = (__typeof__(lval)) _res;                             \
3048    } while (0)
3049
3050 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3051    do {                                                           \
3052       volatile OrigFn        _orig = (orig);                      \
3053       volatile unsigned long _argvec[7];                          \
3054       volatile unsigned long _res;                                \
3055       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3056       _argvec[1] = (unsigned long)(arg1);                         \
3057       _argvec[2] = (unsigned long)(arg2);                         \
3058       _argvec[3] = (unsigned long)(arg3);                         \
3059       _argvec[4] = (unsigned long)(arg4);                         \
3060       _argvec[5] = (unsigned long)(arg5);                         \
3061       _argvec[6] = (unsigned long)(arg6);                         \
3062       __asm__ volatile(                                           \
3063          VALGRIND_ALIGN_STACK                                     \
3064          "ldr r0, [%1, #20] \n\t"                                 \
3065          "ldr r1, [%1, #24] \n\t"                                 \
3066          "push {r0, r1} \n\t"                                     \
3067          "ldr r0, [%1, #4] \n\t"                                  \
3068          "ldr r1, [%1, #8] \n\t"                                  \
3069          "ldr r2, [%1, #12] \n\t"                                 \
3070          "ldr r3, [%1, #16] \n\t"                                 \
3071          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3072          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3073          VALGRIND_RESTORE_STACK                                   \
3074          "mov %0, r0"                                             \
3075          : /*out*/   "=r" (_res)                                  \
3076          : /*in*/    "0" (&_argvec[0])                            \
3077          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3078       );                                                          \
3079       lval = (__typeof__(lval)) _res;                             \
3080    } while (0)
3081
3082 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3083                                  arg7)                            \
3084    do {                                                           \
3085       volatile OrigFn        _orig = (orig);                      \
3086       volatile unsigned long _argvec[8];                          \
3087       volatile unsigned long _res;                                \
3088       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3089       _argvec[1] = (unsigned long)(arg1);                         \
3090       _argvec[2] = (unsigned long)(arg2);                         \
3091       _argvec[3] = (unsigned long)(arg3);                         \
3092       _argvec[4] = (unsigned long)(arg4);                         \
3093       _argvec[5] = (unsigned long)(arg5);                         \
3094       _argvec[6] = (unsigned long)(arg6);                         \
3095       _argvec[7] = (unsigned long)(arg7);                         \
3096       __asm__ volatile(                                           \
3097          VALGRIND_ALIGN_STACK                                     \
3098          "sub sp, sp, #4 \n\t"                                    \
3099          "ldr r0, [%1, #20] \n\t"                                 \
3100          "ldr r1, [%1, #24] \n\t"                                 \
3101          "ldr r2, [%1, #28] \n\t"                                 \
3102          "push {r0, r1, r2} \n\t"                                 \
3103          "ldr r0, [%1, #4] \n\t"                                  \
3104          "ldr r1, [%1, #8] \n\t"                                  \
3105          "ldr r2, [%1, #12] \n\t"                                 \
3106          "ldr r3, [%1, #16] \n\t"                                 \
3107          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3108          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3109          VALGRIND_RESTORE_STACK                                   \
3110          "mov %0, r0"                                             \
3111          : /*out*/   "=r" (_res)                                  \
3112          : /*in*/    "0" (&_argvec[0])                            \
3113          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3114       );                                                          \
3115       lval = (__typeof__(lval)) _res;                             \
3116    } while (0)
3117
3118 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3119                                  arg7,arg8)                       \
3120    do {                                                           \
3121       volatile OrigFn        _orig = (orig);                      \
3122       volatile unsigned long _argvec[9];                          \
3123       volatile unsigned long _res;                                \
3124       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3125       _argvec[1] = (unsigned long)(arg1);                         \
3126       _argvec[2] = (unsigned long)(arg2);                         \
3127       _argvec[3] = (unsigned long)(arg3);                         \
3128       _argvec[4] = (unsigned long)(arg4);                         \
3129       _argvec[5] = (unsigned long)(arg5);                         \
3130       _argvec[6] = (unsigned long)(arg6);                         \
3131       _argvec[7] = (unsigned long)(arg7);                         \
3132       _argvec[8] = (unsigned long)(arg8);                         \
3133       __asm__ volatile(                                           \
3134          VALGRIND_ALIGN_STACK                                     \
3135          "ldr r0, [%1, #20] \n\t"                                 \
3136          "ldr r1, [%1, #24] \n\t"                                 \
3137          "ldr r2, [%1, #28] \n\t"                                 \
3138          "ldr r3, [%1, #32] \n\t"                                 \
3139          "push {r0, r1, r2, r3} \n\t"                             \
3140          "ldr r0, [%1, #4] \n\t"                                  \
3141          "ldr r1, [%1, #8] \n\t"                                  \
3142          "ldr r2, [%1, #12] \n\t"                                 \
3143          "ldr r3, [%1, #16] \n\t"                                 \
3144          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3145          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3146          VALGRIND_RESTORE_STACK                                   \
3147          "mov %0, r0"                                             \
3148          : /*out*/   "=r" (_res)                                  \
3149          : /*in*/    "0" (&_argvec[0])                            \
3150          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3151       );                                                          \
3152       lval = (__typeof__(lval)) _res;                             \
3153    } while (0)
3154
3155 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3156                                  arg7,arg8,arg9)                  \
3157    do {                                                           \
3158       volatile OrigFn        _orig = (orig);                      \
3159       volatile unsigned long _argvec[10];                         \
3160       volatile unsigned long _res;                                \
3161       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3162       _argvec[1] = (unsigned long)(arg1);                         \
3163       _argvec[2] = (unsigned long)(arg2);                         \
3164       _argvec[3] = (unsigned long)(arg3);                         \
3165       _argvec[4] = (unsigned long)(arg4);                         \
3166       _argvec[5] = (unsigned long)(arg5);                         \
3167       _argvec[6] = (unsigned long)(arg6);                         \
3168       _argvec[7] = (unsigned long)(arg7);                         \
3169       _argvec[8] = (unsigned long)(arg8);                         \
3170       _argvec[9] = (unsigned long)(arg9);                         \
3171       __asm__ volatile(                                           \
3172          VALGRIND_ALIGN_STACK                                     \
3173          "sub sp, sp, #4 \n\t"                                    \
3174          "ldr r0, [%1, #20] \n\t"                                 \
3175          "ldr r1, [%1, #24] \n\t"                                 \
3176          "ldr r2, [%1, #28] \n\t"                                 \
3177          "ldr r3, [%1, #32] \n\t"                                 \
3178          "ldr r4, [%1, #36] \n\t"                                 \
3179          "push {r0, r1, r2, r3, r4} \n\t"                         \
3180          "ldr r0, [%1, #4] \n\t"                                  \
3181          "ldr r1, [%1, #8] \n\t"                                  \
3182          "ldr r2, [%1, #12] \n\t"                                 \
3183          "ldr r3, [%1, #16] \n\t"                                 \
3184          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3185          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3186          VALGRIND_RESTORE_STACK                                   \
3187          "mov %0, r0"                                             \
3188          : /*out*/   "=r" (_res)                                  \
3189          : /*in*/    "0" (&_argvec[0])                            \
3190          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3191       );                                                          \
3192       lval = (__typeof__(lval)) _res;                             \
3193    } while (0)
3194
3195 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3196                                   arg7,arg8,arg9,arg10)           \
3197    do {                                                           \
3198       volatile OrigFn        _orig = (orig);                      \
3199       volatile unsigned long _argvec[11];                         \
3200       volatile unsigned long _res;                                \
3201       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3202       _argvec[1] = (unsigned long)(arg1);                         \
3203       _argvec[2] = (unsigned long)(arg2);                         \
3204       _argvec[3] = (unsigned long)(arg3);                         \
3205       _argvec[4] = (unsigned long)(arg4);                         \
3206       _argvec[5] = (unsigned long)(arg5);                         \
3207       _argvec[6] = (unsigned long)(arg6);                         \
3208       _argvec[7] = (unsigned long)(arg7);                         \
3209       _argvec[8] = (unsigned long)(arg8);                         \
3210       _argvec[9] = (unsigned long)(arg9);                         \
3211       _argvec[10] = (unsigned long)(arg10);                       \
3212       __asm__ volatile(                                           \
3213          VALGRIND_ALIGN_STACK                                     \
3214          "ldr r0, [%1, #40] \n\t"                                 \
3215          "push {r0} \n\t"                                         \
3216          "ldr r0, [%1, #20] \n\t"                                 \
3217          "ldr r1, [%1, #24] \n\t"                                 \
3218          "ldr r2, [%1, #28] \n\t"                                 \
3219          "ldr r3, [%1, #32] \n\t"                                 \
3220          "ldr r4, [%1, #36] \n\t"                                 \
3221          "push {r0, r1, r2, r3, r4} \n\t"                         \
3222          "ldr r0, [%1, #4] \n\t"                                  \
3223          "ldr r1, [%1, #8] \n\t"                                  \
3224          "ldr r2, [%1, #12] \n\t"                                 \
3225          "ldr r3, [%1, #16] \n\t"                                 \
3226          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3227          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3228          VALGRIND_RESTORE_STACK                                   \
3229          "mov %0, r0"                                             \
3230          : /*out*/   "=r" (_res)                                  \
3231          : /*in*/    "0" (&_argvec[0])                            \
3232          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3233       );                                                          \
3234       lval = (__typeof__(lval)) _res;                             \
3235    } while (0)
3236
3237 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
3238                                   arg6,arg7,arg8,arg9,arg10,      \
3239                                   arg11)                          \
3240    do {                                                           \
3241       volatile OrigFn        _orig = (orig);                      \
3242       volatile unsigned long _argvec[12];                         \
3243       volatile unsigned long _res;                                \
3244       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3245       _argvec[1] = (unsigned long)(arg1);                         \
3246       _argvec[2] = (unsigned long)(arg2);                         \
3247       _argvec[3] = (unsigned long)(arg3);                         \
3248       _argvec[4] = (unsigned long)(arg4);                         \
3249       _argvec[5] = (unsigned long)(arg5);                         \
3250       _argvec[6] = (unsigned long)(arg6);                         \
3251       _argvec[7] = (unsigned long)(arg7);                         \
3252       _argvec[8] = (unsigned long)(arg8);                         \
3253       _argvec[9] = (unsigned long)(arg9);                         \
3254       _argvec[10] = (unsigned long)(arg10);                       \
3255       _argvec[11] = (unsigned long)(arg11);                       \
3256       __asm__ volatile(                                           \
3257          VALGRIND_ALIGN_STACK                                     \
3258          "sub sp, sp, #4 \n\t"                                    \
3259          "ldr r0, [%1, #40] \n\t"                                 \
3260          "ldr r1, [%1, #44] \n\t"                                 \
3261          "push {r0, r1} \n\t"                                     \
3262          "ldr r0, [%1, #20] \n\t"                                 \
3263          "ldr r1, [%1, #24] \n\t"                                 \
3264          "ldr r2, [%1, #28] \n\t"                                 \
3265          "ldr r3, [%1, #32] \n\t"                                 \
3266          "ldr r4, [%1, #36] \n\t"                                 \
3267          "push {r0, r1, r2, r3, r4} \n\t"                         \
3268          "ldr r0, [%1, #4] \n\t"                                  \
3269          "ldr r1, [%1, #8] \n\t"                                  \
3270          "ldr r2, [%1, #12] \n\t"                                 \
3271          "ldr r3, [%1, #16] \n\t"                                 \
3272          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3273          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3274          VALGRIND_RESTORE_STACK                                   \
3275          "mov %0, r0"                                             \
3276          : /*out*/   "=r" (_res)                                  \
3277          : /*in*/    "0" (&_argvec[0])                            \
3278          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3279       );                                                          \
3280       lval = (__typeof__(lval)) _res;                             \
3281    } while (0)
3282
3283 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
3284                                   arg6,arg7,arg8,arg9,arg10,      \
3285                                   arg11,arg12)                    \
3286    do {                                                           \
3287       volatile OrigFn        _orig = (orig);                      \
3288       volatile unsigned long _argvec[13];                         \
3289       volatile unsigned long _res;                                \
3290       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3291       _argvec[1] = (unsigned long)(arg1);                         \
3292       _argvec[2] = (unsigned long)(arg2);                         \
3293       _argvec[3] = (unsigned long)(arg3);                         \
3294       _argvec[4] = (unsigned long)(arg4);                         \
3295       _argvec[5] = (unsigned long)(arg5);                         \
3296       _argvec[6] = (unsigned long)(arg6);                         \
3297       _argvec[7] = (unsigned long)(arg7);                         \
3298       _argvec[8] = (unsigned long)(arg8);                         \
3299       _argvec[9] = (unsigned long)(arg9);                         \
3300       _argvec[10] = (unsigned long)(arg10);                       \
3301       _argvec[11] = (unsigned long)(arg11);                       \
3302       _argvec[12] = (unsigned long)(arg12);                       \
3303       __asm__ volatile(                                           \
3304          VALGRIND_ALIGN_STACK                                     \
3305          "ldr r0, [%1, #40] \n\t"                                 \
3306          "ldr r1, [%1, #44] \n\t"                                 \
3307          "ldr r2, [%1, #48] \n\t"                                 \
3308          "push {r0, r1, r2} \n\t"                                 \
3309          "ldr r0, [%1, #20] \n\t"                                 \
3310          "ldr r1, [%1, #24] \n\t"                                 \
3311          "ldr r2, [%1, #28] \n\t"                                 \
3312          "ldr r3, [%1, #32] \n\t"                                 \
3313          "ldr r4, [%1, #36] \n\t"                                 \
3314          "push {r0, r1, r2, r3, r4} \n\t"                         \
3315          "ldr r0, [%1, #4] \n\t"                                  \
3316          "ldr r1, [%1, #8] \n\t"                                  \
3317          "ldr r2, [%1, #12] \n\t"                                 \
3318          "ldr r3, [%1, #16] \n\t"                                 \
3319          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3320          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3321          VALGRIND_RESTORE_STACK                                   \
3322          "mov %0, r0"                                             \
3323          : /*out*/   "=r" (_res)                                  \
3324          : /*in*/    "0" (&_argvec[0])                            \
3325          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3326       );                                                          \
3327       lval = (__typeof__(lval)) _res;                             \
3328    } while (0)
3329
3330 #endif /* PLAT_arm_linux */
3331
3332 /* ------------------------- s390x-linux ------------------------- */
3333
3334 #if defined(PLAT_s390x_linux)
3335
3336 /* Similar workaround as amd64 (see above), but we use r11 as frame
3337    pointer and save the old r11 in r7. r11 might be used for
3338    argvec, therefore we copy argvec in r1 since r1 is clobbered
3339    after the call anyway.  */
3340 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3341 #  define __FRAME_POINTER                                         \
3342       ,"d"(__builtin_dwarf_cfa())
3343 #  define VALGRIND_CFI_PROLOGUE                                   \
3344       ".cfi_remember_state\n\t"                                   \
3345       "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
3346       "lgr 7,11\n\t"                                              \
3347       "lgr 11,%2\n\t"                                             \
3348       ".cfi_def_cfa r11, 0\n\t"
3349 #  define VALGRIND_CFI_EPILOGUE                                   \
3350       "lgr 11, 7\n\t"                                             \
3351       ".cfi_restore_state\n\t"
3352 #else
3353 #  define __FRAME_POINTER
3354 #  define VALGRIND_CFI_PROLOGUE                                   \
3355       "lgr 1,%1\n\t"
3356 #  define VALGRIND_CFI_EPILOGUE
3357 #endif
3358
3359 /* Nb: On s390 the stack pointer is properly aligned *at all times*
3360    according to the s390 GCC maintainer. (The ABI specification is not
3361    precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
3362    VALGRIND_RESTORE_STACK are not defined here. */
3363
3364 /* These regs are trashed by the hidden call. Note that we overwrite
3365    r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3366    function a proper return address. All others are ABI defined call
3367    clobbers. */
3368 #define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3369                            "f0","f1","f2","f3","f4","f5","f6","f7"
3370
3371 /* Nb: Although r11 is modified in the asm snippets below (inside 
3372    VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
3373    two reasons:
3374    (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
3375        modified
3376    (2) GCC will complain that r11 cannot appear inside a clobber section,
3377        when compiled with -O -fno-omit-frame-pointer
3378  */
3379
3380 #define CALL_FN_W_v(lval, orig)                                  \
3381    do {                                                          \
3382       volatile OrigFn        _orig = (orig);                     \
3383       volatile unsigned long  _argvec[1];                        \
3384       volatile unsigned long _res;                               \
3385       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3386       __asm__ volatile(                                          \
3387          VALGRIND_CFI_PROLOGUE                                   \
3388          "aghi 15,-160\n\t"                                      \
3389          "lg 1, 0(1)\n\t"  /* target->r1 */                      \
3390          VALGRIND_CALL_NOREDIR_R1                                \
3391          "lgr %0, 2\n\t"                                         \
3392          "aghi 15,160\n\t"                                       \
3393          VALGRIND_CFI_EPILOGUE                                   \
3394          : /*out*/   "=d" (_res)                                 \
3395          : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
3396          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3397       );                                                         \
3398       lval = (__typeof__(lval)) _res;                            \
3399    } while (0)
3400
3401 /* The call abi has the arguments in r2-r6 and stack */
3402 #define CALL_FN_W_W(lval, orig, arg1)                            \
3403    do {                                                          \
3404       volatile OrigFn        _orig = (orig);                     \
3405       volatile unsigned long _argvec[2];                         \
3406       volatile unsigned long _res;                               \
3407       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3408       _argvec[1] = (unsigned long)arg1;                          \
3409       __asm__ volatile(                                          \
3410          VALGRIND_CFI_PROLOGUE                                   \
3411          "aghi 15,-160\n\t"                                      \
3412          "lg 2, 8(1)\n\t"                                        \
3413          "lg 1, 0(1)\n\t"                                        \
3414          VALGRIND_CALL_NOREDIR_R1                                \
3415          "lgr %0, 2\n\t"                                         \
3416          "aghi 15,160\n\t"                                       \
3417          VALGRIND_CFI_EPILOGUE                                   \
3418          : /*out*/   "=d" (_res)                                 \
3419          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3420          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3421       );                                                         \
3422       lval = (__typeof__(lval)) _res;                            \
3423    } while (0)
3424
3425 #define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
3426    do {                                                          \
3427       volatile OrigFn        _orig = (orig);                     \
3428       volatile unsigned long _argvec[3];                         \
3429       volatile unsigned long _res;                               \
3430       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3431       _argvec[1] = (unsigned long)arg1;                          \
3432       _argvec[2] = (unsigned long)arg2;                          \
3433       __asm__ volatile(                                          \
3434          VALGRIND_CFI_PROLOGUE                                   \
3435          "aghi 15,-160\n\t"                                      \
3436          "lg 2, 8(1)\n\t"                                        \
3437          "lg 3,16(1)\n\t"                                        \
3438          "lg 1, 0(1)\n\t"                                        \
3439          VALGRIND_CALL_NOREDIR_R1                                \
3440          "lgr %0, 2\n\t"                                         \
3441          "aghi 15,160\n\t"                                       \
3442          VALGRIND_CFI_EPILOGUE                                   \
3443          : /*out*/   "=d" (_res)                                 \
3444          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3445          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3446       );                                                         \
3447       lval = (__typeof__(lval)) _res;                            \
3448    } while (0)
3449
3450 #define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
3451    do {                                                          \
3452       volatile OrigFn        _orig = (orig);                     \
3453       volatile unsigned long _argvec[4];                         \
3454       volatile unsigned long _res;                               \
3455       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3456       _argvec[1] = (unsigned long)arg1;                          \
3457       _argvec[2] = (unsigned long)arg2;                          \
3458       _argvec[3] = (unsigned long)arg3;                          \
3459       __asm__ volatile(                                          \
3460          VALGRIND_CFI_PROLOGUE                                   \
3461          "aghi 15,-160\n\t"                                      \
3462          "lg 2, 8(1)\n\t"                                        \
3463          "lg 3,16(1)\n\t"                                        \
3464          "lg 4,24(1)\n\t"                                        \
3465          "lg 1, 0(1)\n\t"                                        \
3466          VALGRIND_CALL_NOREDIR_R1                                \
3467          "lgr %0, 2\n\t"                                         \
3468          "aghi 15,160\n\t"                                       \
3469          VALGRIND_CFI_EPILOGUE                                   \
3470          : /*out*/   "=d" (_res)                                 \
3471          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3472          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3473       );                                                         \
3474       lval = (__typeof__(lval)) _res;                            \
3475    } while (0)
3476
3477 #define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
3478    do {                                                          \
3479       volatile OrigFn        _orig = (orig);                     \
3480       volatile unsigned long _argvec[5];                         \
3481       volatile unsigned long _res;                               \
3482       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3483       _argvec[1] = (unsigned long)arg1;                          \
3484       _argvec[2] = (unsigned long)arg2;                          \
3485       _argvec[3] = (unsigned long)arg3;                          \
3486       _argvec[4] = (unsigned long)arg4;                          \
3487       __asm__ volatile(                                          \
3488          VALGRIND_CFI_PROLOGUE                                   \
3489          "aghi 15,-160\n\t"                                      \
3490          "lg 2, 8(1)\n\t"                                        \
3491          "lg 3,16(1)\n\t"                                        \
3492          "lg 4,24(1)\n\t"                                        \
3493          "lg 5,32(1)\n\t"                                        \
3494          "lg 1, 0(1)\n\t"                                        \
3495          VALGRIND_CALL_NOREDIR_R1                                \
3496          "lgr %0, 2\n\t"                                         \
3497          "aghi 15,160\n\t"                                       \
3498          VALGRIND_CFI_EPILOGUE                                   \
3499          : /*out*/   "=d" (_res)                                 \
3500          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3501          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3502       );                                                         \
3503       lval = (__typeof__(lval)) _res;                            \
3504    } while (0)
3505
3506 #define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
3507    do {                                                          \
3508       volatile OrigFn        _orig = (orig);                     \
3509       volatile unsigned long _argvec[6];                         \
3510       volatile unsigned long _res;                               \
3511       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3512       _argvec[1] = (unsigned long)arg1;                          \
3513       _argvec[2] = (unsigned long)arg2;                          \
3514       _argvec[3] = (unsigned long)arg3;                          \
3515       _argvec[4] = (unsigned long)arg4;                          \
3516       _argvec[5] = (unsigned long)arg5;                          \
3517       __asm__ volatile(                                          \
3518          VALGRIND_CFI_PROLOGUE                                   \
3519          "aghi 15,-160\n\t"                                      \
3520          "lg 2, 8(1)\n\t"                                        \
3521          "lg 3,16(1)\n\t"                                        \
3522          "lg 4,24(1)\n\t"                                        \
3523          "lg 5,32(1)\n\t"                                        \
3524          "lg 6,40(1)\n\t"                                        \
3525          "lg 1, 0(1)\n\t"                                        \
3526          VALGRIND_CALL_NOREDIR_R1                                \
3527          "lgr %0, 2\n\t"                                         \
3528          "aghi 15,160\n\t"                                       \
3529          VALGRIND_CFI_EPILOGUE                                   \
3530          : /*out*/   "=d" (_res)                                 \
3531          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3532          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3533       );                                                         \
3534       lval = (__typeof__(lval)) _res;                            \
3535    } while (0)
3536
3537 #define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3538                      arg6)                                       \
3539    do {                                                          \
3540       volatile OrigFn        _orig = (orig);                     \
3541       volatile unsigned long _argvec[7];                         \
3542       volatile unsigned long _res;                               \
3543       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3544       _argvec[1] = (unsigned long)arg1;                          \
3545       _argvec[2] = (unsigned long)arg2;                          \
3546       _argvec[3] = (unsigned long)arg3;                          \
3547       _argvec[4] = (unsigned long)arg4;                          \
3548       _argvec[5] = (unsigned long)arg5;                          \
3549       _argvec[6] = (unsigned long)arg6;                          \
3550       __asm__ volatile(                                          \
3551          VALGRIND_CFI_PROLOGUE                                   \
3552          "aghi 15,-168\n\t"                                      \
3553          "lg 2, 8(1)\n\t"                                        \
3554          "lg 3,16(1)\n\t"                                        \
3555          "lg 4,24(1)\n\t"                                        \
3556          "lg 5,32(1)\n\t"                                        \
3557          "lg 6,40(1)\n\t"                                        \
3558          "mvc 160(8,15), 48(1)\n\t"                              \
3559          "lg 1, 0(1)\n\t"                                        \
3560          VALGRIND_CALL_NOREDIR_R1                                \
3561          "lgr %0, 2\n\t"                                         \
3562          "aghi 15,168\n\t"                                       \
3563          VALGRIND_CFI_EPILOGUE                                   \
3564          : /*out*/   "=d" (_res)                                 \
3565          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3566          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3567       );                                                         \
3568       lval = (__typeof__(lval)) _res;                            \
3569    } while (0)
3570
3571 #define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3572                      arg6, arg7)                                 \
3573    do {                                                          \
3574       volatile OrigFn        _orig = (orig);                     \
3575       volatile unsigned long _argvec[8];                         \
3576       volatile unsigned long _res;                               \
3577       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3578       _argvec[1] = (unsigned long)arg1;                          \
3579       _argvec[2] = (unsigned long)arg2;                          \
3580       _argvec[3] = (unsigned long)arg3;                          \
3581       _argvec[4] = (unsigned long)arg4;                          \
3582       _argvec[5] = (unsigned long)arg5;                          \
3583       _argvec[6] = (unsigned long)arg6;                          \
3584       _argvec[7] = (unsigned long)arg7;                          \
3585       __asm__ volatile(                                          \
3586          VALGRIND_CFI_PROLOGUE                                   \
3587          "aghi 15,-176\n\t"                                      \
3588          "lg 2, 8(1)\n\t"                                        \
3589          "lg 3,16(1)\n\t"                                        \
3590          "lg 4,24(1)\n\t"                                        \
3591          "lg 5,32(1)\n\t"                                        \
3592          "lg 6,40(1)\n\t"                                        \
3593          "mvc 160(8,15), 48(1)\n\t"                              \
3594          "mvc 168(8,15), 56(1)\n\t"                              \
3595          "lg 1, 0(1)\n\t"                                        \
3596          VALGRIND_CALL_NOREDIR_R1                                \
3597          "lgr %0, 2\n\t"                                         \
3598          "aghi 15,176\n\t"                                       \
3599          VALGRIND_CFI_EPILOGUE                                   \
3600          : /*out*/   "=d" (_res)                                 \
3601          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3602          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3603       );                                                         \
3604       lval = (__typeof__(lval)) _res;                            \
3605    } while (0)
3606
3607 #define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3608                      arg6, arg7 ,arg8)                           \
3609    do {                                                          \
3610       volatile OrigFn        _orig = (orig);                     \
3611       volatile unsigned long _argvec[9];                         \
3612       volatile unsigned long _res;                               \
3613       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3614       _argvec[1] = (unsigned long)arg1;                          \
3615       _argvec[2] = (unsigned long)arg2;                          \
3616       _argvec[3] = (unsigned long)arg3;                          \
3617       _argvec[4] = (unsigned long)arg4;                          \
3618       _argvec[5] = (unsigned long)arg5;                          \
3619       _argvec[6] = (unsigned long)arg6;                          \
3620       _argvec[7] = (unsigned long)arg7;                          \
3621       _argvec[8] = (unsigned long)arg8;                          \
3622       __asm__ volatile(                                          \
3623          VALGRIND_CFI_PROLOGUE                                   \
3624          "aghi 15,-184\n\t"                                      \
3625          "lg 2, 8(1)\n\t"                                        \
3626          "lg 3,16(1)\n\t"                                        \
3627          "lg 4,24(1)\n\t"                                        \
3628          "lg 5,32(1)\n\t"                                        \
3629          "lg 6,40(1)\n\t"                                        \
3630          "mvc 160(8,15), 48(1)\n\t"                              \
3631          "mvc 168(8,15), 56(1)\n\t"                              \
3632          "mvc 176(8,15), 64(1)\n\t"                              \
3633          "lg 1, 0(1)\n\t"                                        \
3634          VALGRIND_CALL_NOREDIR_R1                                \
3635          "lgr %0, 2\n\t"                                         \
3636          "aghi 15,184\n\t"                                       \
3637          VALGRIND_CFI_EPILOGUE                                   \
3638          : /*out*/   "=d" (_res)                                 \
3639          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3640          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3641       );                                                         \
3642       lval = (__typeof__(lval)) _res;                            \
3643    } while (0)
3644
3645 #define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3646                      arg6, arg7 ,arg8, arg9)                     \
3647    do {                                                          \
3648       volatile OrigFn        _orig = (orig);                     \
3649       volatile unsigned long _argvec[10];                        \
3650       volatile unsigned long _res;                               \
3651       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3652       _argvec[1] = (unsigned long)arg1;                          \
3653       _argvec[2] = (unsigned long)arg2;                          \
3654       _argvec[3] = (unsigned long)arg3;                          \
3655       _argvec[4] = (unsigned long)arg4;                          \
3656       _argvec[5] = (unsigned long)arg5;                          \
3657       _argvec[6] = (unsigned long)arg6;                          \
3658       _argvec[7] = (unsigned long)arg7;                          \
3659       _argvec[8] = (unsigned long)arg8;                          \
3660       _argvec[9] = (unsigned long)arg9;                          \
3661       __asm__ volatile(                                          \
3662          VALGRIND_CFI_PROLOGUE                                   \
3663          "aghi 15,-192\n\t"                                      \
3664          "lg 2, 8(1)\n\t"                                        \
3665          "lg 3,16(1)\n\t"                                        \
3666          "lg 4,24(1)\n\t"                                        \
3667          "lg 5,32(1)\n\t"                                        \
3668          "lg 6,40(1)\n\t"                                        \
3669          "mvc 160(8,15), 48(1)\n\t"                              \
3670          "mvc 168(8,15), 56(1)\n\t"                              \
3671          "mvc 176(8,15), 64(1)\n\t"                              \
3672          "mvc 184(8,15), 72(1)\n\t"                              \
3673          "lg 1, 0(1)\n\t"                                        \
3674          VALGRIND_CALL_NOREDIR_R1                                \
3675          "lgr %0, 2\n\t"                                         \
3676          "aghi 15,192\n\t"                                       \
3677          VALGRIND_CFI_EPILOGUE                                   \
3678          : /*out*/   "=d" (_res)                                 \
3679          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3680          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3681       );                                                         \
3682       lval = (__typeof__(lval)) _res;                            \
3683    } while (0)
3684
3685 #define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3686                      arg6, arg7 ,arg8, arg9, arg10)              \
3687    do {                                                          \
3688       volatile OrigFn        _orig = (orig);                     \
3689       volatile unsigned long _argvec[11];                        \
3690       volatile unsigned long _res;                               \
3691       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3692       _argvec[1] = (unsigned long)arg1;                          \
3693       _argvec[2] = (unsigned long)arg2;                          \
3694       _argvec[3] = (unsigned long)arg3;                          \
3695       _argvec[4] = (unsigned long)arg4;                          \
3696       _argvec[5] = (unsigned long)arg5;                          \
3697       _argvec[6] = (unsigned long)arg6;                          \
3698       _argvec[7] = (unsigned long)arg7;                          \
3699       _argvec[8] = (unsigned long)arg8;                          \
3700       _argvec[9] = (unsigned long)arg9;                          \
3701       _argvec[10] = (unsigned long)arg10;                        \
3702       __asm__ volatile(                                          \
3703          VALGRIND_CFI_PROLOGUE                                   \
3704          "aghi 15,-200\n\t"                                      \
3705          "lg 2, 8(1)\n\t"                                        \
3706          "lg 3,16(1)\n\t"                                        \
3707          "lg 4,24(1)\n\t"                                        \
3708          "lg 5,32(1)\n\t"                                        \
3709          "lg 6,40(1)\n\t"                                        \
3710          "mvc 160(8,15), 48(1)\n\t"                              \
3711          "mvc 168(8,15), 56(1)\n\t"                              \
3712          "mvc 176(8,15), 64(1)\n\t"                              \
3713          "mvc 184(8,15), 72(1)\n\t"                              \
3714          "mvc 192(8,15), 80(1)\n\t"                              \
3715          "lg 1, 0(1)\n\t"                                        \
3716          VALGRIND_CALL_NOREDIR_R1                                \
3717          "lgr %0, 2\n\t"                                         \
3718          "aghi 15,200\n\t"                                       \
3719          VALGRIND_CFI_EPILOGUE                                   \
3720          : /*out*/   "=d" (_res)                                 \
3721          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3722          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3723       );                                                         \
3724       lval = (__typeof__(lval)) _res;                            \
3725    } while (0)
3726
3727 #define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3728                      arg6, arg7 ,arg8, arg9, arg10, arg11)       \
3729    do {                                                          \
3730       volatile OrigFn        _orig = (orig);                     \
3731       volatile unsigned long _argvec[12];                        \
3732       volatile unsigned long _res;                               \
3733       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3734       _argvec[1] = (unsigned long)arg1;                          \
3735       _argvec[2] = (unsigned long)arg2;                          \
3736       _argvec[3] = (unsigned long)arg3;                          \
3737       _argvec[4] = (unsigned long)arg4;                          \
3738       _argvec[5] = (unsigned long)arg5;                          \
3739       _argvec[6] = (unsigned long)arg6;                          \
3740       _argvec[7] = (unsigned long)arg7;                          \
3741       _argvec[8] = (unsigned long)arg8;                          \
3742       _argvec[9] = (unsigned long)arg9;                          \
3743       _argvec[10] = (unsigned long)arg10;                        \
3744       _argvec[11] = (unsigned long)arg11;                        \
3745       __asm__ volatile(                                          \
3746          VALGRIND_CFI_PROLOGUE                                   \
3747          "aghi 15,-208\n\t"                                      \
3748          "lg 2, 8(1)\n\t"                                        \
3749          "lg 3,16(1)\n\t"                                        \
3750          "lg 4,24(1)\n\t"                                        \
3751          "lg 5,32(1)\n\t"                                        \
3752          "lg 6,40(1)\n\t"                                        \
3753          "mvc 160(8,15), 48(1)\n\t"                              \
3754          "mvc 168(8,15), 56(1)\n\t"                              \
3755          "mvc 176(8,15), 64(1)\n\t"                              \
3756          "mvc 184(8,15), 72(1)\n\t"                              \
3757          "mvc 192(8,15), 80(1)\n\t"                              \
3758          "mvc 200(8,15), 88(1)\n\t"                              \
3759          "lg 1, 0(1)\n\t"                                        \
3760          VALGRIND_CALL_NOREDIR_R1                                \
3761          "lgr %0, 2\n\t"                                         \
3762          "aghi 15,208\n\t"                                       \
3763          VALGRIND_CFI_EPILOGUE                                   \
3764          : /*out*/   "=d" (_res)                                 \
3765          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3766          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3767       );                                                         \
3768       lval = (__typeof__(lval)) _res;                            \
3769    } while (0)
3770
3771 #define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3772                      arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3773    do {                                                          \
3774       volatile OrigFn        _orig = (orig);                     \
3775       volatile unsigned long _argvec[13];                        \
3776       volatile unsigned long _res;                               \
3777       _argvec[0] = (unsigned long)_orig.nraddr;                  \
3778       _argvec[1] = (unsigned long)arg1;                          \
3779       _argvec[2] = (unsigned long)arg2;                          \
3780       _argvec[3] = (unsigned long)arg3;                          \
3781       _argvec[4] = (unsigned long)arg4;                          \
3782       _argvec[5] = (unsigned long)arg5;                          \
3783       _argvec[6] = (unsigned long)arg6;                          \
3784       _argvec[7] = (unsigned long)arg7;                          \
3785       _argvec[8] = (unsigned long)arg8;                          \
3786       _argvec[9] = (unsigned long)arg9;                          \
3787       _argvec[10] = (unsigned long)arg10;                        \
3788       _argvec[11] = (unsigned long)arg11;                        \
3789       _argvec[12] = (unsigned long)arg12;                        \
3790       __asm__ volatile(                                          \
3791          VALGRIND_CFI_PROLOGUE                                   \
3792          "aghi 15,-216\n\t"                                      \
3793          "lg 2, 8(1)\n\t"                                        \
3794          "lg 3,16(1)\n\t"                                        \
3795          "lg 4,24(1)\n\t"                                        \
3796          "lg 5,32(1)\n\t"                                        \
3797          "lg 6,40(1)\n\t"                                        \
3798          "mvc 160(8,15), 48(1)\n\t"                              \
3799          "mvc 168(8,15), 56(1)\n\t"                              \
3800          "mvc 176(8,15), 64(1)\n\t"                              \
3801          "mvc 184(8,15), 72(1)\n\t"                              \
3802          "mvc 192(8,15), 80(1)\n\t"                              \
3803          "mvc 200(8,15), 88(1)\n\t"                              \
3804          "mvc 208(8,15), 96(1)\n\t"                              \
3805          "lg 1, 0(1)\n\t"                                        \
3806          VALGRIND_CALL_NOREDIR_R1                                \
3807          "lgr %0, 2\n\t"                                         \
3808          "aghi 15,216\n\t"                                       \
3809          VALGRIND_CFI_EPILOGUE                                   \
3810          : /*out*/   "=d" (_res)                                 \
3811          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3812          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3813       );                                                         \
3814       lval = (__typeof__(lval)) _res;                            \
3815    } while (0)
3816
3817
3818 #endif /* PLAT_s390x_linux */
3819
3820 /* ------------------------- mips-linux ------------------------- */
3821  
3822 #if defined(PLAT_mips32_linux)
3823
3824 /* These regs are trashed by the hidden call. */
3825 #define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
3826 "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
3827 "$25", "$31"
3828
3829 /* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
3830    long) == 4. */
3831
3832 #define CALL_FN_W_v(lval, orig)                                   \
3833    do {                                                           \
3834       volatile OrigFn        _orig = (orig);                      \
3835       volatile unsigned long _argvec[1];                          \
3836       volatile unsigned long _res;                                \
3837       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3838       __asm__ volatile(                                           \
3839          "subu $29, $29, 8 \n\t"                                  \
3840          "sw $gp, 0($sp) \n\t"                                    \
3841          "sw $ra, 4($sp) \n\t"                                    \
3842         "subu $29, $29, 16 \n\t"                                 \
3843          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3844          VALGRIND_CALL_NOREDIR_T9                                 \
3845          "addu $29, $29, 16\n\t"                                  \
3846          "lw $gp, 0($sp) \n\t"                                    \
3847          "lw $ra, 4($sp) \n\t"                                    \
3848          "addu $29, $29, 8 \n\t"                                  \
3849          "move %0, $v0\n"                                         \
3850          : /*out*/   "=r" (_res)                                  \
3851          : /*in*/    "0" (&_argvec[0])                            \
3852          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3853       );                                                          \
3854       lval = (__typeof__(lval)) _res;                             \
3855    } while (0)
3856
3857 #define CALL_FN_W_W(lval, orig, arg1)                             \
3858    do {                                                           \
3859       volatile OrigFn        _orig = (orig);                      \
3860      volatile unsigned long _argvec[2];                           \
3861       volatile unsigned long _res;                                \
3862       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3863       _argvec[1] = (unsigned long)(arg1);                         \
3864       __asm__ volatile(                                           \
3865          "subu $29, $29, 8 \n\t"                                  \
3866          "sw $gp, 0($sp) \n\t"                                    \
3867          "sw $ra, 4($sp) \n\t"                                    \
3868          "subu $29, $29, 16 \n\t"                                 \
3869          "lw $a0, 4(%1) \n\t"   /* arg1*/                         \
3870          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3871          VALGRIND_CALL_NOREDIR_T9                                 \
3872          "addu $29, $29, 16 \n\t"                                 \
3873          "lw $gp, 0($sp) \n\t"                                    \
3874          "lw $ra, 4($sp) \n\t"                                    \
3875          "addu $29, $29, 8 \n\t"                                  \
3876          "move %0, $v0\n"                                         \
3877          : /*out*/   "=r" (_res)                                  \
3878         : /*in*/    "0" (&_argvec[0])                             \
3879          : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
3880       );                                                          \
3881       lval = (__typeof__(lval)) _res;                             \
3882    } while (0)
3883
3884 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3885    do {                                                           \
3886       volatile OrigFn        _orig = (orig);                      \
3887       volatile unsigned long _argvec[3];                          \
3888       volatile unsigned long _res;                                \
3889       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3890       _argvec[1] = (unsigned long)(arg1);                         \
3891       _argvec[2] = (unsigned long)(arg2);                         \
3892       __asm__ volatile(                                           \
3893          "subu $29, $29, 8 \n\t"                                  \
3894          "sw $gp, 0($sp) \n\t"                                    \
3895          "sw $ra, 4($sp) \n\t"                                    \
3896          "subu $29, $29, 16 \n\t"                                 \
3897          "lw $a0, 4(%1) \n\t"                                     \
3898          "lw $a1, 8(%1) \n\t"                                     \
3899          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3900          VALGRIND_CALL_NOREDIR_T9                                 \
3901          "addu $29, $29, 16 \n\t"                                 \
3902          "lw $gp, 0($sp) \n\t"                                    \
3903          "lw $ra, 4($sp) \n\t"                                    \
3904          "addu $29, $29, 8 \n\t"                                  \
3905          "move %0, $v0\n"                                         \
3906          : /*out*/   "=r" (_res)                                  \
3907          : /*in*/    "0" (&_argvec[0])                            \
3908          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3909       );                                                          \
3910       lval = (__typeof__(lval)) _res;                             \
3911    } while (0)
3912
3913 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3914    do {                                                           \
3915       volatile OrigFn        _orig = (orig);                      \
3916       volatile unsigned long _argvec[4];                          \
3917       volatile unsigned long _res;                                \
3918       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3919       _argvec[1] = (unsigned long)(arg1);                         \
3920       _argvec[2] = (unsigned long)(arg2);                         \
3921       _argvec[3] = (unsigned long)(arg3);                         \
3922       __asm__ volatile(                                           \
3923          "subu $29, $29, 8 \n\t"                                  \
3924          "sw $gp, 0($sp) \n\t"                                    \
3925          "sw $ra, 4($sp) \n\t"                                    \
3926          "subu $29, $29, 16 \n\t"                                 \
3927          "lw $a0, 4(%1) \n\t"                                     \
3928          "lw $a1, 8(%1) \n\t"                                     \
3929          "lw $a2, 12(%1) \n\t"                                    \
3930          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3931          VALGRIND_CALL_NOREDIR_T9                                 \
3932          "addu $29, $29, 16 \n\t"                                 \
3933          "lw $gp, 0($sp) \n\t"                                    \
3934          "lw $ra, 4($sp) \n\t"                                    \
3935          "addu $29, $29, 8 \n\t"                                  \
3936          "move %0, $v0\n"                                         \
3937          : /*out*/   "=r" (_res)                                  \
3938          : /*in*/    "0" (&_argvec[0])                            \
3939          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3940       );                                                          \
3941       lval = (__typeof__(lval)) _res;                             \
3942    } while (0)
3943
3944 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3945    do {                                                           \
3946       volatile OrigFn        _orig = (orig);                      \
3947       volatile unsigned long _argvec[5];                          \
3948       volatile unsigned long _res;                                \
3949       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3950       _argvec[1] = (unsigned long)(arg1);                         \
3951       _argvec[2] = (unsigned long)(arg2);                         \
3952       _argvec[3] = (unsigned long)(arg3);                         \
3953       _argvec[4] = (unsigned long)(arg4);                         \
3954       __asm__ volatile(                                           \
3955          "subu $29, $29, 8 \n\t"                                  \
3956          "sw $gp, 0($sp) \n\t"                                    \
3957          "sw $ra, 4($sp) \n\t"                                    \
3958          "subu $29, $29, 16 \n\t"                                 \
3959          "lw $a0, 4(%1) \n\t"                                     \
3960          "lw $a1, 8(%1) \n\t"                                     \
3961          "lw $a2, 12(%1) \n\t"                                    \
3962          "lw $a3, 16(%1) \n\t"                                    \
3963          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3964          VALGRIND_CALL_NOREDIR_T9                                 \
3965          "addu $29, $29, 16 \n\t"                                 \
3966          "lw $gp, 0($sp) \n\t"                                    \
3967          "lw $ra, 4($sp) \n\t"                                    \
3968          "addu $29, $29, 8 \n\t"                                  \
3969          "move %0, $v0\n"                                         \
3970          : /*out*/   "=r" (_res)                                  \
3971          : /*in*/    "0" (&_argvec[0])                            \
3972          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3973       );                                                          \
3974       lval = (__typeof__(lval)) _res;                             \
3975    } while (0)
3976
3977 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3978    do {                                                           \
3979       volatile OrigFn        _orig = (orig);                      \
3980       volatile unsigned long _argvec[6];                          \
3981       volatile unsigned long _res;                                \
3982       _argvec[0] = (unsigned long)_orig.nraddr;                   \
3983       _argvec[1] = (unsigned long)(arg1);                         \
3984       _argvec[2] = (unsigned long)(arg2);                         \
3985       _argvec[3] = (unsigned long)(arg3);                         \
3986       _argvec[4] = (unsigned long)(arg4);                         \
3987       _argvec[5] = (unsigned long)(arg5);                         \
3988       __asm__ volatile(                                           \
3989          "subu $29, $29, 8 \n\t"                                  \
3990          "sw $gp, 0($sp) \n\t"                                    \
3991          "sw $ra, 4($sp) \n\t"                                    \
3992          "lw $a0, 20(%1) \n\t"                                    \
3993          "subu $sp, $sp, 24\n\t"                                  \
3994          "sw $a0, 16($sp) \n\t"                                   \
3995          "lw $a0, 4(%1) \n\t"                                     \
3996          "lw $a1, 8(%1) \n\t"                                     \
3997          "lw $a2, 12(%1) \n\t"                                    \
3998          "lw $a3, 16(%1) \n\t"                                    \
3999          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4000          VALGRIND_CALL_NOREDIR_T9                                 \
4001          "addu $29, $29, 24 \n\t"                                 \
4002          "lw $gp, 0($sp) \n\t"                                    \
4003          "lw $ra, 4($sp) \n\t"                                    \
4004          "addu $sp, $sp, 8 \n\t"                                  \
4005          "move %0, $v0\n"                                         \
4006          : /*out*/   "=r" (_res)                                  \
4007          : /*in*/    "0" (&_argvec[0])                            \
4008          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4009       );                                                          \
4010       lval = (__typeof__(lval)) _res;                             \
4011    } while (0)
4012 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
4013    do {                                                           \
4014       volatile OrigFn        _orig = (orig);                      \
4015       volatile unsigned long _argvec[7];                          \
4016       volatile unsigned long _res;                                \
4017       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4018       _argvec[1] = (unsigned long)(arg1);                         \
4019       _argvec[2] = (unsigned long)(arg2);                         \
4020       _argvec[3] = (unsigned long)(arg3);                         \
4021       _argvec[4] = (unsigned long)(arg4);                         \
4022       _argvec[5] = (unsigned long)(arg5);                         \
4023       _argvec[6] = (unsigned long)(arg6);                         \
4024       __asm__ volatile(                                           \
4025          "subu $29, $29, 8 \n\t"                                  \
4026          "sw $gp, 0($sp) \n\t"                                    \
4027          "sw $ra, 4($sp) \n\t"                                    \
4028          "lw $a0, 20(%1) \n\t"                                    \
4029          "subu $sp, $sp, 32\n\t"                                  \
4030          "sw $a0, 16($sp) \n\t"                                   \
4031          "lw $a0, 24(%1) \n\t"                                    \
4032          "nop\n\t"                                                \
4033          "sw $a0, 20($sp) \n\t"                                   \
4034          "lw $a0, 4(%1) \n\t"                                     \
4035          "lw $a1, 8(%1) \n\t"                                     \
4036          "lw $a2, 12(%1) \n\t"                                    \
4037          "lw $a3, 16(%1) \n\t"                                    \
4038          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4039          VALGRIND_CALL_NOREDIR_T9                                 \
4040          "addu $sp, $sp, 32 \n\t"                                 \
4041          "lw $gp, 0($sp) \n\t"                                    \
4042          "lw $ra, 4($sp) \n\t"                                    \
4043          "addu $sp, $sp, 8 \n\t"                                  \
4044          "move %0, $v0\n"                                         \
4045          : /*out*/   "=r" (_res)                                  \
4046          : /*in*/    "0" (&_argvec[0])                            \
4047          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4048       );                                                          \
4049       lval = (__typeof__(lval)) _res;                             \
4050    } while (0)
4051
4052 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4053                                  arg7)                            \
4054    do {                                                           \
4055       volatile OrigFn        _orig = (orig);                      \
4056       volatile unsigned long _argvec[8];                          \
4057       volatile unsigned long _res;                                \
4058       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4059       _argvec[1] = (unsigned long)(arg1);                         \
4060       _argvec[2] = (unsigned long)(arg2);                         \
4061       _argvec[3] = (unsigned long)(arg3);                         \
4062       _argvec[4] = (unsigned long)(arg4);                         \
4063       _argvec[5] = (unsigned long)(arg5);                         \
4064       _argvec[6] = (unsigned long)(arg6);                         \
4065       _argvec[7] = (unsigned long)(arg7);                         \
4066       __asm__ volatile(                                           \
4067          "subu $29, $29, 8 \n\t"                                  \
4068          "sw $gp, 0($sp) \n\t"                                    \
4069          "sw $ra, 4($sp) \n\t"                                    \
4070          "lw $a0, 20(%1) \n\t"                                    \
4071          "subu $sp, $sp, 32\n\t"                                  \
4072          "sw $a0, 16($sp) \n\t"                                   \
4073          "lw $a0, 24(%1) \n\t"                                    \
4074          "sw $a0, 20($sp) \n\t"                                   \
4075          "lw $a0, 28(%1) \n\t"                                    \
4076          "sw $a0, 24($sp) \n\t"                                   \
4077          "lw $a0, 4(%1) \n\t"                                     \
4078          "lw $a1, 8(%1) \n\t"                                     \
4079          "lw $a2, 12(%1) \n\t"                                    \
4080          "lw $a3, 16(%1) \n\t"                                    \
4081          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4082          VALGRIND_CALL_NOREDIR_T9                                 \
4083          "addu $sp, $sp, 32 \n\t"                                 \
4084          "lw $gp, 0($sp) \n\t"                                    \
4085          "lw $ra, 4($sp) \n\t"                                    \
4086          "addu $sp, $sp, 8 \n\t"                                  \
4087          "move %0, $v0\n"                                         \
4088          : /*out*/   "=r" (_res)                                  \
4089          : /*in*/    "0" (&_argvec[0])                            \
4090          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4091       );                                                          \
4092       lval = (__typeof__(lval)) _res;                             \
4093    } while (0)
4094
4095 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4096                                  arg7,arg8)                       \
4097    do {                                                           \
4098       volatile OrigFn        _orig = (orig);                      \
4099       volatile unsigned long _argvec[9];                          \
4100       volatile unsigned long _res;                                \
4101       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4102       _argvec[1] = (unsigned long)(arg1);                         \
4103       _argvec[2] = (unsigned long)(arg2);                         \
4104       _argvec[3] = (unsigned long)(arg3);                         \
4105       _argvec[4] = (unsigned long)(arg4);                         \
4106       _argvec[5] = (unsigned long)(arg5);                         \
4107       _argvec[6] = (unsigned long)(arg6);                         \
4108       _argvec[7] = (unsigned long)(arg7);                         \
4109       _argvec[8] = (unsigned long)(arg8);                         \
4110       __asm__ volatile(                                           \
4111          "subu $29, $29, 8 \n\t"                                  \
4112          "sw $gp, 0($sp) \n\t"                                    \
4113          "sw $ra, 4($sp) \n\t"                                    \
4114          "lw $a0, 20(%1) \n\t"                                    \
4115          "subu $sp, $sp, 40\n\t"                                  \
4116          "sw $a0, 16($sp) \n\t"                                   \
4117          "lw $a0, 24(%1) \n\t"                                    \
4118          "sw $a0, 20($sp) \n\t"                                   \
4119          "lw $a0, 28(%1) \n\t"                                    \
4120          "sw $a0, 24($sp) \n\t"                                   \
4121          "lw $a0, 32(%1) \n\t"                                    \
4122          "sw $a0, 28($sp) \n\t"                                   \
4123          "lw $a0, 4(%1) \n\t"                                     \
4124          "lw $a1, 8(%1) \n\t"                                     \
4125          "lw $a2, 12(%1) \n\t"                                    \
4126          "lw $a3, 16(%1) \n\t"                                    \
4127          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4128          VALGRIND_CALL_NOREDIR_T9                                 \
4129          "addu $sp, $sp, 40 \n\t"                                 \
4130          "lw $gp, 0($sp) \n\t"                                    \
4131          "lw $ra, 4($sp) \n\t"                                    \
4132          "addu $sp, $sp, 8 \n\t"                                  \
4133          "move %0, $v0\n"                                         \
4134          : /*out*/   "=r" (_res)                                  \
4135          : /*in*/    "0" (&_argvec[0])                            \
4136          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4137       );                                                          \
4138       lval = (__typeof__(lval)) _res;                             \
4139    } while (0)
4140
4141 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4142                                  arg7,arg8,arg9)                  \
4143    do {                                                           \
4144       volatile OrigFn        _orig = (orig);                      \
4145       volatile unsigned long _argvec[10];                         \
4146       volatile unsigned long _res;                                \
4147       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4148       _argvec[1] = (unsigned long)(arg1);                         \
4149       _argvec[2] = (unsigned long)(arg2);                         \
4150       _argvec[3] = (unsigned long)(arg3);                         \
4151       _argvec[4] = (unsigned long)(arg4);                         \
4152       _argvec[5] = (unsigned long)(arg5);                         \
4153       _argvec[6] = (unsigned long)(arg6);                         \
4154       _argvec[7] = (unsigned long)(arg7);                         \
4155       _argvec[8] = (unsigned long)(arg8);                         \
4156       _argvec[9] = (unsigned long)(arg9);                         \
4157       __asm__ volatile(                                           \
4158          "subu $29, $29, 8 \n\t"                                  \
4159          "sw $gp, 0($sp) \n\t"                                    \
4160          "sw $ra, 4($sp) \n\t"                                    \
4161          "lw $a0, 20(%1) \n\t"                                    \
4162          "subu $sp, $sp, 40\n\t"                                  \
4163          "sw $a0, 16($sp) \n\t"                                   \
4164          "lw $a0, 24(%1) \n\t"                                    \
4165          "sw $a0, 20($sp) \n\t"                                   \
4166          "lw $a0, 28(%1) \n\t"                                    \
4167          "sw $a0, 24($sp) \n\t"                                   \
4168          "lw $a0, 32(%1) \n\t"                                    \
4169          "sw $a0, 28($sp) \n\t"                                   \
4170          "lw $a0, 36(%1) \n\t"                                    \
4171          "sw $a0, 32($sp) \n\t"                                   \
4172          "lw $a0, 4(%1) \n\t"                                     \
4173          "lw $a1, 8(%1) \n\t"                                     \
4174          "lw $a2, 12(%1) \n\t"                                    \
4175          "lw $a3, 16(%1) \n\t"                                    \
4176          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4177          VALGRIND_CALL_NOREDIR_T9                                 \
4178          "addu $sp, $sp, 40 \n\t"                                 \
4179          "lw $gp, 0($sp) \n\t"                                    \
4180          "lw $ra, 4($sp) \n\t"                                    \
4181          "addu $sp, $sp, 8 \n\t"                                  \
4182          "move %0, $v0\n"                                         \
4183          : /*out*/   "=r" (_res)                                  \
4184          : /*in*/    "0" (&_argvec[0])                            \
4185          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4186       );                                                          \
4187       lval = (__typeof__(lval)) _res;                             \
4188    } while (0)
4189
4190 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
4191                                   arg7,arg8,arg9,arg10)           \
4192    do {                                                           \
4193       volatile OrigFn        _orig = (orig);                      \
4194       volatile unsigned long _argvec[11];                         \
4195       volatile unsigned long _res;                                \
4196       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4197       _argvec[1] = (unsigned long)(arg1);                         \
4198       _argvec[2] = (unsigned long)(arg2);                         \
4199       _argvec[3] = (unsigned long)(arg3);                         \
4200       _argvec[4] = (unsigned long)(arg4);                         \
4201       _argvec[5] = (unsigned long)(arg5);                         \
4202       _argvec[6] = (unsigned long)(arg6);                         \
4203       _argvec[7] = (unsigned long)(arg7);                         \
4204       _argvec[8] = (unsigned long)(arg8);                         \
4205       _argvec[9] = (unsigned long)(arg9);                         \
4206       _argvec[10] = (unsigned long)(arg10);                       \
4207       __asm__ volatile(                                           \
4208          "subu $29, $29, 8 \n\t"                                  \
4209          "sw $gp, 0($sp) \n\t"                                    \
4210          "sw $ra, 4($sp) \n\t"                                    \
4211          "lw $a0, 20(%1) \n\t"                                    \
4212          "subu $sp, $sp, 48\n\t"                                  \
4213          "sw $a0, 16($sp) \n\t"                                   \
4214          "lw $a0, 24(%1) \n\t"                                    \
4215          "sw $a0, 20($sp) \n\t"                                   \
4216          "lw $a0, 28(%1) \n\t"                                    \
4217          "sw $a0, 24($sp) \n\t"                                   \
4218          "lw $a0, 32(%1) \n\t"                                    \
4219          "sw $a0, 28($sp) \n\t"                                   \
4220          "lw $a0, 36(%1) \n\t"                                    \
4221          "sw $a0, 32($sp) \n\t"                                   \
4222          "lw $a0, 40(%1) \n\t"                                    \
4223          "sw $a0, 36($sp) \n\t"                                   \
4224          "lw $a0, 4(%1) \n\t"                                     \
4225          "lw $a1, 8(%1) \n\t"                                     \
4226          "lw $a2, 12(%1) \n\t"                                    \
4227          "lw $a3, 16(%1) \n\t"                                    \
4228          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4229          VALGRIND_CALL_NOREDIR_T9                                 \
4230          "addu $sp, $sp, 48 \n\t"                                 \
4231          "lw $gp, 0($sp) \n\t"                                    \
4232          "lw $ra, 4($sp) \n\t"                                    \
4233          "addu $sp, $sp, 8 \n\t"                                  \
4234          "move %0, $v0\n"                                         \
4235          : /*out*/   "=r" (_res)                                  \
4236          : /*in*/    "0" (&_argvec[0])                            \
4237          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4238       );                                                          \
4239       lval = (__typeof__(lval)) _res;                             \
4240    } while (0)
4241
4242 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
4243                                   arg6,arg7,arg8,arg9,arg10,      \
4244                                   arg11)                          \
4245    do {                                                           \
4246       volatile OrigFn        _orig = (orig);                      \
4247       volatile unsigned long _argvec[12];                         \
4248       volatile unsigned long _res;                                \
4249       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4250       _argvec[1] = (unsigned long)(arg1);                         \
4251       _argvec[2] = (unsigned long)(arg2);                         \
4252       _argvec[3] = (unsigned long)(arg3);                         \
4253       _argvec[4] = (unsigned long)(arg4);                         \
4254       _argvec[5] = (unsigned long)(arg5);                         \
4255       _argvec[6] = (unsigned long)(arg6);                         \
4256       _argvec[7] = (unsigned long)(arg7);                         \
4257       _argvec[8] = (unsigned long)(arg8);                         \
4258       _argvec[9] = (unsigned long)(arg9);                         \
4259       _argvec[10] = (unsigned long)(arg10);                       \
4260       _argvec[11] = (unsigned long)(arg11);                       \
4261       __asm__ volatile(                                           \
4262          "subu $29, $29, 8 \n\t"                                  \
4263          "sw $gp, 0($sp) \n\t"                                    \
4264          "sw $ra, 4($sp) \n\t"                                    \
4265          "lw $a0, 20(%1) \n\t"                                    \
4266          "subu $sp, $sp, 48\n\t"                                  \
4267          "sw $a0, 16($sp) \n\t"                                   \
4268          "lw $a0, 24(%1) \n\t"                                    \
4269          "sw $a0, 20($sp) \n\t"                                   \
4270          "lw $a0, 28(%1) \n\t"                                    \
4271          "sw $a0, 24($sp) \n\t"                                   \
4272          "lw $a0, 32(%1) \n\t"                                    \
4273          "sw $a0, 28($sp) \n\t"                                   \
4274          "lw $a0, 36(%1) \n\t"                                    \
4275          "sw $a0, 32($sp) \n\t"                                   \
4276          "lw $a0, 40(%1) \n\t"                                    \
4277          "sw $a0, 36($sp) \n\t"                                   \
4278          "lw $a0, 44(%1) \n\t"                                    \
4279          "sw $a0, 40($sp) \n\t"                                   \
4280          "lw $a0, 4(%1) \n\t"                                     \
4281          "lw $a1, 8(%1) \n\t"                                     \
4282          "lw $a2, 12(%1) \n\t"                                    \
4283          "lw $a3, 16(%1) \n\t"                                    \
4284          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4285          VALGRIND_CALL_NOREDIR_T9                                 \
4286          "addu $sp, $sp, 48 \n\t"                                 \
4287          "lw $gp, 0($sp) \n\t"                                    \
4288          "lw $ra, 4($sp) \n\t"                                    \
4289          "addu $sp, $sp, 8 \n\t"                                  \
4290          "move %0, $v0\n"                                         \
4291          : /*out*/   "=r" (_res)                                  \
4292          : /*in*/    "0" (&_argvec[0])                            \
4293          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4294       );                                                          \
4295       lval = (__typeof__(lval)) _res;                             \
4296    } while (0)
4297
4298 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
4299                                   arg6,arg7,arg8,arg9,arg10,      \
4300                                   arg11,arg12)                    \
4301    do {                                                           \
4302       volatile OrigFn        _orig = (orig);                      \
4303       volatile unsigned long _argvec[13];                         \
4304       volatile unsigned long _res;                                \
4305       _argvec[0] = (unsigned long)_orig.nraddr;                   \
4306       _argvec[1] = (unsigned long)(arg1);                         \
4307       _argvec[2] = (unsigned long)(arg2);                         \
4308       _argvec[3] = (unsigned long)(arg3);                         \
4309       _argvec[4] = (unsigned long)(arg4);                         \
4310       _argvec[5] = (unsigned long)(arg5);                         \
4311       _argvec[6] = (unsigned long)(arg6);                         \
4312       _argvec[7] = (unsigned long)(arg7);                         \
4313       _argvec[8] = (unsigned long)(arg8);                         \
4314       _argvec[9] = (unsigned long)(arg9);                         \
4315       _argvec[10] = (unsigned long)(arg10);                       \
4316       _argvec[11] = (unsigned long)(arg11);                       \
4317       _argvec[12] = (unsigned long)(arg12);                       \
4318       __asm__ volatile(                                           \
4319          "subu $29, $29, 8 \n\t"                                  \
4320          "sw $gp, 0($sp) \n\t"                                    \
4321          "sw $ra, 4($sp) \n\t"                                    \
4322          "lw $a0, 20(%1) \n\t"                                    \
4323          "subu $sp, $sp, 56\n\t"                                  \
4324          "sw $a0, 16($sp) \n\t"                                   \
4325          "lw $a0, 24(%1) \n\t"                                    \
4326          "sw $a0, 20($sp) \n\t"                                   \
4327          "lw $a0, 28(%1) \n\t"                                    \
4328          "sw $a0, 24($sp) \n\t"                                   \
4329          "lw $a0, 32(%1) \n\t"                                    \
4330          "sw $a0, 28($sp) \n\t"                                   \
4331          "lw $a0, 36(%1) \n\t"                                    \
4332          "sw $a0, 32($sp) \n\t"                                   \
4333          "lw $a0, 40(%1) \n\t"                                    \
4334          "sw $a0, 36($sp) \n\t"                                   \
4335          "lw $a0, 44(%1) \n\t"                                    \
4336          "sw $a0, 40($sp) \n\t"                                   \
4337          "lw $a0, 48(%1) \n\t"                                    \
4338          "sw $a0, 44($sp) \n\t"                                   \
4339          "lw $a0, 4(%1) \n\t"                                     \
4340          "lw $a1, 8(%1) \n\t"                                     \
4341          "lw $a2, 12(%1) \n\t"                                    \
4342          "lw $a3, 16(%1) \n\t"                                    \
4343          "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4344          VALGRIND_CALL_NOREDIR_T9                                 \
4345          "addu $sp, $sp, 56 \n\t"                                 \
4346          "lw $gp, 0($sp) \n\t"                                    \
4347          "lw $ra, 4($sp) \n\t"                                    \
4348          "addu $sp, $sp, 8 \n\t"                                  \
4349          "move %0, $v0\n"                                         \
4350          : /*out*/   "=r" (_res)                                  \
4351          : /*in*/    "0" (&_argvec[0])                            \
4352          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4353       );                                                          \
4354       lval = (__typeof__(lval)) _res;                             \
4355    } while (0)
4356
4357 #endif /* PLAT_mips32_linux */
4358
4359
4360 /* ------------------------------------------------------------------ */
4361 /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
4362 /*                                                                    */
4363 /* ------------------------------------------------------------------ */
4364
4365 /* Some request codes.  There are many more of these, but most are not
4366    exposed to end-user view.  These are the public ones, all of the
4367    form 0x1000 + small_number.
4368
4369    Core ones are in the range 0x00000000--0x0000ffff.  The non-public
4370    ones start at 0x2000.
4371 */
4372
4373 /* These macros are used by tools -- they must be public, but don't
4374    embed them into other programs. */
4375 #define VG_USERREQ_TOOL_BASE(a,b) \
4376    ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
4377 #define VG_IS_TOOL_USERREQ(a, b, v) \
4378    (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
4379
4380 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
4381    This enum comprises an ABI exported by Valgrind to programs
4382    which use client requests.  DO NOT CHANGE THE ORDER OF THESE
4383    ENTRIES, NOR DELETE ANY -- add new ones at the end. */
4384 typedef
4385    enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
4386           VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
4387
4388           /* These allow any function to be called from the simulated
4389              CPU but run on the real CPU.  Nb: the first arg passed to
4390              the function is always the ThreadId of the running
4391              thread!  So CLIENT_CALL0 actually requires a 1 arg
4392              function, etc. */
4393           VG_USERREQ__CLIENT_CALL0 = 0x1101,
4394           VG_USERREQ__CLIENT_CALL1 = 0x1102,
4395           VG_USERREQ__CLIENT_CALL2 = 0x1103,
4396           VG_USERREQ__CLIENT_CALL3 = 0x1104,
4397
4398           /* Can be useful in regression testing suites -- eg. can
4399              send Valgrind's output to /dev/null and still count
4400              errors. */
4401           VG_USERREQ__COUNT_ERRORS = 0x1201,
4402
4403           /* Allows a string (gdb monitor command) to be passed to the tool
4404              Used for interaction with vgdb/gdb */
4405           VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
4406
4407           /* These are useful and can be interpreted by any tool that
4408              tracks malloc() et al, by using vg_replace_malloc.c. */
4409           VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
4410           VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
4411           VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
4412           /* Memory pool support. */
4413           VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
4414           VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
4415           VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
4416           VG_USERREQ__MEMPOOL_FREE     = 0x1306,
4417           VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
4418           VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
4419           VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
4420           VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
4421
4422           /* Allow printfs to valgrind log. */
4423           /* The first two pass the va_list argument by value, which
4424              assumes it is the same size as or smaller than a UWord,
4425              which generally isn't the case.  Hence are deprecated.
4426              The second two pass the vargs by reference and so are
4427              immune to this problem. */
4428           /* both :: char* fmt, va_list vargs (DEPRECATED) */
4429           VG_USERREQ__PRINTF           = 0x1401,
4430           VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
4431           /* both :: char* fmt, va_list* vargs */
4432           VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
4433           VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
4434
4435           /* Stack support. */
4436           VG_USERREQ__STACK_REGISTER   = 0x1501,
4437           VG_USERREQ__STACK_DEREGISTER = 0x1502,
4438           VG_USERREQ__STACK_CHANGE     = 0x1503,
4439
4440           /* Wine support */
4441           VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
4442
4443           /* Querying of debug info. */
4444           VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
4445
4446           /* Disable/enable error reporting level.  Takes a single
4447              Word arg which is the delta to this thread's error
4448              disablement indicator.  Hence 1 disables or further
4449              disables errors, and -1 moves back towards enablement.
4450              Other values are not allowed. */
4451           VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801
4452    } Vg_ClientRequest;
4453
4454 #if !defined(__GNUC__)
4455 #  define __extension__ /* */
4456 #endif
4457
4458
4459 /* Returns the number of Valgrinds this code is running under.  That
4460    is, 0 if running natively, 1 if running under Valgrind, 2 if
4461    running under Valgrind which is running under another Valgrind,
4462    etc. */
4463 #define RUNNING_ON_VALGRIND                                           \
4464     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
4465                                     VG_USERREQ__RUNNING_ON_VALGRIND,  \
4466                                     0, 0, 0, 0, 0)                    \
4467
4468
4469 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
4470    _qzz_len - 1].  Useful if you are debugging a JITter or some such,
4471    since it provides a way to make sure valgrind will retranslate the
4472    invalidated area.  Returns no value. */
4473 #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
4474     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
4475                                     _qzz_addr, _qzz_len, 0, 0, 0)
4476
4477
4478 /* These requests are for getting Valgrind itself to print something.
4479    Possibly with a backtrace.  This is a really ugly hack.  The return value
4480    is the number of characters printed, excluding the "**<pid>** " part at the
4481    start and the backtrace (if present). */
4482
4483 #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
4484 /* Modern GCC will optimize the static routine out if unused,
4485    and unused attribute will shut down warnings about it.  */
4486 static int VALGRIND_PRINTF(const char *format, ...)
4487    __attribute__((format(__printf__, 1, 2), __unused__));
4488 #endif
4489 static int
4490 #if defined(_MSC_VER)
4491 __inline
4492 #endif
4493 VALGRIND_PRINTF(const char *format, ...)
4494 {
4495 #if defined(NVALGRIND)
4496    return 0;
4497 #else /* NVALGRIND */
4498 #if defined(_MSC_VER)
4499    uintptr_t _qzz_res;
4500 #else
4501    unsigned long _qzz_res;
4502 #endif
4503    va_list vargs;
4504    va_start(vargs, format);
4505 #if defined(_MSC_VER)
4506    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4507                               VG_USERREQ__PRINTF_VALIST_BY_REF,
4508                               (uintptr_t)format,
4509                               (uintptr_t)&vargs,
4510                               0, 0, 0);
4511 #else
4512    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4513                               VG_USERREQ__PRINTF_VALIST_BY_REF,
4514                               (unsigned long)format,
4515                               (unsigned long)&vargs, 
4516                               0, 0, 0);
4517 #endif
4518    va_end(vargs);
4519    return (int)_qzz_res;
4520 #endif /* NVALGRIND */
4521 }
4522
4523 #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
4524 static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
4525    __attribute__((format(__printf__, 1, 2), __unused__));
4526 #endif
4527 static int
4528 #if defined(_MSC_VER)
4529 __inline
4530 #endif
4531 VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
4532 {
4533 #if defined(NVALGRIND)
4534    return 0;
4535 #else /* NVALGRIND */
4536 #if defined(_MSC_VER)
4537    uintptr_t _qzz_res;
4538 #else
4539    unsigned long _qzz_res;
4540 #endif
4541    va_list vargs;
4542    va_start(vargs, format);
4543 #if defined(_MSC_VER)
4544    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4545                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
4546                               (uintptr_t)format,
4547                               (uintptr_t)&vargs,
4548                               0, 0, 0);
4549 #else
4550    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4551                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
4552                               (unsigned long)format,
4553                               (unsigned long)&vargs, 
4554                               0, 0, 0);
4555 #endif
4556    va_end(vargs);
4557    return (int)_qzz_res;
4558 #endif /* NVALGRIND */
4559 }
4560
4561
4562 /* These requests allow control to move from the simulated CPU to the
4563    real CPU, calling an arbitary function.
4564    
4565    Note that the current ThreadId is inserted as the first argument.
4566    So this call:
4567
4568      VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
4569
4570    requires f to have this signature:
4571
4572      Word f(Word tid, Word arg1, Word arg2)
4573
4574    where "Word" is a word-sized type.
4575
4576    Note that these client requests are not entirely reliable.  For example,
4577    if you call a function with them that subsequently calls printf(),
4578    there's a high chance Valgrind will crash.  Generally, your prospects of
4579    these working are made higher if the called function does not refer to
4580    any global variables, and does not refer to any libc or other functions
4581    (printf et al).  Any kind of entanglement with libc or dynamic linking is
4582    likely to have a bad outcome, for tricky reasons which we've grappled
4583    with a lot in the past.
4584 */
4585 #define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
4586     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
4587                                     VG_USERREQ__CLIENT_CALL0,     \
4588                                     _qyy_fn,                      \
4589                                     0, 0, 0, 0)
4590
4591 #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
4592     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4593                                     VG_USERREQ__CLIENT_CALL1,          \
4594                                     _qyy_fn,                           \
4595                                     _qyy_arg1, 0, 0, 0)
4596
4597 #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
4598     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4599                                     VG_USERREQ__CLIENT_CALL2,          \
4600                                     _qyy_fn,                           \
4601                                     _qyy_arg1, _qyy_arg2, 0, 0)
4602
4603 #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
4604     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
4605                                     VG_USERREQ__CLIENT_CALL3,           \
4606                                     _qyy_fn,                            \
4607                                     _qyy_arg1, _qyy_arg2,               \
4608                                     _qyy_arg3, 0)
4609
4610
4611 /* Counts the number of errors that have been recorded by a tool.  Nb:
4612    the tool must record the errors with VG_(maybe_record_error)() or
4613    VG_(unique_error)() for them to be counted. */
4614 #define VALGRIND_COUNT_ERRORS                                     \
4615     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
4616                                0 /* default return */,            \
4617                                VG_USERREQ__COUNT_ERRORS,          \
4618                                0, 0, 0, 0, 0)
4619
4620 /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
4621    when heap blocks are allocated in order to give accurate results.  This
4622    happens automatically for the standard allocator functions such as
4623    malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
4624    delete[], etc.
4625
4626    But if your program uses a custom allocator, this doesn't automatically
4627    happen, and Valgrind will not do as well.  For example, if you allocate
4628    superblocks with mmap() and then allocates chunks of the superblocks, all
4629    Valgrind's observations will be at the mmap() level and it won't know that
4630    the chunks should be considered separate entities.  In Memcheck's case,
4631    that means you probably won't get heap block overrun detection (because
4632    there won't be redzones marked as unaddressable) and you definitely won't
4633    get any leak detection.
4634
4635    The following client requests allow a custom allocator to be annotated so
4636    that it can be handled accurately by Valgrind.
4637
4638    VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
4639    by a malloc()-like function.  For Memcheck (an illustrative case), this
4640    does two things:
4641
4642    - It records that the block has been allocated.  This means any addresses
4643      within the block mentioned in error messages will be
4644      identified as belonging to the block.  It also means that if the block
4645      isn't freed it will be detected by the leak checker.
4646
4647    - It marks the block as being addressable and undefined (if 'is_zeroed' is
4648      not set), or addressable and defined (if 'is_zeroed' is set).  This
4649      controls how accesses to the block by the program are handled.
4650    
4651    'addr' is the start of the usable block (ie. after any
4652    redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
4653    can apply redzones -- these are blocks of padding at the start and end of
4654    each block.  Adding redzones is recommended as it makes it much more likely
4655    Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
4656    zeroed (or filled with another predictable value), as is the case for
4657    calloc().
4658    
4659    VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
4660    heap block -- that will be used by the client program -- is allocated.
4661    It's best to put it at the outermost level of the allocator if possible;
4662    for example, if you have a function my_alloc() which calls
4663    internal_alloc(), and the client request is put inside internal_alloc(),
4664    stack traces relating to the heap block will contain entries for both
4665    my_alloc() and internal_alloc(), which is probably not what you want.
4666
4667    For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
4668    custom blocks from within a heap block, B, that has been allocated with
4669    malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
4670    -- the custom blocks will take precedence.
4671
4672    VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
4673    Memcheck, it does two things:
4674
4675    - It records that the block has been deallocated.  This assumes that the
4676      block was annotated as having been allocated via
4677      VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
4678
4679    - It marks the block as being unaddressable.
4680
4681    VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
4682    heap block is deallocated.
4683
4684    VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
4685    Memcheck, it does four things:
4686
4687    - It records that the size of a block has been changed.  This assumes that
4688      the block was annotated as having been allocated via
4689      VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
4690
4691    - If the block shrunk, it marks the freed memory as being unaddressable.
4692
4693    - If the block grew, it marks the new area as undefined and defines a red
4694      zone past the end of the new block.
4695
4696    - The V-bits of the overlap between the old and the new block are preserved.
4697
4698    VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
4699    and before deallocation of the old block.
4700
4701    In many cases, these three client requests will not be enough to get your
4702    allocator working well with Memcheck.  More specifically, if your allocator
4703    writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
4704    will be necessary to mark the memory as addressable just before the zeroing
4705    occurs, otherwise you'll get a lot of invalid write errors.  For example,
4706    you'll need to do this if your allocator recycles freed blocks, but it
4707    zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
4708    Alternatively, if your allocator reuses freed blocks for allocator-internal
4709    data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
4710
4711    Really, what's happening is a blurring of the lines between the client
4712    program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
4713    memory should be considered unaddressable to the client program, but the
4714    allocator knows more than the rest of the client program and so may be able
4715    to safely access it.  Extra client requests are necessary for Valgrind to
4716    understand the distinction between the allocator and the rest of the
4717    program.
4718
4719    Ignored if addr == 0.
4720 */
4721 #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
4722     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
4723                                     addr, sizeB, rzB, is_zeroed, 0)
4724
4725 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
4726    Ignored if addr == 0.
4727 */
4728 #define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
4729     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
4730                                     addr, oldSizeB, newSizeB, rzB, 0)
4731
4732 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
4733    Ignored if addr == 0.
4734 */
4735 #define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
4736     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
4737                                     addr, rzB, 0, 0, 0)
4738
4739 /* Create a memory pool. */
4740 #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
4741     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
4742                                     pool, rzB, is_zeroed, 0, 0)
4743
4744 /* Destroy a memory pool. */
4745 #define VALGRIND_DESTROY_MEMPOOL(pool)                            \
4746     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
4747                                     pool, 0, 0, 0, 0)
4748
4749 /* Associate a piece of memory with a memory pool. */
4750 #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
4751     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
4752                                     pool, addr, size, 0, 0)
4753
4754 /* Disassociate a piece of memory from a memory pool. */
4755 #define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
4756     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
4757                                     pool, addr, 0, 0, 0)
4758
4759 /* Disassociate any pieces outside a particular range. */
4760 #define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
4761     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
4762                                     pool, addr, size, 0, 0)
4763
4764 /* Resize and/or move a piece associated with a memory pool. */
4765 #define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
4766     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
4767                                     poolA, poolB, 0, 0, 0)
4768
4769 /* Resize and/or move a piece associated with a memory pool. */
4770 #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
4771     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
4772                                     pool, addrA, addrB, size, 0)
4773
4774 /* Return 1 if a mempool exists, else 0. */
4775 #define VALGRIND_MEMPOOL_EXISTS(pool)                             \
4776     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4777                                VG_USERREQ__MEMPOOL_EXISTS,        \
4778                                pool, 0, 0, 0, 0)
4779
4780 /* Mark a piece of memory as being a stack. Returns a stack id. */
4781 #define VALGRIND_STACK_REGISTER(start, end)                       \
4782     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4783                                VG_USERREQ__STACK_REGISTER,        \
4784                                start, end, 0, 0, 0)
4785
4786 /* Unmark the piece of memory associated with a stack id as being a
4787    stack. */
4788 #define VALGRIND_STACK_DEREGISTER(id)                             \
4789     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
4790                                     id, 0, 0, 0, 0)
4791
4792 /* Change the start and end address of the stack id. */
4793 #define VALGRIND_STACK_CHANGE(id, start, end)                     \
4794     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
4795                                     id, start, end, 0, 0)
4796
4797 /* Load PDB debug info for Wine PE image_map. */
4798 #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
4799     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
4800                                     fd, ptr, total_size, delta, 0)
4801
4802 /* Map a code address to a source file name and line number.  buf64
4803    must point to a 64-byte buffer in the caller's address space.  The
4804    result will be dumped in there and is guaranteed to be zero
4805    terminated.  If no info is found, the first byte is set to zero. */
4806 #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
4807     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4808                                VG_USERREQ__MAP_IP_TO_SRCLOC,      \
4809                                addr, buf64, 0, 0, 0)
4810
4811 /* Disable error reporting for this thread.  Behaves in a stack like
4812    way, so you can safely call this multiple times provided that
4813    VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
4814    to re-enable reporting.  The first call of this macro disables
4815    reporting.  Subsequent calls have no effect except to increase the
4816    number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
4817    reporting.  Child threads do not inherit this setting from their
4818    parents -- they are always created with reporting enabled. */
4819 #define VALGRIND_DISABLE_ERROR_REPORTING                                \
4820     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4821                                     1, 0, 0, 0, 0)
4822
4823 /* Re-enable error reporting, as per comments on
4824    VALGRIND_DISABLE_ERROR_REPORTING. */
4825 #define VALGRIND_ENABLE_ERROR_REPORTING                                 \
4826     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4827                                     -1, 0, 0, 0, 0)
4828
4829 #undef PLAT_x86_darwin
4830 #undef PLAT_amd64_darwin
4831 #undef PLAT_x86_win32
4832 #undef PLAT_x86_linux
4833 #undef PLAT_amd64_linux
4834 #undef PLAT_ppc32_linux
4835 #undef PLAT_ppc64_linux
4836 #undef PLAT_arm_linux
4837 #undef PLAT_s390x_linux
4838 #undef PLAT_mips32_linux
4839
4840 #endif   /* __VALGRIND_H */