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