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
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2000-2012 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
92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __VALGRIND_MINOR__    8
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
120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef PLAT_mips32_linux
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__APPLE__) && defined(__i386__)
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_x86_darwin 1
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__APPLE__) && defined(__x86_64__)
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_amd64_darwin 1
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(__MINGW32__) || defined(__CYGWIN32__) \
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      || (defined(_WIN32) && defined(_M_IX86))
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_x86_win32 1
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__i386__)
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_x86_linux 1
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__x86_64__)
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_amd64_linux 1
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_ppc32_linux 1
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_ppc64_linux 1
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(__linux__) && defined(__arm__)
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PLAT_arm_linux 1
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define PLAT_s390x_linux 1
142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(__linux__) && defined(__mips__)
143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PLAT_mips32_linux 1
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If we're not compiling for our target platform, don't generate
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any inline asms.  */
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  if !defined(NVALGRIND)
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#    define NVALGRIND 1
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  endif
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* in here of use to end-users -- skip to the next section.           */
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * request. Accepts both pointers and integers as arguments.
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * client request that does not return a value.
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * client request and whose value equals the client request result.  Accepts
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * both pointers and integers as arguments.  Note that such calls are not
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * necessarily pure functions -- they may have side effects.
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(NVALGRIND)
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Define NVALGRIND to completely remove the Valgrind magic sequence
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   from the compiled code (analogous to NDEBUG's effects on
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert()) */
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      (_zzq_default)
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else  /* ! NVALGRIND */
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The following defines the magic code sequences which the JITter
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   spots and handles magically.  Don't look too closely at them as
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   they will rot your brain.
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The assembly code sequences for all architectures is in this one
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   file.  This is because this file must be stand-alone, and we don't
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   want to have multiple files.
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   value gets put in the return slot, so that everything works when
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this is executed not under Valgrind.  Args are passed in a memory
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   block, and so there's no intrinsic limit to the number that could
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be passed, but it's currently five.
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The macro args are:
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _zzq_rlval    result lvalue
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _zzq_default  default value (result returned when running on real CPU)
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _zzq_request  request code
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _zzq_arg1..5  request params
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The other two macros are used to support function wrapping, and are
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest's NRADDR pseudo-register and whatever other information is
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   needed to safely run the call original from the wrapper: on
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppc64-linux, the R2 value at the divert point is also needed.  This
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information is abstracted into a user-visible type, OrigFn.
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guest, but guarantees that the branch instruction will not be
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   complete inline asm, since it needs to be combined with more magic
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   inline asm stuff to be useful.
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-{linux,darwin} ---------------- */
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int nraddr; /* where's the code? */
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "roll $29, %%edi ; roll $19, %%edi\n\t"
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  __extension__                                                   \
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ({volatile unsigned int _zzq_args[6];                           \
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned int _zzq_result;                            \
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %EDX = client_request ( %EAX ) */         \
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgl %%ebx,%%ebx"                          \
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=d" (_zzq_result)                         \
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory"                             \
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_result;                                                  \
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  })
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned int __addr;                                 \
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %EAX = guest_NRADDR */                    \
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgl %%ecx,%%ecx"                          \
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=a" (__addr)                              \
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory"                             \
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_EAX                                 \
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* call-noredir *%EAX */                     \
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgl %%edx,%%edx\n\t"
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-Win32 ------------------------- */
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_win32) && !defined(__GNUC__)
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int nraddr; /* where's the code? */
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER)
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __asm rol edi, 3  __asm rol edi, 13          \
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __asm rol edi, 29 __asm rol edi, 19
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic __inline uintptr_t
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvalgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                uintptr_t _zzq_arg5)
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    volatile uintptr_t _zzq_args[6];
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    volatile unsigned int _zzq_result;
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[0] = (uintptr_t)(_zzq_request);
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            __SPECIAL_INSTRUCTION_PREAMBLE
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            /* %EDX = client_request ( %EAX ) */
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            __asm xchg ebx,ebx
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            __asm mov _zzq_result, edx
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    return _zzq_result;
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned int __addr;                                 \
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* %EAX = guest_NRADDR */                             \
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            __asm xchg ecx,ecx                                    \
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            __asm mov __addr, eax                                 \
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }                                                             \
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_EAX ERROR
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error Unsupported compiler.
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_win32 */
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ amd64-{linux,darwin} --------------- */
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned long long int nraddr; /* where's the code? */
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    __extension__                                                 \
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ({ volatile unsigned long long int _zzq_args[6];              \
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned long long int _zzq_result;                  \
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %RDX = client_request ( %RAX ) */         \
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgq %%rbx,%%rbx"                          \
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=d" (_zzq_result)                         \
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory"                             \
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_result;                                                  \
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    })
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned long long int __addr;                       \
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %RAX = guest_NRADDR */                    \
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgq %%rcx,%%rcx"                          \
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=a" (__addr)                              \
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory"                             \
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CALL_NOREDIR_RAX                                 \
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* call-noredir *%RAX */                     \
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "xchgq %%rdx,%%rdx\n\t"
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc32-linux ------------------------ */
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc32_linux)
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int nraddr; /* where's the code? */
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                                                  \
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    __extension__                                                 \
427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ({         unsigned int  _zzq_args[6];                          \
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             unsigned int  _zzq_result;                           \
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             unsigned int* _zzq_ptr;                              \
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_ptr = _zzq_args;                                         \
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mr 4,%2\n\t" /*ptr*/                        \
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %R3 = client_request ( %R4 ) */           \
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "or 1,1,1\n\t"                               \
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mr %0,3"     /*result*/                     \
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=b" (_zzq_result)                         \
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory", "r3", "r4");               \
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_result;                                                  \
447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    })
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    unsigned int __addr;                                          \
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %R3 = guest_NRADDR */                     \
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "or 2,2,2\n\t"                               \
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mr %0,3"                                    \
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=b" (__addr)                              \
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory", "r3"                       \
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* branch-and-link-to-noredir *%R11 */       \
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "or 3,3,3\n\t"
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc32_linux */
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc64-linux ------------------------ */
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc64_linux)
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned long long int nraddr; /* where's the code? */
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned long long int r2;  /* what tocptr do we need? */
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                                                  \
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  __extension__                                                   \
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ({         unsigned long long int  _zzq_args[6];                \
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             unsigned long long int  _zzq_result;                 \
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             unsigned long long int* _zzq_ptr;                    \
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_ptr = _zzq_args;                                         \
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "mr 4,%2\n\t" /*ptr*/                        \
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     __SPECIAL_INSTRUCTION_PREAMBLE               \
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %R3 = client_request ( %R4 ) */           \
503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "or 1,1,1\n\t"                               \
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "mr %0,3"     /*result*/                     \
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "=b" (_zzq_result)                         \
506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "cc", "memory", "r3", "r4");               \
508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_result;                                                  \
509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  })
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    unsigned long long int __addr;                                \
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %R3 = guest_NRADDR */                     \
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "or 2,2,2\n\t"                               \
517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "mr %0,3"                                    \
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "=b" (__addr)                              \
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "cc", "memory", "r3"                       \
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* %R3 = guest_NRADDR_GPR2 */                \
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "or 4,4,4\n\t"                               \
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "mr %0,3"                                    \
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "=b" (__addr)                              \
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     : "cc", "memory", "r3"                       \
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->r2 = __addr;                                       \
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* branch-and-link-to-noredir *%R11 */       \
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "or 3,3,3\n\t"
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc64_linux */
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- arm-linux ------------------------- */
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_arm_linux)
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int nraddr; /* where's the code? */
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OrigFn;
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        _zzq_default, _zzq_request,                               \
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                                                  \
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  __extension__                                                   \
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  ({volatile unsigned int  _zzq_args[6];                          \
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    volatile unsigned int  _zzq_result;                           \
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mov r4, %2\n\t" /*ptr*/                     \
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* R3 = client_request ( R4 ) */             \
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "orr r10, r10, r10\n\t"                      \
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mov %0, r3"     /*result*/                  \
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=r" (_zzq_result)                         \
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc","memory", "r3", "r4");                \
577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    _zzq_result;                                                  \
578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  })
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    unsigned int __addr;                                          \
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* R3 = guest_NRADDR */                      \
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "orr r11, r11, r11\n\t"                      \
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "mov %0, r3"                                 \
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "=r" (__addr)                              \
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     :                                            \
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : "cc", "memory", "r3"                       \
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    );                                            \
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    _zzq_orig->nraddr = __addr;                                   \
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     __SPECIAL_INSTRUCTION_PREAMBLE               \
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     /* branch-and-link-to-noredir *%R4 */        \
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "orr r12, r12, r12\n\t"
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_arm_linux */
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------ s390x-linux ------------------------ */
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(PLAT_s390x_linux)
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  struct {
607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     unsigned long long int nraddr; /* where's the code? */
6089bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root  }
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  OrigFn;
6109bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * code. This detection is implemented in platform specific toIR.c
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * (e.g. VEX/priv/guest_s390_decoder.c).
614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */
615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "lr 15,15\n\t"                              \
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "lr 1,1\n\t"                                \
618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "lr 2,2\n\t"                                \
619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     "lr 3,3\n\t"
620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       _zzq_default, _zzq_request,                               \
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  __extension__                                                  \
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ({volatile unsigned long long int _zzq_args[6];                 \
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   volatile unsigned long long int _zzq_result;                  \
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   __asm__ volatile(/* r2 = args */                              \
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    "lgr 2,%1\n\t"                               \
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    /* r3 = default */                           \
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    "lgr 3,%2\n\t"                               \
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    __SPECIAL_INSTRUCTION_PREAMBLE               \
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    __CLIENT_REQUEST_CODE                        \
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    /* results = r3 */                           \
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    "lgr %0, 3\n\t"                              \
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    : "=d" (_zzq_result)                         \
646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    : "cc", "2", "3", "memory"                   \
648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   );                                            \
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_result;                                                  \
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov })
651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   volatile unsigned long long int __addr;                       \
655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    __GET_NR_CONTEXT_CODE                        \
657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    "lgr %0, 3\n\t"                              \
658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    : "=a" (__addr)                              \
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    :                                            \
660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    : "cc", "3", "memory"                        \
661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   );                                            \
662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _zzq_orig->nraddr = __addr;                                   \
663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov }
664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_CALL_NOREDIR_R1                                 \
666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    __SPECIAL_INSTRUCTION_PREAMBLE               \
667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    __CALL_NO_REDIR_CODE
668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* PLAT_s390x_linux */
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------- mips32-linux ---------------- */
672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_mips32_linux)
674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef
676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   struct {
677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      unsigned int nraddr; /* where's the code? */
678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   OrigFn;
680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* .word  0x342
682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word  0x742
683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word  0xC2
684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * .word  0x4C2*/
685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __SPECIAL_INSTRUCTION_PREAMBLE          \
686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "srl $0, $0, 13\n\t"       \
687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "srl $0, $0, 29\n\t"       \
688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "srl $0, $0, 3\n\t"        \
689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "srl $0, $0, 19\n\t"
690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       _zzq_default, _zzq_request,                                \
693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  __extension__                                                   \
695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ({ volatile unsigned int _zzq_args[6];                          \
696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    volatile unsigned int _zzq_result;                            \
697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        __asm__ volatile("move $11, %1\n\t" /*default*/           \
704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "move $12, %2\n\t" /*ptr*/                   \
705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     __SPECIAL_INSTRUCTION_PREAMBLE               \
706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     /* T3 = client_request ( T4 ) */             \
707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "or $13, $13, $13\n\t"                       \
708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "move %0, $11\n\t"     /*result*/            \
709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     : "=r" (_zzq_result)                         \
710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     : "cc","memory", "t3", "t4");                \
712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_result;                                                  \
713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  })
714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    volatile unsigned int __addr;                                 \
718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     /* %t9 = guest_NRADDR */                     \
720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "or $14, $14, $14\n\t"                       \
721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "move %0, $11"     /*result*/                \
722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     : "=r" (__addr)                              \
723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     :                                            \
724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     : "cc", "memory" , "t3"                      \
725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    );                                            \
726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    _zzq_orig->nraddr = __addr;                                   \
727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  }
728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_CALL_NOREDIR_T9                                 \
730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     __SPECIAL_INSTRUCTION_PREAMBLE              \
731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     /* call-noredir *%t9 */                     \
732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     "or $15, $15, $15\n\t"
733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_mips32_linux */
734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Insert assembly code for other platforms here... */
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* NVALGRIND */
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ugly.  It's the least-worst tradeoff I can think of.               */
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------------------------------------------------ */
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This section defines magic (a.k.a appalling-hack) macros for doing
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   guaranteed-no-redirection macros, so as to get from function
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wrappers to the functions they are wrapping.  The whole point is to
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   construct standard call sequences, but to do the call itself with a
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   special no-redirect call pseudo-instruction that the JIT
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   understands and handles specially.  This section is long and
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   repetitious, and I can't see a way to make it shorter.
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The naming scheme is as follows:
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'W' stands for "word" and 'v' for "void".  Hence there are
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and for each, the possibility of returning a word-typed result, or
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   no result.
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use these to write the name of your wrapper.  NOTE: duplicates
764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the default behaviour equivalance class tag "0000" into the name.
766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   See pub_tool_redir.h for details -- normally you don't need to
767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   think about this, though. */
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use an extra level of macroisation so as to ensure the soname/fnname
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   args are fully macro-expanded before pasting them together. */
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Use this macro from within a wrapper function to collect the
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   context (address and possibly other info) of the original function.
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Once you have that you can then use it in one of the CALL_FN_
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   macros.  The type of the argument _lval is OrigFn. */
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Also provide end-user facilities for function replacement, rather
786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   than wrapping.  A replacement function differs from a wrapper in
787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   that it has no way to get hold of the original function being
788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   called, and hence no way to call onwards to it.  In a replacement
789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   function, VALGRIND_GET_ORIG_FN always returns zero. */
790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Derivatives of the main macros below, for calling functions
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   returning void. */
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_v(fnptr)                                        \
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_v(_junk,fnptr); } while (0)
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_W(fnptr, arg1)                                  \
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { volatile unsigned long _junk;                             \
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- x86-{linux,darwin} ---------------- */
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call.  No need to mention eax
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   as gcc can already see that, plus causes gcc to bomb. */
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function
841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   call and restore it afterwards as gcc may not keep the stack
842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   pointer aligned if it doesn't realise calls are being made
843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to other functions. */
844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK               \
846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "movl %%esp,%%edi\n\t"               \
847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "andl $0xfffffff0,%%esp\n\t"
848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK             \
849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "movl %%edi,%%esp\n\t"
850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   long) == 4. */
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig)                                   \
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[1];                          \
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1)                             \
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[2];                          \
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $12, %%esp\n\t"                                    \
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3];                          \
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $8, %%esp\n\t"                                     \
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[4];                          \
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $4, %%esp\n\t"                                     \
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[5];                          \
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[6];                          \
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $12, %%esp\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                                \
988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[7];                          \
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $8, %%esp\n\t"                                     \
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7)                            \
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[8];                          \
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $4, %%esp\n\t"                                     \
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8)                       \
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[9];                          \
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 32(%%eax)\n\t"                                    \
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8,arg9)                  \
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[10];                         \
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $12, %%esp\n\t"                                    \
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 36(%%eax)\n\t"                                    \
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 32(%%eax)\n\t"                                    \
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg7,arg8,arg9,arg10)           \
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[11];                         \
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $8, %%esp\n\t"                                     \
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 40(%%eax)\n\t"                                    \
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 36(%%eax)\n\t"                                    \
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 32(%%eax)\n\t"                                    \
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg6,arg7,arg8,arg9,arg10,      \
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg11)                          \
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[12];                         \
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)(arg11);                       \
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "subl $4, %%esp\n\t"                                     \
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 44(%%eax)\n\t"                                    \
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 40(%%eax)\n\t"                                    \
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 36(%%eax)\n\t"                                    \
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 32(%%eax)\n\t"                                    \
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg6,arg7,arg8,arg9,arg10,      \
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg11,arg12)                    \
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[13];                         \
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)(arg11);                       \
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[12] = (unsigned long)(arg12);                       \
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 48(%%eax)\n\t"                                    \
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 44(%%eax)\n\t"                                    \
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 40(%%eax)\n\t"                                    \
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 36(%%eax)\n\t"                                    \
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 32(%%eax)\n\t"                                    \
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 28(%%eax)\n\t"                                    \
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 24(%%eax)\n\t"                                    \
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 20(%%eax)\n\t"                                    \
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 16(%%eax)\n\t"                                    \
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 12(%%eax)\n\t"                                    \
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 8(%%eax)\n\t"                                     \
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "pushl 4(%%eax)\n\t"                                     \
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_CALL_NOREDIR_EAX                                \
1253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=a" (_res)                                  \
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "a" (&_argvec[0])                            \
1256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_x86_linux || PLAT_x86_darwin */
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ amd64-{linux,darwin} --------------- */
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "rdi", "r8", "r9", "r10", "r11"
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is all pretty complex.  It's so as to make stack unwinding
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   work reliably.  See bug 243270.  The basic problem is the sub and
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   add of 128 of %rsp in all of the following macros.  If gcc believes
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the CFA is in %rsp, then unwinding may fail, because what's at the
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CFA is not what gcc "expected" when it constructs the CFIs for the
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   places where the macros are instantiated.
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   But we can't just add a CFI annotation to increase the CFA offset
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   by 128, to match the sub of 128 from %rsp, because we don't know
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   whether gcc has chosen %rsp as the CFA at that point, or whether it
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   has chosen some other register (eg, %rbp).  In the latter case,
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   adding a CFI annotation to change the CFA offset is simply wrong.
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   So the solution is to get hold of the CFA using
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __builtin_dwarf_cfa(), put it in a known register, and add a
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CFI annotation to say what the register is.  We choose %rbp for
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this (perhaps perversely), because:
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (1) %rbp is already subject to unwinding.  If a new register was
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       chosen then the unwinder would have to unwind it in all stack
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       traces, which is expensive, and
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (2) %rbp is already subject to precise exception updates in the
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       JIT.  If a new register was chosen, we'd have to have precise
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       exceptions for it too, which reduces performance of the
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       generated code.
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   However .. one extra complication.  We can't just whack the result
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   list of trashed registers at the end of the inline assembly
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fragments; gcc won't allow %rbp to appear in that list.  Hence
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   instead we need to stash %rbp in %r15 for the duration of the asm,
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and say that %r15 is trashed instead.  gcc seems happy to go with
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that.
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Oh .. and this all needs to be conditionalised so that it is
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unchanged from before this commit, when compiled with older gccs
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that don't support __builtin_dwarf_cfa.  Furthermore, since
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this header file is freestanding, it has to be independent of
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   config.h, and so the following conditionalisation cannot depend on
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   configure time checks.
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Although it's not clear from
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this expression excludes Darwin.
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   .cfi directives in Darwin assembly appear to be completely
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   different and I haven't investigated how they work.
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For even more entertainment value, note we have to use the
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   completely undocumented __builtin_dwarf_cfa(), which appears to
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   really compute the CFA, whereas __builtin_frame_address(0) claims
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   to but actually doesn't.  See
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   https://bugs.kde.org/show_bug.cgi?id=243270#c47
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define __FRAME_POINTER                                         \
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ,"r"(__builtin_dwarf_cfa())
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define VALGRIND_CFI_PROLOGUE                                   \
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "movq %%rbp, %%r15\n\t"                                     \
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "movq %2, %%rbp\n\t"                                        \
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ".cfi_remember_state\n\t"                                   \
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ".cfi_def_cfa rbp, 0\n\t"
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define VALGRIND_CFI_EPILOGUE                                   \
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "movq %%r15, %%rbp\n\t"                                     \
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ".cfi_restore_state\n\t"
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define __FRAME_POINTER
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define VALGRIND_CFI_PROLOGUE
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define VALGRIND_CFI_EPILOGUE
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function
1345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   call and restore it afterwards as gcc may not keep the stack
1346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   pointer aligned if it doesn't realise calls are being made
1347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to other functions. */
1348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK               \
1350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "movq %%rsp,%%r14\n\t"               \
1351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "andq $0xfffffffffffffff0,%%rsp\n\t"
1352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK             \
1353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "movq %%r14,%%rsp\n\t"
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   long) == 8. */
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   macros.  In order not to trash the stack redzone, we need to drop
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   %rsp by 128 before the hidden call, and restore afterwards.  The
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nastyness is that it is only by luck that the stack still appears
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   to be unwindable during the hidden call - since then the behaviour
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of any routine using this macro does not match what the CFI data
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   says.  Sigh.
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Why is this important?  Imagine that a wrapper has a stack
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocated local, and passes to the hidden call, a pointer to it.
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Because gcc does not know about the hidden call, it may allocate
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that local in the redzone.  Unfortunately the hidden call may then
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   trash it before it comes to use it.  So we must step clear of the
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   redzone, for the duration of the hidden call, to make it safe.
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Probably the same problem afflicts the other redzone-style ABIs too
1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (ppc64-linux); but for those, the stack is
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   self describing (none of this CFI nonsense) so at least messing
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with the stack pointer doesn't give a danger of non-unwindable
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stack. */
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_v(lval, orig)                                        \
1380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[1];                               \
1383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_W(lval, orig, arg1)                                  \
1401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[2];                               \
1404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
1424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[3];                               \
1427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
1449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[4];                               \
1452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
1476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[5];                               \
1479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
1505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[6];                               \
1508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1526663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1527663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
1536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[7];                               \
1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7)                                 \
1570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[8];                               \
1573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $136,%%rsp\n\t"                                         \
1586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8)                            \
1606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[9];                               \
1609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1612663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1613663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1614663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                              \
1619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1620663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1621663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1622663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 64(%%rax)\n\t"                                         \
1624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
1643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8,arg9)                       \
1644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[10];                              \
1647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                              \
1657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                              \
1658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $136,%%rsp\n\t"                                         \
1662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 72(%%rax)\n\t"                                         \
1663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 64(%%rax)\n\t"                                         \
1664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg7,arg8,arg9,arg10)                \
1684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[11];                              \
1687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                              \
1697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                              \
1698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                            \
1699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 80(%%rax)\n\t"                                         \
1704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 72(%%rax)\n\t"                                         \
1705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 64(%%rax)\n\t"                                         \
1706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg7,arg8,arg9,arg10,arg11)          \
1726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[12];                              \
1729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1735663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                              \
1739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                              \
1740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                            \
1741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[11] = (unsigned long)(arg11);                            \
1742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $136,%%rsp\n\t"                                         \
1746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 88(%%rax)\n\t"                                         \
1747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 80(%%rax)\n\t"                                         \
1748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 72(%%rax)\n\t"                                         \
1749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 64(%%rax)\n\t"                                         \
1750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
1769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                arg7,arg8,arg9,arg10,arg11,arg12)      \
1770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                                \
1771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                           \
1772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[13];                              \
1773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                     \
1774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                        \
1775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                              \
1776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                              \
1777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                              \
1778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                              \
1779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                              \
1780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                              \
1781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                              \
1782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                              \
1783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                              \
1784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                            \
1785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[11] = (unsigned long)(arg11);                            \
1786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[12] = (unsigned long)(arg12);                            \
1787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                                \
1788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_PROLOGUE                                         \
1789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                          \
1790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subq $128,%%rsp\n\t"                                         \
1791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 96(%%rax)\n\t"                                         \
1792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 88(%%rax)\n\t"                                         \
1793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 80(%%rax)\n\t"                                         \
1794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 72(%%rax)\n\t"                                         \
1795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 64(%%rax)\n\t"                                         \
1796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "pushq 56(%%rax)\n\t"                                         \
1797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 48(%%rax), %%r9\n\t"                                    \
1798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 40(%%rax), %%r8\n\t"                                    \
1799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 32(%%rax), %%rcx\n\t"                                   \
1800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 24(%%rax), %%rdx\n\t"                                   \
1801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 16(%%rax), %%rsi\n\t"                                   \
1802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq 8(%%rax), %%rdi\n\t"                                    \
1803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
1804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_RAX                                     \
1805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                        \
1806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CFI_EPILOGUE                                         \
1807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=a" (_res)                                       \
1808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
1809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
1810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                               \
1811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                                  \
1812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
1813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
1815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------ ppc32-linux ------------------------ */
1817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_ppc32_linux)
1819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is useful for finding out about the on-stack stuff:
1821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   extern int f9  ( int,int,int,int,int,int,int,int,int );
1823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int g9 ( void ) {
1828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return f9(11,22,33,44,55,66,77,88,99);
1829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int g10 ( void ) {
1831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return f10(11,22,33,44,55,66,77,88,99,110);
1832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int g11 ( void ) {
1834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return f11(11,22,33,44,55,66,77,88,99,110,121);
1835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int g12 ( void ) {
1837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
1839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/
1840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These regs are trashed by the hidden call. */
1844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __CALLER_SAVED_REGS                                       \
1845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   "lr", "ctr", "xer",                                            \
1846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   "r11", "r12", "r13"
1849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function
1851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   call and restore it afterwards as gcc may not keep the stack
1852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   pointer aligned if it doesn't realise calls are being made
1853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to other functions. */
1854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK               \
1856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mr 28,1\n\t"                        \
1857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "rlwinm 1,1,0,0,27\n\t"
1858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK             \
1859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mr 1,28\n\t"
1860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These CALL_FN_ macros assume that on ppc32-linux,
1862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   sizeof(unsigned long) == 4. */
1863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig)                                   \
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[1];                          \
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
1877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
1878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
1879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1)                             \
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[2];                          \
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
1899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
1900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
1901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3];                          \
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
1913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
1919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
1923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
1924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
1925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[4];                          \
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
1937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
1938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
1944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
1945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
1949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
1950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
1951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[5];                          \
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
1963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
1964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
1965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[6];                          \
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
1991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
1992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
1993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
1994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
1996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
1997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
1998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
2000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
2001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
2007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
2008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
2009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[7];                          \
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
2021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
2022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
2023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
2024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
2025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)arg6;                           \
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr 11,%1\n\t"                                           \
2029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
2031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
2032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 8,24(11)\n\t"                                       \
2035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "mr %0,3"                                                \
2039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
2040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "r" (&_argvec[0])                            \
2041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7)                            \
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[8];                          \
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)arg1;                           \
2054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)arg2;                           \
2055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
2056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
2057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
2058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)arg6;                           \
2059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)arg7;                           \
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 4,8(11)\n\t"                                        \
2065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
2066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 8,24(11)\n\t"                                       \
2069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 9,28(11)\n\t"                                       \
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8)                       \
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[9];                          \
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)arg1;                           \
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)arg2;                           \
2090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)arg3;                           \
2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)arg6;                           \
2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)arg7;                           \
2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)arg8;                           \
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 4,8(11)\n\t"                                        \
2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 5,12(11)\n\t"                                       \
2102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 8,24(11)\n\t"                                       \
2105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 9,28(11)\n\t"                                       \
2106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8,arg9)                  \
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[10];                         \
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)arg1;                           \
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)arg2;                           \
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)arg3;                           \
2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)arg4;                           \
2129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
2130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)arg6;                           \
2131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)arg7;                           \
2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)arg8;                           \
2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)arg9;                           \
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addi 1,1,-16\n\t"                                       \
2138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* arg9 */                                               \
2139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,36(11)\n\t"                                       \
2140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "stw 3,8(1)\n\t"                                         \
2141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* args1-8 */                                            \
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 4,8(11)\n\t"                                        \
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 5,12(11)\n\t"                                       \
2145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 8,24(11)\n\t"                                       \
2148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 9,28(11)\n\t"                                       \
2149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg7,arg8,arg9,arg10)           \
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[11];                         \
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)arg1;                           \
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)arg2;                           \
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)arg3;                           \
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)arg4;                           \
2172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)arg5;                           \
2173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)arg6;                           \
2174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)arg7;                           \
2175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)arg8;                           \
2176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)arg9;                           \
2177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)arg10;                         \
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addi 1,1,-16\n\t"                                       \
2182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* arg10 */                                              \
2183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,40(11)\n\t"                                       \
2184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "stw 3,12(1)\n\t"                                        \
2185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* arg9 */                                               \
2186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 3,36(11)\n\t"                                       \
2187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "stw 3,8(1)\n\t"                                         \
2188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* args1-8 */                                            \
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 4,8(11)\n\t"                                        \
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 5,12(11)\n\t"                                       \
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 7,20(11)\n\t"                                       \
2194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 8,24(11)\n\t"                                       \
2195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 9,28(11)\n\t"                                       \
2196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg7,arg8,arg9,arg10,arg11)     \
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[12];                         \
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)arg1;                           \
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)arg2;                           \
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)arg3;                           \
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)arg4;                           \
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)arg5;                           \
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)arg6;                           \
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)arg7;                           \
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)arg8;                           \
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)arg9;                           \
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)arg10;                         \
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)arg11;                         \
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-32\n\t"                                       \
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg11 */                                              \
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,44(11)\n\t"                                       \
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,16(1)\n\t"                                        \
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg10 */                                              \
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,40(11)\n\t"                                       \
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,12(1)\n\t"                                        \
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,36(11)\n\t"                                       \
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,8(1)\n\t"                                         \
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 4,8(11)\n\t"                                        \
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 5,12(11)\n\t"                                       \
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 7,20(11)\n\t"                                       \
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 8,24(11)\n\t"                                       \
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 9,28(11)\n\t"                                       \
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                arg7,arg8,arg9,arg10,arg11,arg12) \
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[13];                         \
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)arg1;                           \
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)arg2;                           \
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)arg3;                           \
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)arg4;                           \
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)arg5;                           \
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)arg6;                           \
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)arg7;                           \
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)arg8;                           \
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)arg9;                           \
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)arg10;                         \
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)arg11;                         \
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[12] = (unsigned long)arg12;                         \
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-32\n\t"                                       \
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg12 */                                              \
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,48(11)\n\t"                                       \
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,20(1)\n\t"                                        \
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg11 */                                              \
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,44(11)\n\t"                                       \
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,16(1)\n\t"                                        \
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg10 */                                              \
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,40(11)\n\t"                                       \
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,12(1)\n\t"                                        \
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,36(11)\n\t"                                       \
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "stw 3,8(1)\n\t"                                         \
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 4,8(11)\n\t"                                        \
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 5,12(11)\n\t"                                       \
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 7,20(11)\n\t"                                       \
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 8,24(11)\n\t"                                       \
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 9,28(11)\n\t"                                       \
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3"                                                \
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[0])                            \
2309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc32_linux */
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------ ppc64-linux ------------------------ */
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_ppc64_linux)
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS                                       \
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "lr", "ctr", "xer",                                            \
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "r11", "r12", "r13"
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function
2330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   call and restore it afterwards as gcc may not keep the stack
2331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   pointer aligned if it doesn't realise calls are being made
2332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to other functions. */
2333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK               \
2335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mr 28,1\n\t"                        \
2336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "rldicr 1,1,0,59\n\t"
2337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK             \
2338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mr 1,28\n\t"
2339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   long) == 8. */
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig)                                   \
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+0];                        \
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)_orig.r2;                       \
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)_orig.nraddr;                   \
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1)                             \
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+1];                        \
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+2];                        \
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+3];                        \
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+4];                        \
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+5];                        \
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+6];                        \
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7)                            \
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+7];                        \
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8)                       \
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+8];                        \
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+8] = (unsigned long)arg8;                         \
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8,arg9)                  \
2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+9];                        \
2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+8] = (unsigned long)arg8;                         \
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+9] = (unsigned long)arg9;                         \
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,72(11)\n\t"                                       \
2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,112(1)\n\t"                                       \
2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg7,arg8,arg9,arg10)           \
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+10];                       \
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+8] = (unsigned long)arg8;                         \
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+9] = (unsigned long)arg9;                         \
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+10] = (unsigned long)arg10;                       \
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg10 */                                              \
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,80(11)\n\t"                                       \
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,120(1)\n\t"                                       \
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,72(11)\n\t"                                       \
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,112(1)\n\t"                                       \
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg7,arg8,arg9,arg10,arg11)     \
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+11];                       \
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+8] = (unsigned long)arg8;                         \
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+9] = (unsigned long)arg9;                         \
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+10] = (unsigned long)arg10;                       \
2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+11] = (unsigned long)arg11;                       \
2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg11 */                                              \
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,88(11)\n\t"                                       \
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,128(1)\n\t"                                       \
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg10 */                                              \
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,80(11)\n\t"                                       \
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,120(1)\n\t"                                       \
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,72(11)\n\t"                                       \
2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,112(1)\n\t"                                       \
2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                arg7,arg8,arg9,arg10,arg11,arg12) \
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3+12];                       \
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* _argvec[0] holds current r2 across the call */           \
2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1]   = (unsigned long)_orig.r2;                     \
2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+1] = (unsigned long)arg1;                         \
2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+2] = (unsigned long)arg2;                         \
2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+3] = (unsigned long)arg3;                         \
2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+4] = (unsigned long)arg4;                         \
2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+5] = (unsigned long)arg5;                         \
2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+6] = (unsigned long)arg6;                         \
2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+7] = (unsigned long)arg7;                         \
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+8] = (unsigned long)arg8;                         \
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+9] = (unsigned long)arg9;                         \
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+10] = (unsigned long)arg10;                       \
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+11] = (unsigned long)arg11;                       \
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2+12] = (unsigned long)arg12;                       \
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg12 */                                              \
2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,96(11)\n\t"                                       \
2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,136(1)\n\t"                                       \
2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg11 */                                              \
2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,88(11)\n\t"                                       \
2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,128(1)\n\t"                                       \
2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg10 */                                              \
2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,80(11)\n\t"                                       \
2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,120(1)\n\t"                                       \
2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* arg9 */                                               \
2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  3,72(11)\n\t"                                       \
2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "std 3,112(1)\n\t"                                       \
2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* args1-8 */                                            \
2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr 11,%1\n\t"                                           \
2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mr %0,3\n\t"                                            \
2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "r" (&_argvec[2])                            \
2866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_ppc64_linux */
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------------- arm-linux ------------------------- */
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(PLAT_arm_linux)
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These regs are trashed by the hidden call. */
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Macros to save and align the stack before making a function
2881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   call and restore it afterwards as gcc may not keep the stack
2882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   pointer aligned if it doesn't realise calls are being made
2883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to other functions. */
2884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This is a bit tricky.  We store the original stack pointer in r10
2886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   as it is callee-saves.  gcc doesn't allow the use of r11 for some
2887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   reason.  Also, we can't directly "bic" the stack pointer in thumb
2888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   mode since r13 isn't an allowed register number in that context.
2889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   So use r4 as a temporary, since that is about to get trashed
2890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   anyway, just after each use of this macro.  Side effect is we need
2891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to be very careful about any future changes, since
2892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
2893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_ALIGN_STACK               \
2894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mov r10, sp\n\t"                    \
2895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mov r4,  sp\n\t"                    \
2896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "bic r4,  r4, #7\n\t"                \
2897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mov sp,  r4\n\t"
2898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define VALGRIND_RESTORE_STACK             \
2899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      "mov sp,  r10\n\t"
2900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   long) == 4. */
2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_v(lval, orig)                                   \
2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[1];                          \
2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0\n"                                           \
2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
2918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_W(lval, orig, arg1)                             \
2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[2];                          \
2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0\n"                                           \
2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
2939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[3];                          \
2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0\n"                                           \
2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
2962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[4];                          \
2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
2977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
2983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0\n"                                           \
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
2987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[5];                          \
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[6];                          \
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sub sp, sp, #4 \n\t"                                    \
3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0} \n\t"                                         \
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[7];                          \
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1} \n\t"                                     \
3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7)                            \
3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[8];                          \
3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sub sp, sp, #4 \n\t"                                    \
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2} \n\t"                                 \
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8)                       \
3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[9];                          \
3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #32] \n\t"                                 \
3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2, r3} \n\t"                             \
3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 arg7,arg8,arg9)                  \
3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[10];                         \
3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sub sp, sp, #4 \n\t"                                    \
3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #32] \n\t"                                 \
3178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1, #36] \n\t"                                 \
3179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2, r3, r4} \n\t"                         \
3180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg7,arg8,arg9,arg10)           \
3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[11];                         \
3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #40] \n\t"                                 \
3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0} \n\t"                                         \
3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #32] \n\t"                                 \
3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1, #36] \n\t"                                 \
3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2, r3, r4} \n\t"                         \
3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg6,arg7,arg8,arg9,arg10,      \
3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg11)                          \
3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[12];                         \
3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)(arg11);                       \
3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sub sp, sp, #4 \n\t"                                    \
3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #40] \n\t"                                 \
3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #44] \n\t"                                 \
3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1} \n\t"                                     \
3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #32] \n\t"                                 \
3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1, #36] \n\t"                                 \
3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2, r3, r4} \n\t"                         \
3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg6,arg7,arg8,arg9,arg10,      \
3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  arg11,arg12)                    \
3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile OrigFn        _orig = (orig);                      \
3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _argvec[13];                         \
3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      volatile unsigned long _res;                                \
3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[1] = (unsigned long)(arg1);                         \
3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[2] = (unsigned long)(arg2);                         \
3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[3] = (unsigned long)(arg3);                         \
3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[4] = (unsigned long)(arg4);                         \
3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[5] = (unsigned long)(arg5);                         \
3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[6] = (unsigned long)(arg6);                         \
3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[7] = (unsigned long)(arg7);                         \
3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[8] = (unsigned long)(arg8);                         \
3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[9] = (unsigned long)(arg9);                         \
3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[10] = (unsigned long)(arg10);                       \
3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[11] = (unsigned long)(arg11);                       \
3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _argvec[12] = (unsigned long)(arg12);                       \
3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __asm__ volatile(                                           \
3304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_ALIGN_STACK                                     \
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #40] \n\t"                                 \
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #44] \n\t"                                 \
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #48] \n\t"                                 \
3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2} \n\t"                                 \
3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #20] \n\t"                                 \
3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #24] \n\t"                                 \
3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #28] \n\t"                                 \
3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #32] \n\t"                                 \
3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1, #36] \n\t"                                 \
3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "push {r0, r1, r2, r3, r4} \n\t"                         \
3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r0, [%1, #4] \n\t"                                  \
3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r1, [%1, #8] \n\t"                                  \
3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r2, [%1, #12] \n\t"                                 \
3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r3, [%1, #16] \n\t"                                 \
3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
3321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_RESTORE_STACK                                   \
3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "mov %0, r0"                                             \
3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*out*/   "=r" (_res)                                  \
3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         : /*in*/    "0" (&_argvec[0])                            \
3325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lval = (__typeof__(lval)) _res;                             \
3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* PLAT_arm_linux */
3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------- s390x-linux ------------------------- */
3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(PLAT_s390x_linux)
3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Similar workaround as amd64 (see above), but we use r11 as frame
3337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   pointer and save the old r11 in r7. r11 might be used for
3338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   argvec, therefore we copy argvec in r1 since r1 is clobbered
3339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   after the call anyway.  */
3340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define __FRAME_POINTER                                         \
3342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ,"d"(__builtin_dwarf_cfa())
3343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VALGRIND_CFI_PROLOGUE                                   \
3344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ".cfi_remember_state\n\t"                                   \
3345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
3346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      "lgr 7,11\n\t"                                              \
3347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      "lgr 11,%2\n\t"                                             \
3348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ".cfi_def_cfa r11, 0\n\t"
3349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VALGRIND_CFI_EPILOGUE                                   \
3350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      "lgr 11, 7\n\t"                                             \
3351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ".cfi_restore_state\n\t"
3352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
3353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define __FRAME_POINTER
3354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VALGRIND_CFI_PROLOGUE                                   \
3355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      "lgr 1,%1\n\t"
3356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define VALGRIND_CFI_EPILOGUE
3357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Nb: On s390 the stack pointer is properly aligned *at all times*
3360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   according to the s390 GCC maintainer. (The ABI specification is not
3361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
3362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VALGRIND_RESTORE_STACK are not defined here. */
3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* These regs are trashed by the hidden call. Note that we overwrite
3365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   function a proper return address. All others are ABI defined call
3367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   clobbers. */
3368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           "f0","f1","f2","f3","f4","f5","f6","f7"
3370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Nb: Although r11 is modified in the asm snippets below (inside
3372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
3373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   two reasons:
3374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
3375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       modified
3376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   (2) GCC will complain that r11 cannot appear inside a clobber section,
3377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       when compiled with -O -fno-omit-frame-pointer
3378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */
3379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_v(lval, orig)                                  \
3381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long  _argvec[1];                        \
3384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
3390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
3396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* The call abi has the arguments in r2-r6 and stack */
3402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_W(lval, orig, arg1)                            \
3403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[2];                         \
3406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
3426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[3];                         \
3429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
3451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[4];                         \
3454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
3478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[5];                         \
3481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
3507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[6];                         \
3510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-160\n\t"                                      \
3520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,160\n\t"                                       \
3529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6)                                       \
3539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[7];                         \
3542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-168\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         "lg 1, 0(1)\n\t"                                        \
3560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,168\n\t"                                       \
3563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7)                                 \
3573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[8];                         \
3576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-176\n\t"                                      \
3588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,176\n\t"                                       \
3599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7 ,arg8)                           \
3609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[9];                         \
3612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[8] = (unsigned long)arg8;                          \
3622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-184\n\t"                                      \
3625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 176(8,15), 64(1)\n\t"                              \
3633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,184\n\t"                                       \
3637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7 ,arg8, arg9)                     \
3647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[10];                        \
3650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[8] = (unsigned long)arg8;                          \
3660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[9] = (unsigned long)arg9;                          \
3661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-192\n\t"                                      \
3664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 176(8,15), 64(1)\n\t"                              \
3672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 184(8,15), 72(1)\n\t"                              \
3673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,192\n\t"                                       \
3677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7 ,arg8, arg9, arg10)              \
3687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[11];                        \
3690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[8] = (unsigned long)arg8;                          \
3700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[9] = (unsigned long)arg9;                          \
3701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[10] = (unsigned long)arg10;                        \
3702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-200\n\t"                                      \
3705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 176(8,15), 64(1)\n\t"                              \
3713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 184(8,15), 72(1)\n\t"                              \
3714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 192(8,15), 80(1)\n\t"                              \
3715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,200\n\t"                                       \
3719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
3729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[12];                        \
3732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[8] = (unsigned long)arg8;                          \
3742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[9] = (unsigned long)arg9;                          \
3743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[10] = (unsigned long)arg10;                        \
3744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[11] = (unsigned long)arg11;                        \
3745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-208\n\t"                                      \
3748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 176(8,15), 64(1)\n\t"                              \
3756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 184(8,15), 72(1)\n\t"                              \
3757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 192(8,15), 80(1)\n\t"                              \
3758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 200(8,15), 88(1)\n\t"                              \
3759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,208\n\t"                                       \
3763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do {                                                          \
3774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile OrigFn        _orig = (orig);                     \
3775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _argvec[13];                        \
3776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      volatile unsigned long _res;                               \
3777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[1] = (unsigned long)arg1;                          \
3779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[2] = (unsigned long)arg2;                          \
3780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[3] = (unsigned long)arg3;                          \
3781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[4] = (unsigned long)arg4;                          \
3782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[5] = (unsigned long)arg5;                          \
3783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[6] = (unsigned long)arg6;                          \
3784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[7] = (unsigned long)arg7;                          \
3785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[8] = (unsigned long)arg8;                          \
3786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[9] = (unsigned long)arg9;                          \
3787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[10] = (unsigned long)arg10;                        \
3788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[11] = (unsigned long)arg11;                        \
3789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      _argvec[12] = (unsigned long)arg12;                        \
3790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      __asm__ volatile(                                          \
3791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_PROLOGUE                                   \
3792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,-216\n\t"                                      \
3793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 2, 8(1)\n\t"                                        \
3794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 3,16(1)\n\t"                                        \
3795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 4,24(1)\n\t"                                        \
3796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 5,32(1)\n\t"                                        \
3797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 6,40(1)\n\t"                                        \
3798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 160(8,15), 48(1)\n\t"                              \
3799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 168(8,15), 56(1)\n\t"                              \
3800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 176(8,15), 64(1)\n\t"                              \
3801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 184(8,15), 72(1)\n\t"                              \
3802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 192(8,15), 80(1)\n\t"                              \
3803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 200(8,15), 88(1)\n\t"                              \
3804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "mvc 208(8,15), 96(1)\n\t"                              \
3805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lg 1, 0(1)\n\t"                                        \
3806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CALL_NOREDIR_R1                                \
3807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "lgr %0, 2\n\t"                                         \
3808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "aghi 15,216\n\t"                                       \
3809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VALGRIND_CFI_EPILOGUE                                   \
3810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*out*/   "=d" (_res)                                 \
3811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );                                                         \
3814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      lval = (__typeof__(lval)) _res;                            \
3815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
3816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* PLAT_s390x_linux */
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* ------------------------- mips-linux ------------------------- */
3821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(PLAT_mips32_linux)
3823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These regs are trashed by the hidden call. */
3825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
3826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
3827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng"$25", "$31"
3828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
3830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   long) == 4. */
3831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_v(lval, orig)                                   \
3833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[1];                          \
3836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        "subu $29, $29, 16 \n\t"                                 \
3843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
3845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 16\n\t"                                  \
3846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
3847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
3848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 8 \n\t"                                  \
3849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
3850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
3851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
3852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
3854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
3855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
3856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_W(lval, orig, arg1)                             \
3858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng     volatile unsigned long _argvec[2];                           \
3861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
3864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 16 \n\t"                                 \
3869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"   /* arg1*/                         \
3870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
3872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 16 \n\t"                                 \
3873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
3874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
3875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 8 \n\t"                                  \
3876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
3877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
3878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        : /*in*/    "0" (&_argvec[0])                             \
3879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
3880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
3881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
3882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
3883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[3];                          \
3888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
3891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
3892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 16 \n\t"                                 \
3897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
3898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
3899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
3901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 16 \n\t"                                 \
3902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
3903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
3904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 8 \n\t"                                  \
3905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
3906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
3907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
3908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
3910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
3911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
3912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[4];                          \
3917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
3920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
3921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
3922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 16 \n\t"                                 \
3927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
3928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
3929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
3930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
3932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 16 \n\t"                                 \
3933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
3934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
3935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 8 \n\t"                                  \
3936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
3937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
3938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
3939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
3941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
3942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
3943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[5];                          \
3948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
3951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
3952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
3953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
3954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 16 \n\t"                                 \
3959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
3960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
3962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
3963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
3964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
3965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 16 \n\t"                                 \
3966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
3967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
3968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 8 \n\t"                                  \
3969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
3970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
3971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
3972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
3974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
3975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
3976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
3979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
3980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[6];                          \
3981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
3982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
3983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
3984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
3985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
3986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
3987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
3988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
3989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
3990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
3991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
3992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
3993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 24\n\t"                                  \
3994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
3995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
3996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
3997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
3998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
3999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $29, $29, 24 \n\t"                                 \
4002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
4013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[7];                          \
4016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 32\n\t"                                  \
4030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "nop\n\t"                                                \
4033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 32 \n\t"                                 \
4041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7)                            \
4054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[8];                          \
4057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 32\n\t"                                  \
4072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 32 \n\t"                                 \
4084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8)                       \
4097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[9];                          \
4100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                         \
4110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 40\n\t"                                  \
4116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 32(%1) \n\t"                                    \
4122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 28($sp) \n\t"                                   \
4123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 40 \n\t"                                 \
4130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
4142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 arg7,arg8,arg9)                  \
4143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[10];                         \
4146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                         \
4156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                         \
4157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 40\n\t"                                  \
4163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 32(%1) \n\t"                                    \
4169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 28($sp) \n\t"                                   \
4170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 36(%1) \n\t"                                    \
4171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 32($sp) \n\t"                                   \
4172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 40 \n\t"                                 \
4179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
4191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg7,arg8,arg9,arg10)           \
4192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[11];                         \
4195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                         \
4205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                         \
4206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                       \
4207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 48\n\t"                                  \
4213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 32(%1) \n\t"                                    \
4219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 28($sp) \n\t"                                   \
4220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 36(%1) \n\t"                                    \
4221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 32($sp) \n\t"                                   \
4222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 40(%1) \n\t"                                    \
4223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 36($sp) \n\t"                                   \
4224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 48 \n\t"                                 \
4231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
4243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg6,arg7,arg8,arg9,arg10,      \
4244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg11)                          \
4245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[12];                         \
4248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                         \
4258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                         \
4259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                       \
4260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[11] = (unsigned long)(arg11);                       \
4261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 48\n\t"                                  \
4267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 32(%1) \n\t"                                    \
4273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 28($sp) \n\t"                                   \
4274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 36(%1) \n\t"                                    \
4275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 32($sp) \n\t"                                   \
4276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 40(%1) \n\t"                                    \
4277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 36($sp) \n\t"                                   \
4278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 44(%1) \n\t"                                    \
4279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 40($sp) \n\t"                                   \
4280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 48 \n\t"                                 \
4287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
4299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg6,arg7,arg8,arg9,arg10,      \
4300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  arg11,arg12)                    \
4301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do {                                                           \
4302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile OrigFn        _orig = (orig);                      \
4303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _argvec[13];                         \
4304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      volatile unsigned long _res;                                \
4305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[0] = (unsigned long)_orig.nraddr;                   \
4306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[1] = (unsigned long)(arg1);                         \
4307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[2] = (unsigned long)(arg2);                         \
4308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[3] = (unsigned long)(arg3);                         \
4309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[4] = (unsigned long)(arg4);                         \
4310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[5] = (unsigned long)(arg5);                         \
4311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[6] = (unsigned long)(arg6);                         \
4312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[7] = (unsigned long)(arg7);                         \
4313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[8] = (unsigned long)(arg8);                         \
4314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[9] = (unsigned long)(arg9);                         \
4315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[10] = (unsigned long)(arg10);                       \
4316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[11] = (unsigned long)(arg11);                       \
4317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _argvec[12] = (unsigned long)(arg12);                       \
4318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ volatile(                                           \
4319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $29, $29, 8 \n\t"                                  \
4320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $gp, 0($sp) \n\t"                                    \
4321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $ra, 4($sp) \n\t"                                    \
4322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 20(%1) \n\t"                                    \
4323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "subu $sp, $sp, 56\n\t"                                  \
4324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 16($sp) \n\t"                                   \
4325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 24(%1) \n\t"                                    \
4326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 20($sp) \n\t"                                   \
4327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 28(%1) \n\t"                                    \
4328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 24($sp) \n\t"                                   \
4329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 32(%1) \n\t"                                    \
4330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 28($sp) \n\t"                                   \
4331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 36(%1) \n\t"                                    \
4332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 32($sp) \n\t"                                   \
4333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 40(%1) \n\t"                                    \
4334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 36($sp) \n\t"                                   \
4335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 44(%1) \n\t"                                    \
4336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 40($sp) \n\t"                                   \
4337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 48(%1) \n\t"                                    \
4338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "sw $a0, 44($sp) \n\t"                                   \
4339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a0, 4(%1) \n\t"                                     \
4340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a1, 8(%1) \n\t"                                     \
4341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a2, 12(%1) \n\t"                                    \
4342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $a3, 16(%1) \n\t"                                    \
4343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
4344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         VALGRIND_CALL_NOREDIR_T9                                 \
4345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 56 \n\t"                                 \
4346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $gp, 0($sp) \n\t"                                    \
4347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "lw $ra, 4($sp) \n\t"                                    \
4348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "addu $sp, $sp, 8 \n\t"                                  \
4349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "move %0, $v0\n"                                         \
4350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*out*/   "=r" (_res)                                  \
4351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*in*/    "0" (&_argvec[0])                            \
4352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
4354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      lval = (__typeof__(lval)) _res;                             \
4355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
4356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* PLAT_mips32_linux */
4358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------------------------ */
4361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
4362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*                                                                    */
4363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------------------------ */
4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Some request codes.  There are many more of these, but most are not
4366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   exposed to end-user view.  These are the public ones, all of the
4367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   form 0x1000 + small_number.
4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
4370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ones start at 0x2000.
4371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
4372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* These macros are used by tools -- they must be public, but don't
4374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   embed them into other programs. */
4375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_USERREQ_TOOL_BASE(a,b) \
4376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
4377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_IS_TOOL_USERREQ(a, b, v) \
4378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This enum comprises an ABI exported by Valgrind to programs
4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* These allow any function to be called from the simulated
4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             CPU but run on the real CPU.  Nb: the first arg passed to
4390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             the function is always the ThreadId of the running
4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             thread!  So CLIENT_CALL0 actually requires a 1 arg
4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             function, etc. */
4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__CLIENT_CALL0 = 0x1101,
4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__CLIENT_CALL1 = 0x1102,
4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__CLIENT_CALL2 = 0x1103,
4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__CLIENT_CALL3 = 0x1104,
4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Can be useful in regression testing suites -- eg. can
4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             send Valgrind's output to /dev/null and still count
4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             errors. */
4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__COUNT_ERRORS = 0x1201,
4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          /* Allows a string (gdb monitor command) to be passed to the tool
4404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             Used for interaction with vgdb/gdb */
4405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
4406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* These are useful and can be interpreted by any tool that
4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             tracks malloc() et al, by using vg_replace_malloc.c. */
4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
4410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Memory pool support. */
4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Allow printfs to valgrind log. */
4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* The first two pass the va_list argument by value, which
4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             assumes it is the same size as or smaller than a UWord,
4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             which generally isn't the case.  Hence are deprecated.
4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             The second two pass the vargs by reference and so are
4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             immune to this problem. */
4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* both :: char* fmt, va_list vargs (DEPRECATED) */
4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__PRINTF           = 0x1401,
4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* both :: char* fmt, va_list* vargs */
4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Stack support. */
4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__STACK_REGISTER   = 0x1501,
4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__STACK_DEREGISTER = 0x1502,
4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__STACK_CHANGE     = 0x1503,
4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Wine support */
4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* Querying of debug info. */
4444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
4445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          /* Disable/enable error reporting level.  Takes a single
4447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             Word arg which is the delta to this thread's error
4448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             disablement indicator.  Hence 1 disables or further
4449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             disables errors, and -1 moves back towards enablement.
4450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             Other values are not allowed. */
4451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801
4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Vg_ClientRequest;
4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if !defined(__GNUC__)
4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define __extension__ /* */
4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the number of Valgrinds this code is running under.  That
4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is, 0 if running natively, 1 if running under Valgrind, 2 if
4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   running under Valgrind which is running under another Valgrind,
4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   etc. */
4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RUNNING_ON_VALGRIND                                           \
4464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    0, 0, 0, 0, 0)                    \
4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since it provides a way to make sure valgrind will retranslate the
4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   invalidated area.  Returns no value. */
4473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
4474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
4475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qzz_addr, _qzz_len, 0, 0, 0)
4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These requests are for getting Valgrind itself to print something.
4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Possibly with a backtrace.  This is a really ugly hack.  The return value
4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is the number of characters printed, excluding the "**<pid>** " part at the
4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   start and the backtrace (if present). */
4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Modern GCC will optimize the static routine out if unused,
4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and unused attribute will shut down warnings about it.  */
4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int VALGRIND_PRINTF(const char *format, ...)
4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __attribute__((format(__printf__, 1, 2), __unused__));
4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER)
4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__inline
4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVALGRIND_PRINTF(const char *format, ...)
4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(NVALGRIND)
4496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
4497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else /* NVALGRIND */
4498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(_MSC_VER)
4499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   uintptr_t _qzz_res;
4500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unsigned long _qzz_res;
4502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_list vargs;
4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_start(vargs, format);
4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER)
4506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              VG_USERREQ__PRINTF_VALIST_BY_REF,
4508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (uintptr_t)format,
4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (uintptr_t)&vargs,
4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              0, 0, 0);
4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              VG_USERREQ__PRINTF_VALIST_BY_REF,
4514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (unsigned long)format,
4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (unsigned long)&vargs,
4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              0, 0, 0);
4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_end(vargs);
4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return (int)_qzz_res;
4520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* NVALGRIND */
4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __attribute__((format(__printf__, 1, 2), __unused__));
4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
4528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER)
4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__inline
4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVALGRIND_PRINTF_BACKTRACE(const char *format, ...)
4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(NVALGRIND)
4534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return 0;
4535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else /* NVALGRIND */
4536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(_MSC_VER)
4537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   uintptr_t _qzz_res;
4538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
4539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unsigned long _qzz_res;
4540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
4541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_list vargs;
4542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_start(vargs, format);
4543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(_MSC_VER)
4544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (uintptr_t)format,
4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (uintptr_t)&vargs,
4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              0, 0, 0);
4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (unsigned long)format,
4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (unsigned long)&vargs,
4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              0, 0, 0);
4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_end(vargs);
4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return (int)_qzz_res;
45589bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root#endif /* NVALGRIND */
4559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
45609bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These requests allow control to move from the simulated CPU to the
4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   real CPU, calling an arbitary function.
4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Note that the current ThreadId is inserted as the first argument.
4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   So this call:
4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   requires f to have this signature:
4571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Word f(Word tid, Word arg1, Word arg2)
4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   where "Word" is a word-sized type.
4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Note that these client requests are not entirely reliable.  For example,
4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if you call a function with them that subsequently calls printf(),
4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   there's a high chance Valgrind will crash.  Generally, your prospects of
4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   these working are made higher if the called function does not refer to
4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any global variables, and does not refer to any libc or other functions
4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (printf et al).  Any kind of entanglement with libc or dynamic linking is
4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   likely to have a bad outcome, for tricky reasons which we've grappled
4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with a lot in the past.
4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
4586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
4587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    VG_USERREQ__CLIENT_CALL0,     \
4588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_fn,                      \
4589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    0, 0, 0, 0)
4590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
4592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    VG_USERREQ__CLIENT_CALL1,          \
4594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_fn,                           \
4595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_arg1, 0, 0, 0)
4596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
4598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    VG_USERREQ__CLIENT_CALL2,          \
4600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_fn,                           \
4601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_arg1, _qyy_arg2, 0, 0)
4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
4604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
4605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    VG_USERREQ__CLIENT_CALL3,           \
4606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_fn,                            \
4607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_arg1, _qyy_arg2,               \
4608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    _qyy_arg3, 0)
4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Counts the number of errors that have been recorded by a tool.  Nb:
4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the tool must record the errors with VG_(maybe_record_error)() or
4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(unique_error)() for them to be counted. */
4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_COUNT_ERRORS                                     \
4615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
4616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                               0 /* default return */,            \
4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               VG_USERREQ__COUNT_ERRORS,          \
4618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                               0, 0, 0, 0, 0)
4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   when heap blocks are allocated in order to give accurate results.  This
4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   happens automatically for the standard allocator functions such as
4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   delete[], etc.
4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   But if your program uses a custom allocator, this doesn't automatically
4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   happen, and Valgrind will not do as well.  For example, if you allocate
4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   superblocks with mmap() and then allocates chunks of the superblocks, all
4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Valgrind's observations will be at the mmap() level and it won't know that
4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the chunks should be considered separate entities.  In Memcheck's case,
4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that means you probably won't get heap block overrun detection (because
4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   there won't be redzones marked as unaddressable) and you definitely won't
4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   get any leak detection.
4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The following client requests allow a custom allocator to be annotated so
4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that it can be handled accurately by Valgrind.
4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   by a malloc()-like function.  For Memcheck (an illustrative case), this
4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   does two things:
4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - It records that the block has been allocated.  This means any addresses
4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     within the block mentioned in error messages will be
4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     identified as belonging to the block.  It also means that if the block
4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     isn't freed it will be detected by the leak checker.
4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - It marks the block as being addressable and undefined (if 'is_zeroed' is
4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     not set), or addressable and defined (if 'is_zeroed' is set).  This
4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     controls how accesses to the block by the program are handled.
4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'addr' is the start of the usable block (ie. after any
4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   can apply redzones -- these are blocks of padding at the start and end of
4654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   each block.  Adding redzones is recommended as it makes it much more likely
4655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
4656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   zeroed (or filled with another predictable value), as is the case for
4657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   calloc().
4658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
4660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   heap block -- that will be used by the client program -- is allocated.
4661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   It's best to put it at the outermost level of the allocator if possible;
4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for example, if you have a function my_alloc() which calls
4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   internal_alloc(), and the client request is put inside internal_alloc(),
4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stack traces relating to the heap block will contain entries for both
4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   my_alloc() and internal_alloc(), which is probably not what you want.
4666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   custom blocks from within a heap block, B, that has been allocated with
4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   -- the custom blocks will take precedence.
4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Memcheck, it does two things:
4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - It records that the block has been deallocated.  This assumes that the
4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     block was annotated as having been allocated via
4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   - It marks the block as being unaddressable.
4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   heap block is deallocated.
4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
4685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Memcheck, it does four things:
4686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   - It records that the size of a block has been changed.  This assumes that
4688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     the block was annotated as having been allocated via
4689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
4690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   - If the block shrunk, it marks the freed memory as being unaddressable.
4692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   - If the block grew, it marks the new area as undefined and defines a red
4694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     zone past the end of the new block.
4695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   - The V-bits of the overlap between the old and the new block are preserved.
4697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
4699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   and before deallocation of the old block.
4700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   In many cases, these three client requests will not be enough to get your
4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocator working well with Memcheck.  More specifically, if your allocator
4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
4704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   will be necessary to mark the memory as addressable just before the zeroing
4705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   occurs, otherwise you'll get a lot of invalid write errors.  For example,
4706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   you'll need to do this if your allocator recycles freed blocks, but it
4707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
4708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Alternatively, if your allocator reuses freed blocks for allocator-internal
4709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
4710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Really, what's happening is a blurring of the lines between the client
4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
4713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   memory should be considered unaddressable to the client program, but the
4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocator knows more than the rest of the client program and so may be able
4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   to safely access it.  Extra client requests are necessary for Valgrind to
4716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   understand the distinction between the allocator and the rest of the
4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   program.
4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Ignored if addr == 0.
4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
4721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
4722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
4723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    addr, sizeB, rzB, is_zeroed, 0)
47248f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov
47258f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
47268f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov   Ignored if addr == 0.
47278f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov*/
4728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
4729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
4730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    addr, oldSizeB, newSizeB, rzB, 0)
4731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
4733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Ignored if addr == 0.
4734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
4735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
4736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
4737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    addr, rzB, 0, 0, 0)
4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create a memory pool. */
4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
4741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
4742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, rzB, is_zeroed, 0, 0)
4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Destroy a memory pool. */
4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
4746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
4747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, 0, 0, 0, 0)
4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Associate a piece of memory with a memory pool. */
4750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
4751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
4752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, addr, size, 0, 0)
4753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Disassociate a piece of memory from a memory pool. */
4755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
4756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
4757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, addr, 0, 0, 0)
4758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Disassociate any pieces outside a particular range. */
4760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
4761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
4762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, addr, size, 0, 0)
4763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Resize and/or move a piece associated with a memory pool. */
4765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
4766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
4767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    poolA, poolB, 0, 0, 0)
4768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Resize and/or move a piece associated with a memory pool. */
4770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
4771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
4772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    pool, addrA, addrB, size, 0)
4773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return 1 if a mempool exists, else 0. */
4775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
4776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               VG_USERREQ__MEMPOOL_EXISTS,        \
4778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                               pool, 0, 0, 0, 0)
4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Mark a piece of memory as being a stack. Returns a stack id. */
4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_REGISTER(start, end)                       \
4782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               VG_USERREQ__STACK_REGISTER,        \
4784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                               start, end, 0, 0, 0)
4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Unmark the piece of memory associated with a stack id as being a
4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stack. */
4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_DEREGISTER(id)                             \
4789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
4790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    id, 0, 0, 0, 0)
4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Change the start and end address of the stack id. */
4793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_STACK_CHANGE(id, start, end)                     \
4794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
4795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    id, start, end, 0, 0)
4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Load PDB debug info for Wine PE image_map. */
4798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
4799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
4800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    fd, ptr, total_size, delta, 0)
4801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Map a code address to a source file name and line number.  buf64
4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   must point to a 64-byte buffer in the caller's address space.  The
4804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   result will be dumped in there and is guaranteed to be zero
4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   terminated.  If no info is found, the first byte is set to zero. */
4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
4807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
4809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                               addr, buf64, 0, 0, 0)
4810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Disable error reporting for this thread.  Behaves in a stack like
4812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   way, so you can safely call this multiple times provided that
4813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
4814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to re-enable reporting.  The first call of this macro disables
4815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   reporting.  Subsequent calls have no effect except to increase the
4816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
4817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   reporting.  Child threads do not inherit this setting from their
4818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   parents -- they are always created with reporting enabled. */
4819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_DISABLE_ERROR_REPORTING                                \
4820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    1, 0, 0, 0, 0)
4822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Re-enable error reporting, as per comments on
4824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VALGRIND_DISABLE_ERROR_REPORTING. */
4825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VALGRIND_ENABLE_ERROR_REPORTING                                 \
4826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
4827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                    -1, 0, 0, 0, 0)
4828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_x86_darwin
4830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_amd64_darwin
4831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_x86_win32
4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_x86_linux
4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_amd64_linux
4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc32_linux
4835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_ppc64_linux
4836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PLAT_arm_linux
4837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef PLAT_s390x_linux
4838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef PLAT_mips32_linux
4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif   /* __VALGRIND_H */
4841