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