valgrind.h revision 42f83fe6c64da13801d4eb54fa2aa6530679848a
1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj/* -*- c -*-
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
3e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
4e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Notice that the following BSD-style license applies to this one
57fd15d674f18757167305947732057099e175914njn   file (valgrind.h) only.  The rest of Valgrind is licensed under the
67fd15d674f18757167305947732057099e175914njn   terms of the GNU General Public License, version 2, unless
77fd15d674f18757167305947732057099e175914njn   otherwise indicated.  See the COPYING file in the source
87fd15d674f18757167305947732057099e175914njn   distribution for details.
9e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
11e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
12b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   This file is part of Valgrind, a dynamic binary instrumentation
13b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   framework.
14de4a1d01951937632098a6cda45859afa587a06fsewardj
15ec062e8d96a361af9905b5447027819dfbfee01asewardj   Copyright (C) 2000-2011 Julian Seward.  All rights reserved.
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Redistribution and use in source and binary forms, with or without
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   modification, are permitted provided that the following conditions
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   are met:
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   1. Redistributions of source code must retain the above copyright
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      notice, this list of conditions and the following disclaimer.
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   2. The origin of this software must not be misrepresented; you must
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      not claim that you wrote the original software.  If you use this
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      software in a product, an acknowledgment in the product
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      documentation would be appreciated but is not required.
28de4a1d01951937632098a6cda45859afa587a06fsewardj
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   3. Altered source versions must be plainly marked as such, and must
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      not be misrepresented as being the original software.
31de4a1d01951937632098a6cda45859afa587a06fsewardj
32e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   4. The name of the author may not be used to endorse or promote
33e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      products derived from this software without specific prior written
34e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      permission.
35de4a1d01951937632098a6cda45859afa587a06fsewardj
36e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47de4a1d01951937632098a6cda45859afa587a06fsewardj
48e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
49e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
50e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Notice that the above BSD-style license applies to this one file
51e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   (valgrind.h) only.  The entire rest of Valgrind is licensed under
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   the terms of the GNU General Public License, version 2.  See the
53e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   COPYING file in the source distribution for details.
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
56de4a1d01951937632098a6cda45859afa587a06fsewardj*/
57de4a1d01951937632098a6cda45859afa587a06fsewardj
58de4a1d01951937632098a6cda45859afa587a06fsewardj
5930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* This file is for inclusion into client (your!) code.
6030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   You can use these macros to manipulate and query Valgrind's
6230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   execution inside your own programs.
6330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   The resulting executables will still run without Valgrind, just a
6530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   little bit more slowly than they otherwise would, but otherwise
6630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   unchanged.  When not running on valgrind, each client request
670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   consumes very few (eg. 7) instructions, so the resulting performance
6830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   loss is negligible unless you plan to execute client requests
6930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   millions of times per second.  Nevertheless, if that is still a
7030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   problem, you can compile with the NVALGRIND symbol defined (gcc
7130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   -DNVALGRIND) so that client requests are not even compiled in.  */
7230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
73de4a1d01951937632098a6cda45859afa587a06fsewardj#ifndef __VALGRIND_H
74de4a1d01951937632098a6cda45859afa587a06fsewardj#define __VALGRIND_H
75de4a1d01951937632098a6cda45859afa587a06fsewardj
767104416748e90239b97560f5d727da107e3e08a9sewardj
777104416748e90239b97560f5d727da107e3e08a9sewardj/* ------------------------------------------------------------------ */
787104416748e90239b97560f5d727da107e3e08a9sewardj/* VERSION NUMBER OF VALGRIND                                         */
797104416748e90239b97560f5d727da107e3e08a9sewardj/* ------------------------------------------------------------------ */
807104416748e90239b97560f5d727da107e3e08a9sewardj
817104416748e90239b97560f5d727da107e3e08a9sewardj/* Specify Valgrind's version number, so that user code can
820fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj   conditionally compile based on our version number.  Note that these
830fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj   were introduced at version 3.6 and so do not exist in version 3.5
840fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj   or earlier.  The recommended way to use them to check for "version
850fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj   X.Y or later" is (eg)
860fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
870fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
880fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj    && (__VALGRIND_MAJOR__ > 3                                   \
890fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj        || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
900fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj*/
910fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj#define __VALGRIND_MAJOR__    3
927104416748e90239b97560f5d727da107e3e08a9sewardj#define __VALGRIND_MINOR__    6
937104416748e90239b97560f5d727da107e3e08a9sewardj
947104416748e90239b97560f5d727da107e3e08a9sewardj
9539de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#include <stdarg.h>
9639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
973dd0a912e48a4884ee51ab3afe41856c165185canjn/* Nb: this file might be included in a file compiled with -ansi.  So
983dd0a912e48a4884ee51ab3afe41856c165185canjn   we can't use C++ style "//" comments nor the "asm" keyword (instead
993dd0a912e48a4884ee51ab3afe41856c165185canjn   use "__asm__"). */
1003dd0a912e48a4884ee51ab3afe41856c165185canjn
101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Derive some tags indicating what the target platform is.  Note
1020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   that in this file we're using the compiler's CPP symbols for
1030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   identifying architectures, which are different to the ones we use
1040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   within the rest of Valgrind.  Note, __powerpc__ is active for both
1050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
10659570ffbe31930ab4d678754daaeec0715117a3dsewardj   latter (on Linux, that is).
10759570ffbe31930ab4d678754daaeec0715117a3dsewardj
10859570ffbe31930ab4d678754daaeec0715117a3dsewardj   Misc note: how to find out what's predefined in gcc by default:
10959570ffbe31930ab4d678754daaeec0715117a3dsewardj   gcc -Wp,-dM somefile.c
11059570ffbe31930ab4d678754daaeec0715117a3dsewardj*/
1117af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_x86_darwin
1127af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_amd64_darwin
1137f489813d200fb614a0856fca05e2f9ebf66dd48bart#undef PLAT_x86_win32
114f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
116f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
11859570ffbe31930ab4d678754daaeec0715117a3dsewardj#undef PLAT_arm_linux
119b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#undef PLAT_s390x_linux
120b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
121f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
1226e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if defined(__APPLE__) && defined(__i386__)
123f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_x86_darwin 1
124f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__x86_64__)
125f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_amd64_darwin 1
1266e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#elif defined(__MINGW32__) || defined(__CYGWIN32__) \
1276e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj      || (defined(_WIN32) && defined(_M_IX86))
1287f489813d200fb614a0856fca05e2f9ebf66dd48bart#  define PLAT_x86_win32 1
12959570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__i386__)
130f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_x86_linux 1
13159570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__x86_64__)
132f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_amd64_linux 1
13359570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
134f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc32_linux 1
13559570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
136f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc64_linux 1
13759570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__arm__)
13859570ffbe31930ab4d678754daaeec0715117a3dsewardj#  define PLAT_arm_linux 1
139b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
140b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define PLAT_s390x_linux 1
141f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else
142f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* If we're not compiling for our target platform, don't generate
1430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   any inline asms.  */
1440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  if !defined(NVALGRIND)
1450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#    define NVALGRIND 1
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  endif
147b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#endif
148b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
15030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
1510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
1520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* in here of use to end-users -- skip to the next section.           */
15330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
154de4a1d01951937632098a6cda45859afa587a06fsewardj
155575ce8ef8fa86a502dabe152293320676922dcfebart/*
156575ce8ef8fa86a502dabe152293320676922dcfebart * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
157575ce8ef8fa86a502dabe152293320676922dcfebart * request. Accepts both pointers and integers as arguments.
158575ce8ef8fa86a502dabe152293320676922dcfebart *
1594b3a74204894e943c43cb8e8aae39d813040702csewardj * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
1604b3a74204894e943c43cb8e8aae39d813040702csewardj * client request that does not return a value.
1614b3a74204894e943c43cb8e8aae39d813040702csewardj
162575ce8ef8fa86a502dabe152293320676922dcfebart * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
1634b3a74204894e943c43cb8e8aae39d813040702csewardj * client request and whose value equals the client request result.  Accepts
1644b3a74204894e943c43cb8e8aae39d813040702csewardj * both pointers and integers as arguments.  Note that such calls are not
1654b3a74204894e943c43cb8e8aae39d813040702csewardj * necessarily pure functions -- they may have side effects.
166575ce8ef8fa86a502dabe152293320676922dcfebart */
167575ce8ef8fa86a502dabe152293320676922dcfebart
168575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
169575ce8ef8fa86a502dabe152293320676922dcfebart                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
170575ce8ef8fa86a502dabe152293320676922dcfebart                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
17117dfe1addc98de357b9e24ddbe4ad7df4454873aflorian  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
172575ce8ef8fa86a502dabe152293320676922dcfebart                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
17317dfe1addc98de357b9e24ddbe4ad7df4454873aflorian                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
174575ce8ef8fa86a502dabe152293320676922dcfebart
1754b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
1764b3a74204894e943c43cb8e8aae39d813040702csewardj                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
1774b3a74204894e943c43cb8e8aae39d813040702csewardj  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
1784b3a74204894e943c43cb8e8aae39d813040702csewardj                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
1794b3a74204894e943c43cb8e8aae39d813040702csewardj                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
1804b3a74204894e943c43cb8e8aae39d813040702csewardj
1810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
18226aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
18326aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn/* Define NVALGRIND to completely remove the Valgrind magic sequence
1840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   from the compiled code (analogous to NDEBUG's effects on
1850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   assert()) */
186575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
187575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
1889af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
189575ce8ef8fa86a502dabe152293320676922dcfebart      (_zzq_default)
19026aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
1910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#else  /* ! NVALGRIND */
1920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* The following defines the magic code sequences which the JITter
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   spots and handles magically.  Don't look too closely at them as
1950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   they will rot your brain.
196de4a1d01951937632098a6cda45859afa587a06fsewardj
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The assembly code sequences for all architectures is in this one
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   file.  This is because this file must be stand-alone, and we don't
1990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   want to have multiple files.
2000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   value gets put in the return slot, so that everything works when
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   this is executed not under Valgrind.  Args are passed in a memory
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   block, and so there's no intrinsic limit to the number that could
2059af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj   be passed, but it's currently five.
206e90c6836fd430124799e52896c99ea27b1c88541nethercote
2075426544c9c3fc835ead99fae9e2054625110ef3enethercote   The macro args are:
2085426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_rlval    result lvalue
2095426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_default  default value (result returned when running on real CPU)
2105426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_request  request code
2119af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      _zzq_arg1..5  request params
2125426544c9c3fc835ead99fae9e2054625110ef3enethercote
2130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The other two macros are used to support function wrapping, and are
214d68ac3e974d25f88492774f6baa491999afde9f9sewardj   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
215d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest's NRADDR pseudo-register and whatever other information is
216d68ac3e974d25f88492774f6baa491999afde9f9sewardj   needed to safely run the call original from the wrapper: on
217d68ac3e974d25f88492774f6baa491999afde9f9sewardj   ppc64-linux, the R2 value at the divert point is also needed.  This
218d68ac3e974d25f88492774f6baa491999afde9f9sewardj   information is abstracted into a user-visible type, OrigFn.
219d68ac3e974d25f88492774f6baa491999afde9f9sewardj
220d68ac3e974d25f88492774f6baa491999afde9f9sewardj   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
221d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest, but guarantees that the branch instruction will not be
222d68ac3e974d25f88492774f6baa491999afde9f9sewardj   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
223d68ac3e974d25f88492774f6baa491999afde9f9sewardj   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
224d68ac3e974d25f88492774f6baa491999afde9f9sewardj   complete inline asm, since it needs to be combined with more magic
225d68ac3e974d25f88492774f6baa491999afde9f9sewardj   inline asm stuff to be useful.
226e90c6836fd430124799e52896c99ea27b1c88541nethercote*/
227de4a1d01951937632098a6cda45859afa587a06fsewardj
228f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
2290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
230520a03a4c59703908bae4cc437814abf0a24cdcdsewardj#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
231602278444fa6b4135a44d19ae833ed42a9898e48sewardj    ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
232c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
233c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
234c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
235c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
236c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
237c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
238c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
2390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
2411a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "roll $29, %%edi ; roll $19, %%edi\n\t"
2420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
243575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
244575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
2459af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
246575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
247575ce8ef8fa86a502dabe152293320676922dcfebart  ({volatile unsigned int _zzq_args[6];                           \
2480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned int _zzq_result;                            \
2490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
2500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
2530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
2549af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EDX = client_request ( %EAX ) */         \
2570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ebx,%%ebx"                          \
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
262575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
263575ce8ef8fa86a502dabe152293320676922dcfebart  })
2640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
265c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
266c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
267c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned int __addr;                                 \
2680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EAX = guest_NRADDR */                    \
2700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ecx,%%ecx"                          \
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
275c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
276ca0518df66f8c3375a860f1a55a51f18e2a16c44njn  }
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_EAX                                 \
2790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%EAX */                     \
2810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%edx,%%edx\n\t"
282602278444fa6b4135a44d19ae833ed42a9898e48sewardj#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
2837f489813d200fb614a0856fca05e2f9ebf66dd48bart
2847f489813d200fb614a0856fca05e2f9ebf66dd48bart/* ------------------------- x86-Win32 ------------------------- */
2857f489813d200fb614a0856fca05e2f9ebf66dd48bart
2867f489813d200fb614a0856fca05e2f9ebf66dd48bart#if defined(PLAT_x86_win32) && !defined(__GNUC__)
2877f489813d200fb614a0856fca05e2f9ebf66dd48bart
2887f489813d200fb614a0856fca05e2f9ebf66dd48barttypedef
2897f489813d200fb614a0856fca05e2f9ebf66dd48bart   struct {
2907f489813d200fb614a0856fca05e2f9ebf66dd48bart      unsigned int nraddr; /* where's the code? */
2917f489813d200fb614a0856fca05e2f9ebf66dd48bart   }
2927f489813d200fb614a0856fca05e2f9ebf66dd48bart   OrigFn;
2937f489813d200fb614a0856fca05e2f9ebf66dd48bart
2947f489813d200fb614a0856fca05e2f9ebf66dd48bart#if defined(_MSC_VER)
2957f489813d200fb614a0856fca05e2f9ebf66dd48bart
2967f489813d200fb614a0856fca05e2f9ebf66dd48bart#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2977f489813d200fb614a0856fca05e2f9ebf66dd48bart                     __asm rol edi, 3  __asm rol edi, 13          \
2987f489813d200fb614a0856fca05e2f9ebf66dd48bart                     __asm rol edi, 29 __asm rol edi, 19
2997f489813d200fb614a0856fca05e2f9ebf66dd48bart
300575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
301575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
3027f489813d200fb614a0856fca05e2f9ebf66dd48bart        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
303575ce8ef8fa86a502dabe152293320676922dcfebart    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
304575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
305575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
306575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
307575ce8ef8fa86a502dabe152293320676922dcfebart
308575ce8ef8fa86a502dabe152293320676922dcfebartstatic __inline uintptr_t
309575ce8ef8fa86a502dabe152293320676922dcfebartvalgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
310575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
311575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
312575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg5)
313575ce8ef8fa86a502dabe152293320676922dcfebart{
314575ce8ef8fa86a502dabe152293320676922dcfebart    volatile uintptr_t _zzq_args[6];
315575ce8ef8fa86a502dabe152293320676922dcfebart    volatile unsigned int _zzq_result;
316575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[0] = (uintptr_t)(_zzq_request);
317575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
318575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
319575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
320575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
321575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
322575ce8ef8fa86a502dabe152293320676922dcfebart    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
323575ce8ef8fa86a502dabe152293320676922dcfebart            __SPECIAL_INSTRUCTION_PREAMBLE
324575ce8ef8fa86a502dabe152293320676922dcfebart            /* %EDX = client_request ( %EAX ) */
325575ce8ef8fa86a502dabe152293320676922dcfebart            __asm xchg ebx,ebx
326575ce8ef8fa86a502dabe152293320676922dcfebart            __asm mov _zzq_result, edx
327575ce8ef8fa86a502dabe152293320676922dcfebart    }
328575ce8ef8fa86a502dabe152293320676922dcfebart    return _zzq_result;
329575ce8ef8fa86a502dabe152293320676922dcfebart}
3307f489813d200fb614a0856fca05e2f9ebf66dd48bart
3317f489813d200fb614a0856fca05e2f9ebf66dd48bart#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
3327f489813d200fb614a0856fca05e2f9ebf66dd48bart  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
3337f489813d200fb614a0856fca05e2f9ebf66dd48bart    volatile unsigned int __addr;                                 \
3347f489813d200fb614a0856fca05e2f9ebf66dd48bart    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
3357f489813d200fb614a0856fca05e2f9ebf66dd48bart            /* %EAX = guest_NRADDR */                             \
3367f489813d200fb614a0856fca05e2f9ebf66dd48bart            __asm xchg ecx,ecx                                    \
3377f489813d200fb614a0856fca05e2f9ebf66dd48bart            __asm mov __addr, eax                                 \
3387f489813d200fb614a0856fca05e2f9ebf66dd48bart    }                                                             \
3397f489813d200fb614a0856fca05e2f9ebf66dd48bart    _zzq_orig->nraddr = __addr;                                   \
3407f489813d200fb614a0856fca05e2f9ebf66dd48bart  }
3417f489813d200fb614a0856fca05e2f9ebf66dd48bart
3427f489813d200fb614a0856fca05e2f9ebf66dd48bart#define VALGRIND_CALL_NOREDIR_EAX ERROR
3437f489813d200fb614a0856fca05e2f9ebf66dd48bart
3447f489813d200fb614a0856fca05e2f9ebf66dd48bart#else
3457f489813d200fb614a0856fca05e2f9ebf66dd48bart#error Unsupported compiler.
3467f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
3477f489813d200fb614a0856fca05e2f9ebf66dd48bart
3487f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif /* PLAT_x86_win32 */
3490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
350f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
3510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
352f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
353c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
354c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
355c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
356c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned long long int nraddr; /* where's the code? */
357c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
358c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
359c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
3600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
3621a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
3630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
364575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
365575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
3669af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
367575ce8ef8fa86a502dabe152293320676922dcfebart    __extension__                                                 \
368575ce8ef8fa86a502dabe152293320676922dcfebart    ({ volatile unsigned long long int _zzq_args[6];              \
3690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned long long int _zzq_result;                  \
3700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
3710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
3720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
3730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
3740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
3759af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
3760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RDX = client_request ( %RAX ) */         \
3780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rbx,%%rbx"                          \
3790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
3800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
3810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
3820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
383575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
384575ce8ef8fa86a502dabe152293320676922dcfebart    })
3850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
386c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
387c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
388c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned long long int __addr;                       \
3890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RAX = guest_NRADDR */                    \
3910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rcx,%%rcx"                          \
3920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
3930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
3940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
3950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
396c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
3972c48c7b0a453d32375a4df17e153011b797ef28csewardj  }
3980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_RAX                                 \
4000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%RAX */                     \
4020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rdx,%%rdx\n\t"
403f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
4040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
405f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
4060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
408d68ac3e974d25f88492774f6baa491999afde9f9sewardj
409d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
410d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
411c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
412d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
413d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
414d68ac3e974d25f88492774f6baa491999afde9f9sewardj
4150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
4160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
4171a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
4180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
419575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
420575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
4219af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
4220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
423575ce8ef8fa86a502dabe152293320676922dcfebart    __extension__                                                 \
424575ce8ef8fa86a502dabe152293320676922dcfebart  ({         unsigned int  _zzq_args[6];                          \
4251c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int  _zzq_result;                           \
4261c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int* _zzq_ptr;                              \
4270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
4280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
4290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
4300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
4310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
4329af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
4330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
4341c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
4351c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
4361c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = client_request ( %R4 ) */           \
4381c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 1,1,1\n\t"                               \
4391c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"     /*result*/                     \
4401c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (_zzq_result)                         \
4411c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
4421c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3", "r4");               \
443575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
444575ce8ef8fa86a502dabe152293320676922dcfebart    })
4450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
446d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
447d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
4481c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    unsigned int __addr;                                          \
4490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
4500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = guest_NRADDR */                     \
4511c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 2,2,2\n\t"                               \
4521c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"                                    \
4531c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (__addr)                              \
4540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
4551c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3"                       \
4560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
457d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
4580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
4590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
4610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* branch-and-link-to-noredir *%R11 */       \
4630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "or 3,3,3\n\t"
464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
4650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
4670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
469d68ac3e974d25f88492774f6baa491999afde9f9sewardj
470d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
471d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
472d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int nraddr; /* where's the code? */
473d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int r2;  /* what tocptr do we need? */
474d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
475d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
476d68ac3e974d25f88492774f6baa491999afde9f9sewardj
4771a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
4781a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
4791a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
4801a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
481575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
482575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
4839af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
4840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
485575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
486575ce8ef8fa86a502dabe152293320676922dcfebart  ({         unsigned long long int  _zzq_args[6];                \
4878258a3a849f8bf47146ff1740d2dac429bb453a5sewardj             unsigned long long int  _zzq_result;                 \
4888258a3a849f8bf47146ff1740d2dac429bb453a5sewardj             unsigned long long int* _zzq_ptr;                    \
4891a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
4901a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
4911a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
4921a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
4931a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
4949af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
4950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
4968258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
4978258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
4988258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4991a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = client_request ( %R4 ) */           \
5008258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 1,1,1\n\t"                               \
5018258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"     /*result*/                     \
5028258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (_zzq_result)                         \
5038258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
5048258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3", "r4");               \
505575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
506575ce8ef8fa86a502dabe152293320676922dcfebart  })
5071a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
508d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
509d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
5108258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    unsigned long long int __addr;                                \
5111a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
5121a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = guest_NRADDR */                     \
5138258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 2,2,2\n\t"                               \
5148258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"                                    \
5158258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (__addr)                              \
5161a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     :                                            \
5178258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3"                       \
5181a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                    );                                            \
519d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
520d68ac3e974d25f88492774f6baa491999afde9f9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
521d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
5228258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 4,4,4\n\t"                               \
5238258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"                                    \
5248258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (__addr)                              \
525d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     :                                            \
5268258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3"                       \
527d68ac3e974d25f88492774f6baa491999afde9f9sewardj                    );                                            \
528d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->r2 = __addr;                                       \
5290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
5301a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
5311a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
5321a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
5331a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* branch-and-link-to-noredir *%R11 */       \
5341a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 3,3,3\n\t"
5351a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
53859570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
53959570ffbe31930ab4d678754daaeec0715117a3dsewardj
54059570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
54159570ffbe31930ab4d678754daaeec0715117a3dsewardj
54259570ffbe31930ab4d678754daaeec0715117a3dsewardjtypedef
54359570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct {
54459570ffbe31930ab4d678754daaeec0715117a3dsewardj      unsigned int nraddr; /* where's the code? */
54559570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
54659570ffbe31930ab4d678754daaeec0715117a3dsewardj   OrigFn;
54759570ffbe31930ab4d678754daaeec0715117a3dsewardj
54859570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
54959570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
55059570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
55159570ffbe31930ab4d678754daaeec0715117a3dsewardj
552575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
553575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
55459570ffbe31930ab4d678754daaeec0715117a3dsewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
55559570ffbe31930ab4d678754daaeec0715117a3dsewardj                                                                  \
556575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
557575ce8ef8fa86a502dabe152293320676922dcfebart  ({volatile unsigned int  _zzq_args[6];                          \
55859570ffbe31930ab4d678754daaeec0715117a3dsewardj    volatile unsigned int  _zzq_result;                           \
55959570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
56059570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
56159570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
56259570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
56359570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
56459570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
56559570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
56659570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov r4, %2\n\t" /*ptr*/                     \
56759570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
56859570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = client_request ( R4 ) */             \
56959570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r10, r10, r10\n\t"                      \
57059570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"     /*result*/                  \
57159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (_zzq_result)                         \
57259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
57359570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc","memory", "r3", "r4");                \
574575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
575575ce8ef8fa86a502dabe152293320676922dcfebart  })
57659570ffbe31930ab4d678754daaeec0715117a3dsewardj
57759570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
57859570ffbe31930ab4d678754daaeec0715117a3dsewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
57959570ffbe31930ab4d678754daaeec0715117a3dsewardj    unsigned int __addr;                                          \
58059570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
58159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = guest_NRADDR */                      \
58259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r11, r11, r11\n\t"                      \
58359570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"                                 \
58459570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (__addr)                              \
58559570ffbe31930ab4d678754daaeec0715117a3dsewardj                     :                                            \
58659570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc", "memory", "r3"                       \
58759570ffbe31930ab4d678754daaeec0715117a3dsewardj                    );                                            \
58859570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_orig->nraddr = __addr;                                   \
58959570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
59059570ffbe31930ab4d678754daaeec0715117a3dsewardj
59159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
59259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
59359570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* branch-and-link-to-noredir *%R4 */        \
59459570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r12, r12, r12\n\t"
59559570ffbe31930ab4d678754daaeec0715117a3dsewardj
59659570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
59759570ffbe31930ab4d678754daaeec0715117a3dsewardj
598b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* ------------------------ s390x-linux ------------------------ */
599b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
600b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(PLAT_s390x_linux)
601b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
602b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjtypedef
603b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  struct {
604b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj     unsigned long long int nraddr; /* where's the code? */
605b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
606b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  OrigFn;
607b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
608b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
609b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * code. This detection is implemented in platform specific toIR.c
610b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * (e.g. VEX/priv/guest_s390_decoder.c).
611b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj */
612b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
613b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 15,15\n\t"                              \
614b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 1,1\n\t"                                \
615b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 2,2\n\t"                                \
616b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 3,3\n\t"
617b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
618b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
619b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
620b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
621b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
622575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
623575ce8ef8fa86a502dabe152293320676922dcfebart       _zzq_default, _zzq_request,                               \
624b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
625575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                  \
626575ce8ef8fa86a502dabe152293320676922dcfebart ({volatile unsigned long long int _zzq_args[6];                 \
627b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   volatile unsigned long long int _zzq_result;                  \
628b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
629b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
630b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
631b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
632b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
633b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
634b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   __asm__ volatile(/* r2 = args */                              \
635b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr 2,%1\n\t"                               \
636b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    /* r3 = default */                           \
637b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr 3,%2\n\t"                               \
638b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __SPECIAL_INSTRUCTION_PREAMBLE               \
639b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __CLIENT_REQUEST_CODE                        \
640b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    /* results = r3 */                           \
641b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr %0, 3\n\t"                              \
642b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "=d" (_zzq_result)                         \
643b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
644b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "cc", "2", "3", "memory"                   \
645b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                   );                                            \
646575ce8ef8fa86a502dabe152293320676922dcfebart   _zzq_result;                                                  \
647575ce8ef8fa86a502dabe152293320676922dcfebart })
648b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
649b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
650b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
651b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   volatile unsigned long long int __addr;                       \
652b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
653b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __GET_NR_CONTEXT_CODE                        \
654b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr %0, 3\n\t"                              \
655b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "=a" (__addr)                              \
656b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    :                                            \
657b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "cc", "3", "memory"                        \
658b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                   );                                            \
659b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_orig->nraddr = __addr;                                   \
660b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj }
661b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
662b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define VALGRIND_CALL_NOREDIR_R1                                 \
663b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __SPECIAL_INSTRUCTION_PREAMBLE               \
664b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __CALL_NO_REDIR_CODE
665b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
666b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif /* PLAT_s390x_linux */
667b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
668f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Insert assembly code for other platforms here... */
66926aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
67037091fb739760631f436043c47de612cf9fd2dd1sewardj#endif /* NVALGRIND */
6712e93c50dc50235189661b70e3f27a4098d5cccccsewardj
67269d9c4625034b60c08e04cc246fcf8093d23fde5nethercote
67330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
674f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
6750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ugly.  It's the least-worst tradeoff I can think of.               */
6760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
6770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* This section defines magic (a.k.a appalling-hack) macros for doing
6790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   guaranteed-no-redirection macros, so as to get from function
6800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   wrappers to the functions they are wrapping.  The whole point is to
6810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   construct standard call sequences, but to do the call itself with a
6820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   special no-redirect call pseudo-instruction that the JIT
6830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   understands and handles specially.  This section is long and
6840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   repetitious, and I can't see a way to make it shorter.
6850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The naming scheme is as follows:
6870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
6890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   'W' stands for "word" and 'v' for "void".  Hence there are
6910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
6920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   and for each, the possibility of returning a word-typed result, or
6930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   no result.
6940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj*/
6950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Use these to write the name of your wrapper.  NOTE: duplicates
69785cf90056b7a8d98d88335b47c599a35b35ff7casewardj   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
69885cf90056b7a8d98d88335b47c599a35b35ff7casewardj   the default behaviour equivalance class tag "0000" into the name.
69985cf90056b7a8d98d88335b47c599a35b35ff7casewardj   See pub_tool_redir.h for details -- normally you don't need to
70085cf90056b7a8d98d88335b47c599a35b35ff7casewardj   think about this, though. */
7010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7025f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn/* Use an extra level of macroisation so as to ensure the soname/fnname
7035f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   args are fully macro-expanded before pasting them together. */
7045f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
7055f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
7060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
70796044842731e581702c9ed4104d2949fcde20fd8sewardj   VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
7080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
71096044842731e581702c9ed4104d2949fcde20fd8sewardj   VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
7110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
712d68ac3e974d25f88492774f6baa491999afde9f9sewardj/* Use this macro from within a wrapper function to collect the
713d68ac3e974d25f88492774f6baa491999afde9f9sewardj   context (address and possibly other info) of the original function.
714d68ac3e974d25f88492774f6baa491999afde9f9sewardj   Once you have that you can then use it in one of the CALL_FN_
715d68ac3e974d25f88492774f6baa491999afde9f9sewardj   macros.  The type of the argument _lval is OrigFn. */
716d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
7170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Derivatives of the main macros below, for calling functions
7190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   returning void. */
7200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_v(fnptr)                                        \
7220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
7230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_v(_junk,fnptr); } while (0)
7240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_W(fnptr, arg1)                                  \
7260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
7270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
7280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
7300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
7310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
7320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7335ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
7345ce4b150ce5d32c9af07a24717081ea34568388asewardj   do { volatile unsigned long _junk;                             \
7355ce4b150ce5d32c9af07a24717081ea34568388asewardj        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
7365ce4b150ce5d32c9af07a24717081ea34568388asewardj
7372b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
7382b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
7392b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
7402b5f0a90334a2271791c110548a842fadb5ffc65njn
7412b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
7422b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
7432b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
7442b5f0a90334a2271791c110548a842fadb5ffc65njn
7452b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
7462b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
7472b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
7482b5f0a90334a2271791c110548a842fadb5ffc65njn
7492b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
7502b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
7512b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
7522b5f0a90334a2271791c110548a842fadb5ffc65njn
753f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
7540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
755f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
7560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call.  No need to mention eax
7580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   as gcc can already see that, plus causes gcc to bomb. */
7590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
7600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
7620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 4. */
7630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
76466226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_v(lval, orig)                                   \
7650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
76666226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
7680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
76966226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
78066226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
7810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
78266226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
7840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
78566226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
78887a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
7890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
79287a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $16, %%esp\n"                                      \
7930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
80066226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
80266226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
80566226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
80987a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
81487a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $16, %%esp\n"                                      \
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8169e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*in*/    "a" (&_argvec[0])                            \
8179e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8189e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      );                                                          \
8199e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      lval = (__typeof__(lval)) _res;                             \
8209e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   } while (0)
8219e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
8229e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
8239e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   do {                                                           \
8249e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile OrigFn        _orig = (orig);                      \
8259e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _argvec[4];                          \
8269e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _res;                                \
8279e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8289e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[1] = (unsigned long)(arg1);                         \
8299e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[2] = (unsigned long)(arg2);                         \
8309e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[3] = (unsigned long)(arg3);                         \
8319e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      __asm__ volatile(                                           \
83287a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
8339e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 12(%%eax)\n\t"                                    \
8349e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 8(%%eax)\n\t"                                     \
8359e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 4(%%eax)\n\t"                                     \
8369e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8379e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         VALGRIND_CALL_NOREDIR_EAX                                \
83887a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $16, %%esp\n"                                      \
8399e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*out*/   "=a" (_res)                                  \
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
84666226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
8470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
84866226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[5];                          \
8500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
85166226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $16, %%esp\n"                                      \
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
87166226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
8720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
87366226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[6];                          \
8750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
87666226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
88387a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
8840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
89187a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $32, %%esp\n"                                      \
8920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
89966226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
9000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
90166226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[7];                          \
9030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
90466226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
9080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
9090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
9100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
9110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
91287a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
9130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
9140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
9150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
9160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
9170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
9180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
92187a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $32, %%esp\n"                                      \
9220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
92966226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
93066226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7)                            \
9310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
93266226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[8];                          \
9340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
93566226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
9390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
9400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
9410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
9420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
9430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
94487a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
9450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
9460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
9470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
9480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
9490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
9500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
9510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
95487a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $32, %%esp\n"                                      \
9550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
96266226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
96366226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7,arg8)                       \
9640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
96566226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[9];                          \
9670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
96866226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
9720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
9730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
9740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
9750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
9760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
9770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
9780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
9790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
9800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
9810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
9820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
9830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
9840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
9850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $32, %%esp\n"                                      \
9890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
99645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
99745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                 arg7,arg8,arg9)                  \
99845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
99945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
100045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[10];                         \
100145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
100245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
100345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
100445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
100545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
100645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
100745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
100845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
100945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
101045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
101145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
101245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
101387a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
101445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
101545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
101645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
101745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
101845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
101945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
102045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
102145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
102245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
102345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
102445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
102587a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $48, %%esp\n"                                      \
102645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
102745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
102845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
102945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
103045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
103145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
103245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
103345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
103445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                  arg7,arg8,arg9,arg10)           \
103545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
103645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
103745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[11];                         \
103845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
103945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
104045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
104145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
104245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
104345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
104445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
104545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
104645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
104745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
104845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
104945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[10] = (unsigned long)(arg10);                       \
105045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
105187a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
105245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 40(%%eax)\n\t"                                    \
105345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
105445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
105545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
105645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
105745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
105845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
105945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
106045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
106145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
106245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
106345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
106487a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $48, %%esp\n"                                      \
106545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
106645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
106745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
106845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
106945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
107045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
107145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
10725ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
10735ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg6,arg7,arg8,arg9,arg10,      \
10745ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg11)                          \
10755ce4b150ce5d32c9af07a24717081ea34568388asewardj   do {                                                           \
10765ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile OrigFn        _orig = (orig);                      \
10775ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _argvec[12];                         \
10785ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _res;                                \
10795ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10805ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[1] = (unsigned long)(arg1);                         \
10815ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[2] = (unsigned long)(arg2);                         \
10825ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[3] = (unsigned long)(arg3);                         \
10835ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[4] = (unsigned long)(arg4);                         \
10845ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[5] = (unsigned long)(arg5);                         \
10855ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[6] = (unsigned long)(arg6);                         \
10865ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[7] = (unsigned long)(arg7);                         \
10875ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[8] = (unsigned long)(arg8);                         \
10885ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[9] = (unsigned long)(arg9);                         \
10895ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[10] = (unsigned long)(arg10);                       \
10905ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[11] = (unsigned long)(arg11);                       \
10915ce4b150ce5d32c9af07a24717081ea34568388asewardj      __asm__ volatile(                                           \
109287a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
10935ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 44(%%eax)\n\t"                                    \
10945ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 40(%%eax)\n\t"                                    \
10955ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 36(%%eax)\n\t"                                    \
10965ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 32(%%eax)\n\t"                                    \
10975ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 28(%%eax)\n\t"                                    \
10985ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 24(%%eax)\n\t"                                    \
10995ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 20(%%eax)\n\t"                                    \
11005ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 16(%%eax)\n\t"                                    \
11015ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 12(%%eax)\n\t"                                    \
11025ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 8(%%eax)\n\t"                                     \
11035ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 4(%%eax)\n\t"                                     \
11045ce4b150ce5d32c9af07a24717081ea34568388asewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
11055ce4b150ce5d32c9af07a24717081ea34568388asewardj         VALGRIND_CALL_NOREDIR_EAX                                \
110687a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addl $48, %%esp\n"                                      \
11075ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*out*/   "=a" (_res)                                  \
11085ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*in*/    "a" (&_argvec[0])                            \
11095ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11105ce4b150ce5d32c9af07a24717081ea34568388asewardj      );                                                          \
11115ce4b150ce5d32c9af07a24717081ea34568388asewardj      lval = (__typeof__(lval)) _res;                             \
11125ce4b150ce5d32c9af07a24717081ea34568388asewardj   } while (0)
11135ce4b150ce5d32c9af07a24717081ea34568388asewardj
111466226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
111566226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
111666226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg11,arg12)                    \
11170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
111866226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
11190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[13];                         \
11200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
112166226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
11230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
11240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
11250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
11260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
11270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
11280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
11290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
11300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[9] = (unsigned long)(arg9);                         \
11310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[10] = (unsigned long)(arg10);                       \
11320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[11] = (unsigned long)(arg11);                       \
11330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[12] = (unsigned long)(arg12);                       \
11340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
11350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 48(%%eax)\n\t"                                    \
11360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 44(%%eax)\n\t"                                    \
11370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 40(%%eax)\n\t"                                    \
11380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 36(%%eax)\n\t"                                    \
11390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
11400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
11410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
11420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
11430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
11440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
11450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
11460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
11470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
11480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
11490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $48, %%esp\n"                                      \
11500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1157f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
11580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1159f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
11600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1161f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
11620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
11640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
11660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
11670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                            "rdi", "r8", "r9", "r10", "r11"
11680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1169dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj/* This is all pretty complex.  It's so as to make stack unwinding
1170dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   work reliably.  See bug 243270.  The basic problem is the sub and
1171dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   add of 128 of %rsp in all of the following macros.  If gcc believes
1172dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   the CFA is in %rsp, then unwinding may fail, because what's at the
1173dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   CFA is not what gcc "expected" when it constructs the CFIs for the
1174dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   places where the macros are instantiated.
1175dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1176dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   But we can't just add a CFI annotation to increase the CFA offset
1177dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   by 128, to match the sub of 128 from %rsp, because we don't know
1178dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   whether gcc has chosen %rsp as the CFA at that point, or whether it
1179dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   has chosen some other register (eg, %rbp).  In the latter case,
1180dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   adding a CFI annotation to change the CFA offset is simply wrong.
1181dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1182dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   So the solution is to get hold of the CFA using
11838d1dc150a77fe495682a928949c5d5b7443b045csewardj   __builtin_dwarf_cfa(), put it in a known register, and add a
1184dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   CFI annotation to say what the register is.  We choose %rbp for
1185dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   this (perhaps perversely), because:
1186dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1187dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   (1) %rbp is already subject to unwinding.  If a new register was
1188dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       chosen then the unwinder would have to unwind it in all stack
1189dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       traces, which is expensive, and
1190dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1191dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   (2) %rbp is already subject to precise exception updates in the
1192dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       JIT.  If a new register was chosen, we'd have to have precise
1193dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       exceptions for it too, which reduces performance of the
1194dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       generated code.
1195dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1196dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   However .. one extra complication.  We can't just whack the result
11978d1dc150a77fe495682a928949c5d5b7443b045csewardj   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1198dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   list of trashed registers at the end of the inline assembly
1199dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   fragments; gcc won't allow %rbp to appear in that list.  Hence
1200dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   instead we need to stash %rbp in %r15 for the duration of the asm,
1201dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   and say that %r15 is trashed instead.  gcc seems happy to go with
1202dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   that.
1203dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1204dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   Oh .. and this all needs to be conditionalised so that it is
1205dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   unchanged from before this commit, when compiled with older gccs
12068d1dc150a77fe495682a928949c5d5b7443b045csewardj   that don't support __builtin_dwarf_cfa.  Furthermore, since
12078d1dc150a77fe495682a928949c5d5b7443b045csewardj   this header file is freestanding, it has to be independent of
12088d1dc150a77fe495682a928949c5d5b7443b045csewardj   config.h, and so the following conditionalisation cannot depend on
12098d1dc150a77fe495682a928949c5d5b7443b045csewardj   configure time checks.
12108d1dc150a77fe495682a928949c5d5b7443b045csewardj
12118d1dc150a77fe495682a928949c5d5b7443b045csewardj   Although it's not clear from
12128d1dc150a77fe495682a928949c5d5b7443b045csewardj   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
12138d1dc150a77fe495682a928949c5d5b7443b045csewardj   this expression excludes Darwin.
12148d1dc150a77fe495682a928949c5d5b7443b045csewardj   .cfi directives in Darwin assembly appear to be completely
12158d1dc150a77fe495682a928949c5d5b7443b045csewardj   different and I haven't investigated how they work.
12168d1dc150a77fe495682a928949c5d5b7443b045csewardj
12178d1dc150a77fe495682a928949c5d5b7443b045csewardj   For even more entertainment value, note we have to use the
12188d1dc150a77fe495682a928949c5d5b7443b045csewardj   completely undocumented __builtin_dwarf_cfa(), which appears to
12198d1dc150a77fe495682a928949c5d5b7443b045csewardj   really compute the CFA, whereas __builtin_frame_address(0) claims
12208d1dc150a77fe495682a928949c5d5b7443b045csewardj   to but actually doesn't.  See
12218d1dc150a77fe495682a928949c5d5b7443b045csewardj   https://bugs.kde.org/show_bug.cgi?id=243270#c47
1222dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj*/
12238d1dc150a77fe495682a928949c5d5b7443b045csewardj#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1224dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define __FRAME_POINTER                                         \
12258d1dc150a77fe495682a928949c5d5b7443b045csewardj      ,"r"(__builtin_dwarf_cfa())
1226dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
1227dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      "movq %%rbp, %%r15\n\t"                                     \
12288d1dc150a77fe495682a928949c5d5b7443b045csewardj      "movq %2, %%rbp\n\t"                                        \
12298d1dc150a77fe495682a928949c5d5b7443b045csewardj      ".cfi_remember_state\n\t"                                   \
1230dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      ".cfi_def_cfa rbp, 0\n\t"
1231dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_EPILOGUE                                   \
1232dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      "movq %%r15, %%rbp\n\t"                                     \
1233dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      ".cfi_restore_state\n\t"
1234dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#else
1235dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define __FRAME_POINTER
1236dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_PROLOGUE
1237dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_EPILOGUE
1238dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#endif
1239dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1240dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
12410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
12420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 8. */
12430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1244a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1245a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   macros.  In order not to trash the stack redzone, we need to drop
1246a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   %rsp by 128 before the hidden call, and restore afterwards.  The
1247a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   nastyness is that it is only by luck that the stack still appears
1248a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   to be unwindable during the hidden call - since then the behaviour
1249a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   of any routine using this macro does not match what the CFI data
1250a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   says.  Sigh.
1251a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1252a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Why is this important?  Imagine that a wrapper has a stack
1253a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   allocated local, and passes to the hidden call, a pointer to it.
1254a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Because gcc does not know about the hidden call, it may allocate
1255a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   that local in the redzone.  Unfortunately the hidden call may then
1256a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   trash it before it comes to use it.  So we must step clear of the
1257a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   redzone, for the duration of the hidden call, to make it safe.
1258a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1259a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Probably the same problem afflicts the other redzone-style ABIs too
12606e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   (ppc64-linux); but for those, the stack is
1261a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   self describing (none of this CFI nonsense) so at least messing
1262a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   with the stack pointer doesn't give a danger of non-unwindable
1263a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   stack. */
1264a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1265c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_v(lval, orig)                                   \
12660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1267c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
12680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
12690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1270c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
12710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1272dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1273a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
12740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
12750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1276a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1277dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
12780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
1279dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1280dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
12810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
12820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
12830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
12840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1285c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
12860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1287c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
12880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
12890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1290c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
12910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
12920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1293dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1294a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
12950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
12960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
12970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1298a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1299dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
13000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
1301dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1302dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
13030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
13040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
13050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
13060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1307c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
13080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1309c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
13100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
13110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1312c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
13130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
13140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
13150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1316dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1317a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
13180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
13190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
13200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
13210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1322a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1323dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
13240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
1325dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1326dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
13270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
13280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
13290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
13300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1331a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1332a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1333a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1334a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[4];                          \
1335a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1336a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1337a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1338a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1339a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1340a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1341dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1342a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1343a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1344a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1345a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1346a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1347a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1348a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1349dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1350a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1351dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1352dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1353a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1354a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1355a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1356a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1357a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1358a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1359a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1360a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[5];                          \
1361a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1362a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1363a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1364a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1365a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1366a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1367a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1368dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1369a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1370a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1371a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1372a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1373a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1374a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1375a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1376a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1377dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1378a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1379dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1380dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1381a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1382a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1383a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1384a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1385a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1386a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1387a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1388a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[6];                          \
1389a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1390a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1391a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1392a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1393a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1394a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1395a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1396a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1397dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1398a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1399a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1400a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1401a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1402a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1403a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1404a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1405a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1406a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1407dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1408a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1409dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1410dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1411a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1412a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1413a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1414a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1415a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1416a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1417a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1418a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[7];                          \
1419a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1420a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1421a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1422a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1423a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1424a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1425a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1426a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1427a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1428dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1429a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1430a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1431a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1432a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1433a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1434a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1435a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1436a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1437a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
14382823aacb0fa513aef4100388e633c69764e60b77bart         "addq $128,%%rsp\n\t"                                    \
1439dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1440a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1441dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1442dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1443a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1444a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1445a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1446a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1447a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1448a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7)                            \
1449a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1450a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1451a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[8];                          \
1452a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1453a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1454a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1455a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1456a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1457a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1458a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1459a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1460a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1461a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1462dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
146387a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subq $136,%%rsp\n\t"                                    \
1464a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1465a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1466a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1467a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1468a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1469a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1470a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1471a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1472a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1473a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $8, %%rsp\n"                                       \
147487a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addq $136,%%rsp\n\t"                                    \
1475dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1476a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1477dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1478dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1479a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1480a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1481a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1482a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1483a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1484a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8)                       \
1485a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1486a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1487a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[9];                          \
1488a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1489a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1490a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1491a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1492a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1493a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1494a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1495a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1496a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1497a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1498a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1499dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1500a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1501a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1502a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1503a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1504a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1505a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1506a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1507a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1508a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1509a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1510a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1511a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $16, %%rsp\n"                                      \
1512a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1513dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1514a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1515dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1516dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1517a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1518a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1519a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1520a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1521a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1522a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8,arg9)                  \
1523a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1524a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1525a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[10];                         \
1526a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1527a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1528a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1529a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1530a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1531a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1532a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1533a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1534a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1535a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1536a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1537a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1538dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
153987a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subq $136,%%rsp\n\t"                                    \
1540a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1541a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1542a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1543a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1544a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1545a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1546a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1547a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1548a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1549a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1550a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1551a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $24, %%rsp\n"                                      \
155287a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addq $136,%%rsp\n\t"                                    \
1553dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1554a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1555dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1556dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1557a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1558a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1559a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1560a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1561a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1562a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10)           \
1563a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1564a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1565a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[11];                         \
1566a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1567a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1568a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1569a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1570a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1571a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1572a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1573a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1574a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1575a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1576a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1577a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1578a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1579dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1580a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1581a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1582a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1583a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1584a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1585a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1586a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1587a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1588a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1589a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1590a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1591a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1592a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1593a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $32, %%rsp\n"                                      \
1594a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1595dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1596a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1597dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1598dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1599a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1600a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1601a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1602a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1603a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1604a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
1605a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1606a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1607a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[12];                         \
1608a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1609a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1610a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1611a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1612a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1613a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1614a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1615a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1616a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1617a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1618a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1619a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1620a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1621a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1622dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
162387a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subq $136,%%rsp\n\t"                                    \
1624a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1625a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1626a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1627a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1628a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1629a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1630a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1631a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1632a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1633a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1634a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1635a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1636a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1637a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $40, %%rsp\n"                                      \
163887a287b47f496063f5869dc5039a81baeb6a29aesewardj         "addq $136,%%rsp\n\t"                                    \
1639dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1640a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1641dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1642dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1643a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1644a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1645a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1646a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1647a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1648a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
1649a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1650a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1651a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[13];                         \
1652a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1653a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1654a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1655a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1656a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1657a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1658a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1659a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1660a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1661a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1662a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1663a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1664a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1665a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[12] = (unsigned long)(arg12);                       \
1666a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1667dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_PROLOGUE                                    \
1668a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1669a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 96(%%rax)\n\t"                                    \
1670a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1671a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1672a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1673a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1674a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1675a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1676a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1677a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1678a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1679a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1680a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1681a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1682a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1683a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $48, %%rsp\n"                                      \
1684a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1685dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         VALGRIND_CFI_EPILOGUE                                    \
1686a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1687dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
1688dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
1689a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1690a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1691a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1692a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1693f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
16940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1695f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
16960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1697f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
16980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1699ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* This is useful for finding out about the on-stack stuff:
1700ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1701ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f9  ( int,int,int,int,int,int,int,int,int );
1702ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1703ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1704ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1705ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1706ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g9 ( void ) {
1707ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f9(11,22,33,44,55,66,77,88,99);
1708ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1709ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g10 ( void ) {
1710ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f10(11,22,33,44,55,66,77,88,99,110);
1711ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1712ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g11 ( void ) {
1713ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f11(11,22,33,44,55,66,77,88,99,110,121);
1714ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1715ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g12 ( void ) {
1716ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1717ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1718ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj*/
1719ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
17200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
17210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
17220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
1723ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define __CALLER_SAVED_REGS                                       \
1724ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "lr", "ctr", "xer",                                            \
1725ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1726ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1727ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r11", "r12", "r13"
17280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1729ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* These CALL_FN_ macros assume that on ppc32-linux,
1730ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   sizeof(unsigned long) == 4. */
17310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
173238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_v(lval, orig)                                   \
17330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1734d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
17350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
17360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1737d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
17380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
17390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
17400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
17410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
17420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
17430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
17440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
17450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
17460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
17470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
17480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
17490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
175038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
17510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
175238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
17530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
17540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
175538de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
17560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
17570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
17580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
17590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
17600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
17610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
17620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
17630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
17640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
17650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
17660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
17670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
17680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
17690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
177038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
17710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
177238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
17730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
17740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
177538de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
17760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
17770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)arg2;                           \
17780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
17790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
17800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
17810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 4,8(11)\n\t"                                        \
17820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
17830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
17840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
17850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
17860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
17870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
17880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
17890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
17900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
17910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1792ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1793ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1794ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1795ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[4];                          \
1796ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1797ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1798ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1799ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1800ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1801ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1802ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1803ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1804ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1805ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1806ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1807ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1808ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1809ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1810ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1811ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1812ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1813ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1814ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1815ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1816ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1817ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1818ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1819ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[5];                          \
1820ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1821ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1822ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1823ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1824ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1825ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1826ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1827ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1828ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1829ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1830ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1831ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1832ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1833ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1834ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1835ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1836ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1837ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1838ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1839ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1840ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1841ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1842ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1843ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1844ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1845ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[6];                          \
1846ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1847ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1848ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1849ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1850ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1851ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1852ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1853ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1854ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1855ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1856ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1857ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1858ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1859ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1860ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1861ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1862ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1863ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1864ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1865ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1866ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1867ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1868ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1869ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1870ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1871ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1872ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1873ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[7];                          \
1874ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1875ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1876ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1877ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1878ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1879ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1880ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1881ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1882ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1883ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1884ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1885ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1886ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1887ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1888ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1889ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1890ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1891ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1892ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1893ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1894ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1895ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1896ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1897ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1898ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1899ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1900ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1901ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7)                            \
1902ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1903ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1904ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[8];                          \
1905ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1906ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1907ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1908ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1909ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1910ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1911ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1912ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1913ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1914ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1915ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1916ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1917ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1918ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1919ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1920ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1921ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1922ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1923ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1924ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1925ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1926ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1927ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1928ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1929ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1930ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1931ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1932ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1933ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1934ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8)                       \
1935ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1936ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1937ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[9];                          \
1938ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1939ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1940ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1941ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1942ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1943ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1944ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1945ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1946ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1947ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1948ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1949ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1950ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1951ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1952ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1953ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1954ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1955ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1956ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1957ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1958ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1959ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1960ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1961ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1962ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1963ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1964ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1965ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1966ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1967ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1968ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1969ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8,arg9)                  \
1970ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1971ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1972ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[10];                         \
1973ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1974ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1975ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1976ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1977ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1978ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1979ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1980ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1981ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1982ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1983ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1984ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1985ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1986ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
1987ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1988ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1989ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1990ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1991ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1992ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1993ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1994ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1995ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1996ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1997ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1998ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1999ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2000ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2001ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
2002ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2003ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2004ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
2005ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2006ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2007ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2008ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2009ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2010ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2011ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10)           \
2012ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2013ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2014ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[11];                         \
2015ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2016ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2017ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2018ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2019ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2020ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2021ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2022ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2023ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2024ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2025ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2026ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2027ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
2028ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2029ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
2030ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2031ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2032ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2033ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2034ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2035ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2036ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2037ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2038ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2039ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2040ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2041ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2042ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2043ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2044ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2045ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2046ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2047ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
2048ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2049ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2050ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
2051ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2052ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2053ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2054ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2055ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2056ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2057ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2058ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2059ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2060ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[12];                         \
2061ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2062ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2063ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2064ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2065ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2066ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2067ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2068ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2069ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2070ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2071ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2072ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2073ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
2074ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
2075ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2076ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
2077ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
2078ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
2079ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
2080ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2081ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2082ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2083ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2084ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2085ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2086ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2087ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2088ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2089ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2090ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2091ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2092ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2093ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2094ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2095ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2096ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2097ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
2098ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2099ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2100ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
2101ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2102ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2103ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2104ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2105ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2106ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2107ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2108ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2109ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2110ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[13];                         \
2111ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2112ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2113ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2114ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2115ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2116ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2117ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2118ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2119ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2120ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2121ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2122ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2123ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
2124ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[12] = (unsigned long)arg12;                         \
2125ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
2126ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2127ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
2128ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg12 */                                              \
2129ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,48(11)\n\t"                                       \
2130ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,20(1)\n\t"                                        \
2131ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
2132ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
2133ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
2134ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2135ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2136ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2137ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2138ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2139ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2140ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2141ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2142ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2143ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2144ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2145ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2146ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2147ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2148ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2149ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2150ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2151ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
2152ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2153ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2154ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
2155ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2156ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2157ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2158ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2159ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2160f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
21610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2162f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
21630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2164f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
21659734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
21669734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
21679734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
21689734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These regs are trashed by the hidden call. */
2169cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define __CALLER_SAVED_REGS                                       \
2170cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "lr", "ctr", "xer",                                            \
2171cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2172cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2173cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r11", "r12", "r13"
21749734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
21759734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
21769734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   long) == 8. */
21779734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2178d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_v(lval, orig)                                   \
21799734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2180d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2181d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+0];                        \
21829734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2183d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2184d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
2185d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
21869734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
21879734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2188d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2189d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2190d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
21919734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
21929734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
21939734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2194d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
21959734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2196d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
21979734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
21989734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
21999734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
22009734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
22019734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2202d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
22039734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2204d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2205d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+1];                        \
22069734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2207d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2208d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2209d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2210d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
22119734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
22129734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2213d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2214d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2215d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2216d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
22179734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
22189734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
22199734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2220d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
22219734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2222d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
22239734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
22249734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
22259734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
22269734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
22279734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2228d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
22299734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2230d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2231d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+2];                        \
22329734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2233d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2234d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2235d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2236d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2237d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
22389734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
22399734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2240d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2241d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2242d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2243cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2244cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2245cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2246cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2247cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2248cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2249cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2250cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2251cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2252cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2253cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2254cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2255cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2256cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2257cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2258cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2259cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+3];                        \
2260cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2261cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2262cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2263cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2264cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2265cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2266cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2267cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2268cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2269cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2270cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2271cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2272cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2273cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2274d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
22759734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
22769734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
22779734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2278d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
22799734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2280d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
22819734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2282cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2283cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2284cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2285cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2286cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2287cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2288cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2289cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+4];                        \
2290cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2291cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2292cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2293cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2294cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2295cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2296cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2297cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2298cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2299cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2300cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2301cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2302cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2303cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2304cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2305cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2306cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2307cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2308cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2309cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2310cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2311cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2312cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2313cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2314cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2315cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2316cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2317cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2318cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2319cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2320cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2321cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+5];                        \
2322cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2323cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2324cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2325cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2326cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2327cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2328cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2329cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2330cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2331cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2332cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2333cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2334cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2335cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2336cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2337cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2338cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2339cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2340cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2341cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2342cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2343cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2344cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2345cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2346cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2347cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2348cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2349cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2350cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2351cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2352cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2353cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2354cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2355cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+6];                        \
2356cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2357cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2358cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2359cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2360cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2361cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2362cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2363cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2364cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2365cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2366cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2367cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2368cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2369cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2370cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2371cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2372cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2373cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2374cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2375cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2376cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2377cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2378cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2379cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2380cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2381cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2382cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2383cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2384cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2385cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2386cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2387cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2388cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2389cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7)                            \
2390cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2391cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2392cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+7];                        \
2393cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2394cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2395cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2396cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2397cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2398cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2399cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2400cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2401cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2402cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2403cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2404cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2405cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2406cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2407cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2408cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2409cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2410cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2411cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2412cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2413cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2414cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2415cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2416cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2417cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2418cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2419cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2420cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2421cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2422cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2423cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2424cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2425cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2426cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2427cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2428cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8)                       \
2429cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2430cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2431cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+8];                        \
2432cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2433cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2434cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2435cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2436cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2437cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2438cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2439cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2440cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2441cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2442cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2443cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2444cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2445cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2446cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2447cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2448cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2449cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2450cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2451cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2452cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2453cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2454cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2455cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2456cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2457cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2458cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2459cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2460cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2461cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2462cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2463cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2464cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2465cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2466cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2467cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2468cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2469cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8,arg9)                  \
2470cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2471cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2472cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+9];                        \
2473cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2474cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2475cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2476cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2477cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2478cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2479cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2480cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2481cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2482cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2483cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2484cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2485cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2486cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2487cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2488cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2489cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2490cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2491cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2492cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2493cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2494cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2495cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2496cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2497cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2498cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2499cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2500cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2501cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2502cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2503cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2504cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2505cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2506cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2507cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2508cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2509cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2510cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2511cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2512cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2513cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2514cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2515cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2516cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2517cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10)           \
2518cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2519cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2520cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+10];                       \
2521cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2522cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2523cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2524cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2525cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2526cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2527cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2528cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2529cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2530cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2531cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2532cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2533cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2534cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2535cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2536cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2537cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2538cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2539cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2540cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2541cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2542cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2543cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2544cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2545cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2546cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2547cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2548cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2549cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2550cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2551cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2552cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2553cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2554cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2555cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2556cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2557cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2558cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2559cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2560cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2561cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2562cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2563cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2564cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2565cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2566cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2567cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2568cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2569cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2570cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2571cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2572cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+11];                       \
2573cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2574cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2575cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2576cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2577cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2578cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2579cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2580cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2581cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2582cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2583cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2584cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2585cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2586cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2587cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2588cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2589cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2590cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2591cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2592cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2593cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2594cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2595cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2596cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2597cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2598cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2599cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2600cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2601cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2602cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2603cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2604cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2605cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2606cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2607cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2608cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2609cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2610cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2611cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2612cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2613cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2614cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2615cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2616cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2617cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2618cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2619cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2620cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2621cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2622cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2623cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2624cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2625cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2626cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2627cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2628cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+12];                       \
2629cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2630cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2631cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2632cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2633cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2634cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2635cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2636cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2637cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2638cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2639cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2640cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2641cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2642cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2643cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2644cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
2645cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2646cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2647cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2648cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2649cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2650cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg12 */                                              \
2651cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,96(11)\n\t"                                       \
2652cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,136(1)\n\t"                                       \
2653cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2654cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2655cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2656cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2657cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2658cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2659cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2660cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2661cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2662cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2663cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2664cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2665cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2666cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2667cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2668cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2669cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2670cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2671cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2672cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2673cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2674cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2675cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2676cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2677cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2678cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2679cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
26809734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
26819734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
26829734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
26839734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2684f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
2685f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
268659570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
268759570ffbe31930ab4d678754daaeec0715117a3dsewardj
268859570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
268959570ffbe31930ab4d678754daaeec0715117a3dsewardj
269059570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These regs are trashed by the hidden call. */
269159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
269259570ffbe31930ab4d678754daaeec0715117a3dsewardj
269359570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
269459570ffbe31930ab4d678754daaeec0715117a3dsewardj   long) == 4. */
269559570ffbe31930ab4d678754daaeec0715117a3dsewardj
269659570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_v(lval, orig)                                   \
269759570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
269859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
269959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[1];                          \
270059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
270159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
270259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
270359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
270459570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
270559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
270659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
270759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
270859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
270959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
271059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
271159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
271259570ffbe31930ab4d678754daaeec0715117a3dsewardj
271359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
271459570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
271559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
271659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[2];                          \
271759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
271859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
271959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
272059570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
272159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
272259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
272359570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
272459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
272559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
272659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
272759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
272859570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
272959570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
273059570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
273159570ffbe31930ab4d678754daaeec0715117a3dsewardj
273259570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
273359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
273459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
273559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[3];                          \
273659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
273759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
273859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
273959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
274059570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
274159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
274259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
274359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
274459570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
274559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
274659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
274759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
274859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
274959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
275059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
275159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
275259570ffbe31930ab4d678754daaeec0715117a3dsewardj
275359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
275459570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
275559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
275659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[4];                          \
275759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
275859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
275959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
276059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
276159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
276259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
276359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
276459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
276559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
276659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
276759570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
276859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
276959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
277059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
277159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
277259570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
277359570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
277459570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
277559570ffbe31930ab4d678754daaeec0715117a3dsewardj
277659570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
277759570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
277859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
277959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[5];                          \
278059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
278159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
278259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
278359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
278459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
278559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
278659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
278759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
278859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
278959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
279059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
279159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
279259570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
279359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
279459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
279559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
279659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
279759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
279859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
279959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
280059570ffbe31930ab4d678754daaeec0715117a3dsewardj
280159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
280259570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
280359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
280459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[6];                          \
280559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
280659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
280759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
280859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
280959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
281059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
281159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
281259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
281359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
281459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
281559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
281659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
281759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
281859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
281959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
282059570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
282159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #4 \n\t"                                    \
282259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
282359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
282459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
282559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
282659570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
282759570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
282859570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
282959570ffbe31930ab4d678754daaeec0715117a3dsewardj
283059570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
283159570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
283259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
283359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[7];                          \
283459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
283559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
283659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
283759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
283859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
283959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
284059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
284159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
284259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
284359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
284459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
284559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
284659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
284759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
284859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
284959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
285059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
285159570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
285259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #8 \n\t"                                    \
285359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
285459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
285559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
285659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
285759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
285859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
285959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
286059570ffbe31930ab4d678754daaeec0715117a3dsewardj
286159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
286259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7)                            \
286359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
286459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
286559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[8];                          \
286659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
286759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
286859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
286959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
287059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
287159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
287259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
287359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
287459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
287559570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
287659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
287759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
287859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
287959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
288059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
288159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
288259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
288359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
288459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
288559570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
288659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #12 \n\t"                                   \
288759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
288859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
288959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
289059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
289159570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
289259570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
289359570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
289459570ffbe31930ab4d678754daaeec0715117a3dsewardj
289559570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
289659570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8)                       \
289759570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
289859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
289959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[9];                          \
290059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
290159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
290259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
290359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
290459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
290559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
290659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
290759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
290859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
290959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
291059570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
291159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
291259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
291359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
291459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
291559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3} \n\t"                             \
291659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
291759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
291859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
291959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
292059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
292159570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
292259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #16 \n\t"                                   \
292359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
292459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
292559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
292659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
292759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
292859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
292959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
293059570ffbe31930ab4d678754daaeec0715117a3dsewardj
293159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
293259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8,arg9)                  \
293359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
293459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
293559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[10];                         \
293659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
293759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
293859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
293959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
294059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
294159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
294259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
294359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
294459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
294559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
294659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
294759570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
294859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
294959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
295059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
295159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
295259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
295359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
295459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
295559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
295659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
295759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
295859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
295959570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
296059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #20 \n\t"                                   \
296159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
296259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
296359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
296459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
296559570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
296659570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
296759570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
296859570ffbe31930ab4d678754daaeec0715117a3dsewardj
296959570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
297059570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg7,arg8,arg9,arg10)           \
297159570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
297259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
297359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[11];                         \
297459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
297559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
297659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
297759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
297859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
297959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
298059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
298159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
298259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
298359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
298459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
298559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
298659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
298759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
298859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
298959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
299059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
299159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
299259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
299359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
299459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
299559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
299659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
299759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
299859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
299959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
300059570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
300159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #24 \n\t"                                   \
300259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
300359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
300459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
300559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
300659570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
300759570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
300859570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
300959570ffbe31930ab4d678754daaeec0715117a3dsewardj
301059570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
301159570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
301259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11)                          \
301359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
301459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
301559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[12];                         \
301659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
301759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
301859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
301959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
302059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
302159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
302259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
302359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
302459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
302559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
302659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
302759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
302859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
302959570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
303059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
303159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
303259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
303359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
303459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
303559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
303659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
303759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
303859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
303959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
304059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
304159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
304259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
304359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
304459570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
304559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #28 \n\t"                                   \
304659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
304759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
304859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
304959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS           \
305059570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
305159570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
305259570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
305359570ffbe31930ab4d678754daaeec0715117a3dsewardj
305459570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
305559570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
305659570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11,arg12)                    \
305759570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
305859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
305959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[13];                         \
306059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
306159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
306259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
306359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
306459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
306559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
306659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
306759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
306859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
306959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
307059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
307159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
307259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
307359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[12] = (unsigned long)(arg12);                       \
307459570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
307559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
307659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
307759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #48] \n\t"                                 \
307859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
307959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
308059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
308159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
308259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
308359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
308459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
308559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
308659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
308759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
308859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
308959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
309059570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
309159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #32 \n\t"                                   \
309259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
309359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
309459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
309559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
309659570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
309759570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
309859570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
309959570ffbe31930ab4d678754daaeec0715117a3dsewardj
310059570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
310159570ffbe31930ab4d678754daaeec0715117a3dsewardj
3102b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* ------------------------- s390x-linux ------------------------- */
3103b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3104b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(PLAT_s390x_linux)
3105b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3106b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* Similar workaround as amd64 (see above), but we use r11 as frame
3107b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   pointer and save the old r11 in r7. r11 might be used for
3108b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   argvec, therefore we copy argvec in r1 since r1 is clobbered
3109b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   after the call anyway.  */
3110b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3111b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define __FRAME_POINTER                                         \
3112b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ,"d"(__builtin_dwarf_cfa())
3113b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
3114b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_remember_state\n\t"                                   \
3115b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
3116b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 7,11\n\t"                                              \
3117b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 11,%2\n\t"                                             \
3118b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_def_cfa r11, 0\n\t"
3119b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_EPILOGUE                                   \
3120b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 11, 7\n\t"                                             \
3121b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_restore_state\n\t"
3122b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#else
3123b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define __FRAME_POINTER
3124b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
3125b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 1,%1\n\t"
3126b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_EPILOGUE
3127b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif
3128b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3129b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3130b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3131b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3132b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* These regs are trashed by the hidden call. Note that we overwrite
3133b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3134b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   function a proper return address. All others are ABI defined call
3135b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   clobbers. */
3136b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3137b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                           "f0","f1","f2","f3","f4","f5","f6","f7"
3138b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3139b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3140b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_v(lval, orig)                                  \
3141b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3142b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3143b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long  _argvec[1];                        \
3144b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3145b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3146b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3147b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3148b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3149b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
3150b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3151b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3152b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3153b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3154b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3155b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
3156b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3157b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3158b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3159b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3160b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3161b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* The call abi has the arguments in r2-r6 and stack */
3162b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_W(lval, orig, arg1)                            \
3163b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3164b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3165b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[2];                         \
3166b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3167b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3168b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3169b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3170b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3171b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3172b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3173b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3174b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3175b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3176b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3177b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3178b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3179b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3180b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3181b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3182b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3183b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3184b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3185b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
3186b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3187b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3188b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[3];                         \
3189b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3190b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3191b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3192b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3193b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3194b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3195b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3196b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3197b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3198b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3199b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3200b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3201b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3202b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3203b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3204b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3205b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3206b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3207b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3208b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3209b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3210b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
3211b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3212b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3213b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[4];                         \
3214b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3215b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3216b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3217b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3218b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3219b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3220b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3221b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3222b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3223b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3224b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3225b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3226b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3227b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3228b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3229b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3230b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3231b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3232b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3233b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3234b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3235b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3236b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3237b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
3238b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3239b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3240b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[5];                         \
3241b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3242b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3243b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3244b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3245b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3246b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3247b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3248b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3249b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3250b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3251b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3252b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3253b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3254b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3255b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3256b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3257b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3258b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3259b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3260b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3261b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3262b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3263b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3264b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3265b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3266b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
3267b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3268b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3269b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[6];                         \
3270b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3271b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3272b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3273b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3274b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3275b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3276b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3277b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3278b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3279b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3280b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3281b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3282b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3283b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3284b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3285b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3286b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3287b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3288b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3289b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3290b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3291b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3292b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3293b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3294b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3295b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3296b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3297b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3298b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6)                                       \
3299b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3300b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3301b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[7];                         \
3302b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3303b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3304b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3305b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3306b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3307b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3308b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3309b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3310b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3311b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3312b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-168\n\t"                                      \
3313b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3314b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3315b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3316b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3317b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3318b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3319b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3320b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3321b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3322b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,168\n\t"                                       \
3323b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3324b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3325b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3326b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3327b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3328b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3329b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3330b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3331b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3332b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7)                                 \
3333b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3334b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3335b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[8];                         \
3336b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3337b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3338b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3339b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3340b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3341b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3342b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3343b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3344b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3345b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3346b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3347b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-176\n\t"                                      \
3348b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3349b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3350b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3351b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3352b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3353b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3354b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3355b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3356b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3357b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3358b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,176\n\t"                                       \
3359b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3360b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3361b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3362b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3363b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3364b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3365b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3366b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3367b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3368b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8)                           \
3369b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3370b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3371b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[9];                         \
3372b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3373b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3374b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3375b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3376b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3377b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3378b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3379b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3380b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3381b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3382b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3383b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3384b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-184\n\t"                                      \
3385b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3386b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3387b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3388b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3389b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3390b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3391b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3392b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3393b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3394b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3395b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3396b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,184\n\t"                                       \
3397b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3398b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3399b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3400b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3401b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3402b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3403b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3404b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3405b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3406b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9)                     \
3407b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3408b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3409b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[10];                        \
3410b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3411b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3412b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3413b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3414b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3415b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3416b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3417b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3418b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3419b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3420b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3421b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3422b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3423b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-192\n\t"                                      \
3424b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3425b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3426b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3427b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3428b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3429b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3430b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3431b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3432b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3433b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3434b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3435b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3436b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,192\n\t"                                       \
3437b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3438b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3439b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3440b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3441b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3442b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3443b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3444b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3445b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3446b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10)              \
3447b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3448b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3449b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[11];                        \
3450b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3451b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3452b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3453b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3454b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3455b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3456b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3457b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3458b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3459b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3460b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3461b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3462b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3463b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3464b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-200\n\t"                                      \
3465b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3466b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3467b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3468b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3469b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3470b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3471b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3472b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3473b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3474b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3475b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3476b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3477b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3478b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,200\n\t"                                       \
3479b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3480b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3481b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3482b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3483b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3484b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3485b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3486b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3487b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3488b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
3489b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3490b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3491b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[12];                        \
3492b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3493b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3494b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3495b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3496b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3497b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3498b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3499b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3500b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3501b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3502b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3503b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3504b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[11] = (unsigned long)arg11;                        \
3505b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3506b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3507b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-208\n\t"                                      \
3508b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3509b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3510b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3511b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3512b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3513b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3514b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3515b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3516b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3517b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3518b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 200(8,15), 88(1)\n\t"                              \
3519b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3520b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3521b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3522b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,208\n\t"                                       \
3523b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3524b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3525b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3526b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3527b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3528b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3529b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3530b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3531b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3532b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3533b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3534b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3535b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[13];                        \
3536b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3537b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3538b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3539b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3540b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3541b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3542b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3543b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3544b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3545b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3546b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3547b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3548b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[11] = (unsigned long)arg11;                        \
3549b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[12] = (unsigned long)arg12;                        \
3550b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3551b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3552b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-216\n\t"                                      \
3553b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3554b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3555b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3556b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3557b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3558b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3559b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3560b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3561b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3562b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3563b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 200(8,15), 88(1)\n\t"                              \
3564b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 208(8,15), 96(1)\n\t"                              \
3565b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3566b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3567b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3568b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,216\n\t"                                       \
3569b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3570b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3571b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3572b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3573b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3574b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3575b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3576b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3577b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3578b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif /* PLAT_s390x_linux */
3579b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
35800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
35810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
35820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
35830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/*                                                                    */
358430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
358530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
35862e93c50dc50235189661b70e3f27a4098d5cccccsewardj/* Some request codes.  There are many more of these, but most are not
35872e93c50dc50235189661b70e3f27a4098d5cccccsewardj   exposed to end-user view.  These are the public ones, all of the
3588e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   form 0x1000 + small_number.
3589d799418996812817596beaa8b59563e3f3cb2ddanjn
35900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
35910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ones start at 0x2000.
35922e93c50dc50235189661b70e3f27a4098d5cccccsewardj*/
35932e93c50dc50235189661b70e3f27a4098d5cccccsewardj
35940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These macros are used by tools -- they must be public, but don't
35950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   embed them into other programs. */
3596fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_USERREQ_TOOL_BASE(a,b) \
35974c791211835f0e90cbde578187c06e563de3b023njn   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
3598fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_IS_TOOL_USERREQ(a, b, v) \
3599fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
360034042515c1715b3e0c5c0a5e0bd033e9d4858f01sewardj
36015ce4b150ce5d32c9af07a24717081ea34568388asewardj/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
36025ce4b150ce5d32c9af07a24717081ea34568388asewardj   This enum comprises an ABI exported by Valgrind to programs
36035ce4b150ce5d32c9af07a24717081ea34568388asewardj   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
36045ce4b150ce5d32c9af07a24717081ea34568388asewardj   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
3605e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjntypedef
36064c791211835f0e90cbde578187c06e563de3b023njn   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
36074c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
36083e88418f808bf2840646504481d6a5be1df16541njn
36090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These allow any function to be called from the simulated
36100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             CPU but run on the real CPU.  Nb: the first arg passed to
36110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             the function is always the ThreadId of the running
36120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             thread!  So CLIENT_CALL0 actually requires a 1 arg
3613d4795be03ad94334c7517d93d3f5b35a97c7bba0njn             function, etc. */
36144c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL0 = 0x1101,
36154c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL1 = 0x1102,
36164c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL2 = 0x1103,
36174c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL3 = 0x1104,
36183e88418f808bf2840646504481d6a5be1df16541njn
36190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* Can be useful in regression testing suites -- eg. can
36200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             send Valgrind's output to /dev/null and still count
36210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             errors. */
36224c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__COUNT_ERRORS = 0x1201,
362347363aba8fa03b094195bca99fc232ce5f85605dnjn
36243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          /* Allows a string (gdb monitor command) to be passed to the tool
36253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             Used for interaction with vgdb/gdb */
36263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
36273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
36280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These are useful and can be interpreted by any tool that
36290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             tracks malloc() et al, by using vg_replace_malloc.c. */
3630d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
3631913473803432ee37d6edaf232e21978d4f426125bart          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
3632d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
3633bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          /* Memory pool support. */
3634bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
3635bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
3636bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
3637bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
36382c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
3639c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
3640c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
3641c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
3642d799418996812817596beaa8b59563e3f3cb2ddanjn
364339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge          /* Allow printfs to valgrind log. */
3644c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* The first two pass the va_list argument by value, which
3645c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             assumes it is the same size as or smaller than a UWord,
3646c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             which generally isn't the case.  Hence are deprecated.
3647c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             The second two pass the vargs by reference and so are
3648c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             immune to this problem. */
3649c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* both :: char* fmt, va_list vargs (DEPRECATED) */
365030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn          VG_USERREQ__PRINTF           = 0x1401,
36510140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
3652c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* both :: char* fmt, va_list* vargs */
3653c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
3654c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
36550140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
36560140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          /* Stack support. */
36570140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_REGISTER   = 0x1501,
36580140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_DEREGISTER = 0x1502,
3659c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__STACK_CHANGE     = 0x1503,
3660c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
3661c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          /* Wine support */
36625c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
36635c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj
36645c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj          /* Querying of debug info. */
3665dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
3666dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
3667dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj          /* Disable/enable error reporting level.  Takes a single
3668dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             Word arg which is the delta to this thread's error
3669dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             disablement indicator.  Hence 1 disables or further
3670dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             disables errors, and -1 moves back towards enablement.
3671dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             Other values are not allowed. */
3672dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj          VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801
3673e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   } Vg_ClientRequest;
36742e93c50dc50235189661b70e3f27a4098d5cccccsewardj
36750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if !defined(__GNUC__)
36760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define __extension__ /* */
3677c9b365507e9bd5d500476e3e83f4d30f9c68a351mueller#endif
36782e93c50dc50235189661b70e3f27a4098d5cccccsewardj
3679fa5115adb77868b1ee3efc8dce061b881e7833c5bart
36800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Returns the number of Valgrinds this code is running under.  That
36810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   is, 0 if running natively, 1 if running under Valgrind, 2 if
36820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   running under Valgrind which is running under another Valgrind,
36830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   etc. */
3684fa5115adb77868b1ee3efc8dce061b881e7833c5bart#define RUNNING_ON_VALGRIND                                           \
3685575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
3686fa5115adb77868b1ee3efc8dce061b881e7833c5bart                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
3687fa5115adb77868b1ee3efc8dce061b881e7833c5bart                                    0, 0, 0, 0, 0)                    \
3688de4a1d01951937632098a6cda45859afa587a06fsewardj
3689de4a1d01951937632098a6cda45859afa587a06fsewardj
369018d7513cc08bf982711c8a22b70d56af6aa87b33sewardj/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
369118d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
369218d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   since it provides a way to make sure valgrind will retranslate the
369318d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   invalidated area.  Returns no value. */
36944b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
36954b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
36964b3a74204894e943c43cb8e8aae39d813040702csewardj                                    _qzz_addr, _qzz_len, 0, 0, 0)
369718d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
369826aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
36990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These requests are for getting Valgrind itself to print something.
3700d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   Possibly with a backtrace.  This is a really ugly hack.  The return value
3701d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   is the number of characters printed, excluding the "**<pid>** " part at the
3702d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   start and the backtrace (if present). */
37030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
370442f83fe6c64da13801d4eb54fa2aa6530679848abart#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
37057eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj/* Modern GCC will optimize the static routine out if unused,
37067eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   and unused attribute will shut down warnings about it.  */
37077eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF(const char *format, ...)
37087eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
37097f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
37107eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
37110da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
37120da2c772047f3f6795dbb43dde5f5c9b43be73bbbart__inline
37130da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
3714a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF(const char *format, ...)
371539de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
37168c7e25f496b1771f21712db0b1f35935bacfaff3bart#if defined(NVALGRIND)
37178c7e25f496b1771f21712db0b1f35935bacfaff3bart   return 0;
37188c7e25f496b1771f21712db0b1f35935bacfaff3bart#else /* NVALGRIND */
3719575ce8ef8fa86a502dabe152293320676922dcfebart#if defined(_MSC_VER)
3720575ce8ef8fa86a502dabe152293320676922dcfebart   uintptr_t _qzz_res;
3721575ce8ef8fa86a502dabe152293320676922dcfebart#else
3722c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
3723575ce8ef8fa86a502dabe152293320676922dcfebart#endif
3724c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_list vargs;
3725c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_start(vargs, format);
37260da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
3727575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
37280da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              VG_USERREQ__PRINTF_VALIST_BY_REF,
3729fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)format,
3730fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)&vargs,
37310da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              0, 0, 0);
37320da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#else
3733575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3734c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              VG_USERREQ__PRINTF_VALIST_BY_REF,
373505b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
3736c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              (unsigned long)&vargs,
37379af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
37380da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
3739c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_end(vargs);
3740c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
37418c7e25f496b1771f21712db0b1f35935bacfaff3bart#endif /* NVALGRIND */
374239de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
374339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
374442f83fe6c64da13801d4eb54fa2aa6530679848abart#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
37457eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
37467eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
37477f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
37487eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
37490da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
37500da2c772047f3f6795dbb43dde5f5c9b43be73bbbart__inline
37510da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
3752a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF_BACKTRACE(const char *format, ...)
375339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
37548c7e25f496b1771f21712db0b1f35935bacfaff3bart#if defined(NVALGRIND)
37558c7e25f496b1771f21712db0b1f35935bacfaff3bart   return 0;
37568c7e25f496b1771f21712db0b1f35935bacfaff3bart#else /* NVALGRIND */
3757575ce8ef8fa86a502dabe152293320676922dcfebart#if defined(_MSC_VER)
3758575ce8ef8fa86a502dabe152293320676922dcfebart   uintptr_t _qzz_res;
3759575ce8ef8fa86a502dabe152293320676922dcfebart#else
3760c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
3761575ce8ef8fa86a502dabe152293320676922dcfebart#endif
3762c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_list vargs;
3763c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_start(vargs, format);
37640da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
3765575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
37660da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
3767fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)format,
3768fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)&vargs,
37690da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              0, 0, 0);
37700da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#else
3771575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3772c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
377305b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
3774c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              (unsigned long)&vargs,
37759af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
37760da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
3777c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_end(vargs);
3778c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
377939de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#endif /* NVALGRIND */
37808c7e25f496b1771f21712db0b1f35935bacfaff3bart}
378118d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
37820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
37833e88418f808bf2840646504481d6a5be1df16541njn/* These requests allow control to move from the simulated CPU to the
37841319b49115bd0763628273b8a3fe08ac30712e31njn   real CPU, calling an arbitary function.
37851319b49115bd0763628273b8a3fe08ac30712e31njn
37861319b49115bd0763628273b8a3fe08ac30712e31njn   Note that the current ThreadId is inserted as the first argument.
37871319b49115bd0763628273b8a3fe08ac30712e31njn   So this call:
37881319b49115bd0763628273b8a3fe08ac30712e31njn
37891319b49115bd0763628273b8a3fe08ac30712e31njn     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
37901319b49115bd0763628273b8a3fe08ac30712e31njn
37911319b49115bd0763628273b8a3fe08ac30712e31njn   requires f to have this signature:
37921319b49115bd0763628273b8a3fe08ac30712e31njn
37931319b49115bd0763628273b8a3fe08ac30712e31njn     Word f(Word tid, Word arg1, Word arg2)
37941319b49115bd0763628273b8a3fe08ac30712e31njn
37951319b49115bd0763628273b8a3fe08ac30712e31njn   where "Word" is a word-sized type.
379645fb4d304f59e4e4cca917d372278eeb75be2c33njn
379745fb4d304f59e4e4cca917d372278eeb75be2c33njn   Note that these client requests are not entirely reliable.  For example,
379845fb4d304f59e4e4cca917d372278eeb75be2c33njn   if you call a function with them that subsequently calls printf(),
379945fb4d304f59e4e4cca917d372278eeb75be2c33njn   there's a high chance Valgrind will crash.  Generally, your prospects of
380045fb4d304f59e4e4cca917d372278eeb75be2c33njn   these working are made higher if the called function does not refer to
380145fb4d304f59e4e4cca917d372278eeb75be2c33njn   any global variables, and does not refer to any libc or other functions
380245fb4d304f59e4e4cca917d372278eeb75be2c33njn   (printf et al).  Any kind of entanglement with libc or dynamic linking is
380345fb4d304f59e4e4cca917d372278eeb75be2c33njn   likely to have a bad outcome, for tricky reasons which we've grappled
380445fb4d304f59e4e4cca917d372278eeb75be2c33njn   with a lot in the past.
38051319b49115bd0763628273b8a3fe08ac30712e31njn*/
38060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
3807575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
3808575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL0,     \
3809575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                      \
3810575ce8ef8fa86a502dabe152293320676922dcfebart                                    0, 0, 0, 0)
3811575ce8ef8fa86a502dabe152293320676922dcfebart
3812575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
3813575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
3814575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL1,          \
3815575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                           \
3816575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, 0, 0, 0)
3817575ce8ef8fa86a502dabe152293320676922dcfebart
3818575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
3819575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
3820575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL2,          \
3821575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                           \
3822575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, _qyy_arg2, 0, 0)
38233e88418f808bf2840646504481d6a5be1df16541njn
38240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
3825575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
3826575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL3,           \
3827575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                            \
3828575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, _qyy_arg2,               \
3829575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg3, 0)
38303e88418f808bf2840646504481d6a5be1df16541njn
38313e88418f808bf2840646504481d6a5be1df16541njn
38327cc9c239f785f2903b597cdb34418bed42d25331nethercote/* Counts the number of errors that have been recorded by a tool.  Nb:
38337cc9c239f785f2903b597cdb34418bed42d25331nethercote   the tool must record the errors with VG_(maybe_record_error)() or
383447363aba8fa03b094195bca99fc232ce5f85605dnjn   VG_(unique_error)() for them to be counted. */
38350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_COUNT_ERRORS                                     \
3836575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
3837575ce8ef8fa86a502dabe152293320676922dcfebart                               0 /* default return */,            \
38380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__COUNT_ERRORS,          \
3839575ce8ef8fa86a502dabe152293320676922dcfebart                               0, 0, 0, 0, 0)
384047363aba8fa03b094195bca99fc232ce5f85605dnjn
38413ac96953bf8c912a2aaa2870652dda8b9b75337bnjn/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
38423ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   when heap blocks are allocated in order to give accurate results.  This
38433ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happens automatically for the standard allocator functions such as
38443ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
38453ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   delete[], etc.
38463ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38473ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   But if your program uses a custom allocator, this doesn't automatically
38483ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happen, and Valgrind will not do as well.  For example, if you allocate
38493ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   superblocks with mmap() and then allocates chunks of the superblocks, all
38503ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind's observations will be at the mmap() level and it won't know that
38513ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   the chunks should be considered separate entities.  In Memcheck's case,
38523ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that means you probably won't get heap block overrun detection (because
38533ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   there won't be redzones marked as unaddressable) and you definitely won't
38543ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   get any leak detection.
38553ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38563ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   The following client requests allow a custom allocator to be annotated so
38573ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that it can be handled accurately by Valgrind.
38583ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38593ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
38603ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   by a malloc()-like function.  For Memcheck (an illustrative case), this
38613ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   does two things:
38623ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38633ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been allocated.  This means any addresses
38643ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     within the block mentioned in error messages will be
38653ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     identified as belonging to the block.  It also means that if the block
38663ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     isn't freed it will be detected by the leak checker.
38673ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38683ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being addressable and undefined (if 'is_zeroed' is
38693ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     not set), or addressable and defined (if 'is_zeroed' is set).  This
38703ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     controls how accesses to the block by the program are handled.
38713ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38723ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   'addr' is the start of the usable block (ie. after any
38733ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
38743ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   can apply redzones -- these are blocks of padding at the start and end of
38753ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   each block.  Adding redzones is recommended as it makes it much more likely
38763ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
38773ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroed (or filled with another predictable value), as is the case for
38783ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   calloc().
38793ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38803ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
38813ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block -- that will be used by the client program -- is allocated.
38823ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   It's best to put it at the outermost level of the allocator if possible;
38833ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   for example, if you have a function my_alloc() which calls
38843ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   internal_alloc(), and the client request is put inside internal_alloc(),
38853ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   stack traces relating to the heap block will contain entries for both
38863ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   my_alloc() and internal_alloc(), which is probably not what you want.
38873ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
3888b965efb4990bdedc3215ffcca8ea566d25874d26njn   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
3889b965efb4990bdedc3215ffcca8ea566d25874d26njn   custom blocks from within a heap block, B, that has been allocated with
3890b965efb4990bdedc3215ffcca8ea566d25874d26njn   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
3891b965efb4990bdedc3215ffcca8ea566d25874d26njn   -- the custom blocks will take precedence.
3892b965efb4990bdedc3215ffcca8ea566d25874d26njn
38933ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
38943ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Memcheck, it does two things:
38953ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38963ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been deallocated.  This assumes that the
38973ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     block was annotated as having been allocated via
38983ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
38993ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
39003ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being unaddressable.
39013ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
39023ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
39033ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block is deallocated.
39043ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
3905913473803432ee37d6edaf232e21978d4f426125bart   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
3906913473803432ee37d6edaf232e21978d4f426125bart   Memcheck, it does four things:
3907913473803432ee37d6edaf232e21978d4f426125bart
3908913473803432ee37d6edaf232e21978d4f426125bart   - It records that the size of a block has been changed.  This assumes that
3909913473803432ee37d6edaf232e21978d4f426125bart     the block was annotated as having been allocated via
3910913473803432ee37d6edaf232e21978d4f426125bart     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
3911913473803432ee37d6edaf232e21978d4f426125bart
3912913473803432ee37d6edaf232e21978d4f426125bart   - If the block shrunk, it marks the freed memory as being unaddressable.
3913913473803432ee37d6edaf232e21978d4f426125bart
3914913473803432ee37d6edaf232e21978d4f426125bart   - If the block grew, it marks the new area as undefined and defines a red
3915913473803432ee37d6edaf232e21978d4f426125bart     zone past the end of the new block.
3916913473803432ee37d6edaf232e21978d4f426125bart
3917913473803432ee37d6edaf232e21978d4f426125bart   - The V-bits of the overlap between the old and the new block are preserved.
3918913473803432ee37d6edaf232e21978d4f426125bart
3919913473803432ee37d6edaf232e21978d4f426125bart   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
3920913473803432ee37d6edaf232e21978d4f426125bart   and before deallocation of the old block.
3921913473803432ee37d6edaf232e21978d4f426125bart
3922913473803432ee37d6edaf232e21978d4f426125bart   In many cases, these three client requests will not be enough to get your
39233ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator working well with Memcheck.  More specifically, if your allocator
39243ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
39253ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   will be necessary to mark the memory as addressable just before the zeroing
39263ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   occurs, otherwise you'll get a lot of invalid write errors.  For example,
39273ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   you'll need to do this if your allocator recycles freed blocks, but it
39283ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
39293ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Alternatively, if your allocator reuses freed blocks for allocator-internal
39303ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
39313ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
39323ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Really, what's happening is a blurring of the lines between the client
39333ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
39343ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   memory should be considered unaddressable to the client program, but the
39353ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator knows more than the rest of the client program and so may be able
39363ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   to safely access it.  Extra client requests are necessary for Valgrind to
39373ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   understand the distinction between the allocator and the rest of the
39383ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program.
39393ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
394032f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
39413ac96953bf8c912a2aaa2870652dda8b9b75337bnjn*/
39424b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
39434b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
39444b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, sizeB, rzB, is_zeroed, 0)
3945d799418996812817596beaa8b59563e3f3cb2ddanjn
394632f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
394732f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
394832f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn*/
39494b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
39504b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
39514b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, oldSizeB, newSizeB, rzB, 0)
3952913473803432ee37d6edaf232e21978d4f426125bart
3953913473803432ee37d6edaf232e21978d4f426125bart/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
3954913473803432ee37d6edaf232e21978d4f426125bart   Ignored if addr == 0.
3955913473803432ee37d6edaf232e21978d4f426125bart*/
39564b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
39574b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
39584b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, rzB, 0, 0, 0)
3959d799418996812817596beaa8b59563e3f3cb2ddanjn
3960bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Create a memory pool. */
39610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
39624b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
39634b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, rzB, is_zeroed, 0, 0)
3964bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3965bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Destroy a memory pool. */
39660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
39674b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
39684b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, 0, 0, 0, 0)
3969bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3970bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Associate a piece of memory with a memory pool. */
39710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
39724b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
39734b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, size, 0, 0)
3974bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3975bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Disassociate a piece of memory from a memory pool. */
39760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
39774b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
39784b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, 0, 0, 0)
3979bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
39802c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj/* Disassociate any pieces outside a particular range. */
39812c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
39824b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
39834b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, size, 0, 0)
39842c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj
3985c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
3986c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
39874b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
39884b3a74204894e943c43cb8e8aae39d813040702csewardj                                    poolA, poolB, 0, 0, 0)
3989c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
3990c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
3991c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
39924b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
39934b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addrA, addrB, size, 0)
3994c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
3995c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Return 1 if a mempool exists, else 0. */
3996c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
3997575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
3998c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_EXISTS,        \
3999575ce8ef8fa86a502dabe152293320676922dcfebart                               pool, 0, 0, 0, 0)
4000c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
40010140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Mark a piece of memory as being a stack. Returns a stack id. */
40020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_REGISTER(start, end)                       \
4003575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
40040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_REGISTER,        \
4005575ce8ef8fa86a502dabe152293320676922dcfebart                               start, end, 0, 0, 0)
40060140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
40070140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Unmark the piece of memory associated with a stack id as being a
40080140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   stack. */
40090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_DEREGISTER(id)                             \
40104b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
40114b3a74204894e943c43cb8e8aae39d813040702csewardj                                    id, 0, 0, 0, 0)
40120140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
40130140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Change the start and end address of the stack id. */
40140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_CHANGE(id, start, end)                     \
40154b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
40164b3a74204894e943c43cb8e8aae39d813040702csewardj                                    id, start, end, 0, 0)
40170140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
4018c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* Load PDB debug info for Wine PE image_map. */
40194b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
40204b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
40214b3a74204894e943c43cb8e8aae39d813040702csewardj                                    fd, ptr, total_size, delta, 0)
4022c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
40235c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj/* Map a code address to a source file name and line number.  buf64
40245c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   must point to a 64-byte buffer in the caller's address space.  The
40255c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   result will be dumped in there and is guaranteed to be zero
40265c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   terminated.  If no info is found, the first byte is set to zero. */
40275c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
4028575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
40295c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
4030575ce8ef8fa86a502dabe152293320676922dcfebart                               addr, buf64, 0, 0, 0)
40315c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj
4032dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj/* Disable error reporting for this thread.  Behaves in a stack like
4033dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   way, so you can safely call this multiple times provided that
4034dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
4035dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   to re-enable reporting.  The first call of this macro disables
4036dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   reporting.  Subsequent calls have no effect except to increase the
4037dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
4038dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   reporting.  Child threads do not inherit this setting from their
4039dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   parents -- they are always created with reporting enabled. */
404006e9bf06cf953602adaf5e2a0a3f5522e4dc7f50bart#define VALGRIND_DISABLE_ERROR_REPORTING                                \
40414b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
40424b3a74204894e943c43cb8e8aae39d813040702csewardj                                    1, 0, 0, 0, 0)
4043dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
4044dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj/* Re-enable error reporting, as per comments on
4045dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   VALGRIND_DISABLE_ERROR_REPORTING. */
404606e9bf06cf953602adaf5e2a0a3f5522e4dc7f50bart#define VALGRIND_ENABLE_ERROR_REPORTING                                 \
40474b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
40484b3a74204894e943c43cb8e8aae39d813040702csewardj                                    -1, 0, 0, 0, 0)
40490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4050c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_x86_darwin
4051c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_amd64_darwin
4052c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_x86_win32
4053f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
4054f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
4055f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
4056f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
405759570ffbe31930ab4d678754daaeec0715117a3dsewardj#undef PLAT_arm_linux
4058b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#undef PLAT_s390x_linux
40590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
40603e88418f808bf2840646504481d6a5be1df16541njn#endif   /* __VALGRIND_H */
4061