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