valgrind.h revision bb913cd4cc1e56d7d7798a8b754361a05d01f916
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
1503f8d3fc25f5a45c5826259d1b33b7f310117279sewardj   Copyright (C) 2000-2012 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
927d79e0b97af18baed7ab6b12a363538974d3775asewardj#define __VALGRIND_MINOR__    8
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
1205db15403e889d4db339b342bc2a824ef0bfaa654sewardj#undef PLAT_mips32_linux
121b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
122f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
1236e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if defined(__APPLE__) && defined(__i386__)
124f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_x86_darwin 1
125f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__x86_64__)
126f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_amd64_darwin 1
1276e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#elif defined(__MINGW32__) || defined(__CYGWIN32__) \
1286e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj      || (defined(_WIN32) && defined(_M_IX86))
1297f489813d200fb614a0856fca05e2f9ebf66dd48bart#  define PLAT_x86_win32 1
13059570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__i386__)
131f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_x86_linux 1
13259570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__x86_64__)
133f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_amd64_linux 1
13459570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
135f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc32_linux 1
13659570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
137f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc64_linux 1
13859570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__arm__)
13959570ffbe31930ab4d678754daaeec0715117a3dsewardj#  define PLAT_arm_linux 1
140b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
141b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define PLAT_s390x_linux 1
1425db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(__linux__) && defined(__mips__)
1435db15403e889d4db339b342bc2a824ef0bfaa654sewardj#  define PLAT_mips32_linux 1
144f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else
145f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* If we're not compiling for our target platform, don't generate
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   any inline asms.  */
1470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  if !defined(NVALGRIND)
1480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#    define NVALGRIND 1
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  endif
150b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#endif
151b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
15330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
1540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
1550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* in here of use to end-users -- skip to the next section.           */
15630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
157de4a1d01951937632098a6cda45859afa587a06fsewardj
158575ce8ef8fa86a502dabe152293320676922dcfebart/*
159575ce8ef8fa86a502dabe152293320676922dcfebart * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
160575ce8ef8fa86a502dabe152293320676922dcfebart * request. Accepts both pointers and integers as arguments.
161575ce8ef8fa86a502dabe152293320676922dcfebart *
1624b3a74204894e943c43cb8e8aae39d813040702csewardj * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
1634b3a74204894e943c43cb8e8aae39d813040702csewardj * client request that does not return a value.
1644b3a74204894e943c43cb8e8aae39d813040702csewardj
165575ce8ef8fa86a502dabe152293320676922dcfebart * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
1664b3a74204894e943c43cb8e8aae39d813040702csewardj * client request and whose value equals the client request result.  Accepts
1674b3a74204894e943c43cb8e8aae39d813040702csewardj * both pointers and integers as arguments.  Note that such calls are not
1684b3a74204894e943c43cb8e8aae39d813040702csewardj * necessarily pure functions -- they may have side effects.
169575ce8ef8fa86a502dabe152293320676922dcfebart */
170575ce8ef8fa86a502dabe152293320676922dcfebart
171575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
172575ce8ef8fa86a502dabe152293320676922dcfebart                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
173575ce8ef8fa86a502dabe152293320676922dcfebart                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
17417dfe1addc98de357b9e24ddbe4ad7df4454873aflorian  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
175575ce8ef8fa86a502dabe152293320676922dcfebart                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
17617dfe1addc98de357b9e24ddbe4ad7df4454873aflorian                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
177575ce8ef8fa86a502dabe152293320676922dcfebart
1784b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
1794b3a74204894e943c43cb8e8aae39d813040702csewardj                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
1804b3a74204894e943c43cb8e8aae39d813040702csewardj  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
1814b3a74204894e943c43cb8e8aae39d813040702csewardj                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
1824b3a74204894e943c43cb8e8aae39d813040702csewardj                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
1834b3a74204894e943c43cb8e8aae39d813040702csewardj
1840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
18526aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
18626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn/* Define NVALGRIND to completely remove the Valgrind magic sequence
1870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   from the compiled code (analogous to NDEBUG's effects on
1880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   assert()) */
189575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
190575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
1919af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
192575ce8ef8fa86a502dabe152293320676922dcfebart      (_zzq_default)
19326aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#else  /* ! NVALGRIND */
1950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* The following defines the magic code sequences which the JITter
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   spots and handles magically.  Don't look too closely at them as
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   they will rot your brain.
199de4a1d01951937632098a6cda45859afa587a06fsewardj
2000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The assembly code sequences for all architectures is in this one
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   file.  This is because this file must be stand-alone, and we don't
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   want to have multiple files.
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
2050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   value gets put in the return slot, so that everything works when
2060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   this is executed not under Valgrind.  Args are passed in a memory
2070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   block, and so there's no intrinsic limit to the number that could
2089af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj   be passed, but it's currently five.
209e90c6836fd430124799e52896c99ea27b1c88541nethercote
2105426544c9c3fc835ead99fae9e2054625110ef3enethercote   The macro args are:
2115426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_rlval    result lvalue
2125426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_default  default value (result returned when running on real CPU)
2135426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_request  request code
2149af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      _zzq_arg1..5  request params
2155426544c9c3fc835ead99fae9e2054625110ef3enethercote
2160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The other two macros are used to support function wrapping, and are
217d68ac3e974d25f88492774f6baa491999afde9f9sewardj   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
218d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest's NRADDR pseudo-register and whatever other information is
219d68ac3e974d25f88492774f6baa491999afde9f9sewardj   needed to safely run the call original from the wrapper: on
220d68ac3e974d25f88492774f6baa491999afde9f9sewardj   ppc64-linux, the R2 value at the divert point is also needed.  This
221d68ac3e974d25f88492774f6baa491999afde9f9sewardj   information is abstracted into a user-visible type, OrigFn.
222d68ac3e974d25f88492774f6baa491999afde9f9sewardj
223d68ac3e974d25f88492774f6baa491999afde9f9sewardj   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
224d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest, but guarantees that the branch instruction will not be
225d68ac3e974d25f88492774f6baa491999afde9f9sewardj   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
226d68ac3e974d25f88492774f6baa491999afde9f9sewardj   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
227d68ac3e974d25f88492774f6baa491999afde9f9sewardj   complete inline asm, since it needs to be combined with more magic
228d68ac3e974d25f88492774f6baa491999afde9f9sewardj   inline asm stuff to be useful.
229e90c6836fd430124799e52896c99ea27b1c88541nethercote*/
230de4a1d01951937632098a6cda45859afa587a06fsewardj
231f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
2320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
233520a03a4c59703908bae4cc437814abf0a24cdcdsewardj#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
234602278444fa6b4135a44d19ae833ed42a9898e48sewardj    ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
235c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
236c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
237c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
238c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
239c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
240c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
241c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
2420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
2441a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "roll $29, %%edi ; roll $19, %%edi\n\t"
2450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
246575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
247575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
2489af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
249575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
250575ce8ef8fa86a502dabe152293320676922dcfebart  ({volatile unsigned int _zzq_args[6];                           \
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned int _zzq_result;                            \
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
2530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
2540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
2579af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EDX = client_request ( %EAX ) */         \
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ebx,%%ebx"                          \
2610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
265575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
266575ce8ef8fa86a502dabe152293320676922dcfebart  })
2670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
268c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
269c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
270c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned int __addr;                                 \
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EAX = guest_NRADDR */                    \
2730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ecx,%%ecx"                          \
2740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
278c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
279ca0518df66f8c3375a860f1a55a51f18e2a16c44njn  }
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_EAX                                 \
2820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%EAX */                     \
2840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%edx,%%edx\n\t"
285bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
286bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
287bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
288bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
289bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "xchgl %%edi,%%edi\n\t"                     \
290bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     : : : "cc", "memory"                        \
291bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                    );                                           \
292bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
293bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
294602278444fa6b4135a44d19ae833ed42a9898e48sewardj#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
2957f489813d200fb614a0856fca05e2f9ebf66dd48bart
2967f489813d200fb614a0856fca05e2f9ebf66dd48bart/* ------------------------- x86-Win32 ------------------------- */
2977f489813d200fb614a0856fca05e2f9ebf66dd48bart
2987f489813d200fb614a0856fca05e2f9ebf66dd48bart#if defined(PLAT_x86_win32) && !defined(__GNUC__)
2997f489813d200fb614a0856fca05e2f9ebf66dd48bart
3007f489813d200fb614a0856fca05e2f9ebf66dd48barttypedef
3017f489813d200fb614a0856fca05e2f9ebf66dd48bart   struct {
3027f489813d200fb614a0856fca05e2f9ebf66dd48bart      unsigned int nraddr; /* where's the code? */
3037f489813d200fb614a0856fca05e2f9ebf66dd48bart   }
3047f489813d200fb614a0856fca05e2f9ebf66dd48bart   OrigFn;
3057f489813d200fb614a0856fca05e2f9ebf66dd48bart
3067f489813d200fb614a0856fca05e2f9ebf66dd48bart#if defined(_MSC_VER)
3077f489813d200fb614a0856fca05e2f9ebf66dd48bart
3087f489813d200fb614a0856fca05e2f9ebf66dd48bart#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3097f489813d200fb614a0856fca05e2f9ebf66dd48bart                     __asm rol edi, 3  __asm rol edi, 13          \
3107f489813d200fb614a0856fca05e2f9ebf66dd48bart                     __asm rol edi, 29 __asm rol edi, 19
3117f489813d200fb614a0856fca05e2f9ebf66dd48bart
312575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
313575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
3147f489813d200fb614a0856fca05e2f9ebf66dd48bart        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
315575ce8ef8fa86a502dabe152293320676922dcfebart    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
316575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
317575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
318575ce8ef8fa86a502dabe152293320676922dcfebart        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
319575ce8ef8fa86a502dabe152293320676922dcfebart
320575ce8ef8fa86a502dabe152293320676922dcfebartstatic __inline uintptr_t
321575ce8ef8fa86a502dabe152293320676922dcfebartvalgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
322575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
323575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
324575ce8ef8fa86a502dabe152293320676922dcfebart                                uintptr_t _zzq_arg5)
325575ce8ef8fa86a502dabe152293320676922dcfebart{
326575ce8ef8fa86a502dabe152293320676922dcfebart    volatile uintptr_t _zzq_args[6];
327575ce8ef8fa86a502dabe152293320676922dcfebart    volatile unsigned int _zzq_result;
328575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[0] = (uintptr_t)(_zzq_request);
329575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
330575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
331575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
332575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
333575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
334575ce8ef8fa86a502dabe152293320676922dcfebart    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
335575ce8ef8fa86a502dabe152293320676922dcfebart            __SPECIAL_INSTRUCTION_PREAMBLE
336575ce8ef8fa86a502dabe152293320676922dcfebart            /* %EDX = client_request ( %EAX ) */
337575ce8ef8fa86a502dabe152293320676922dcfebart            __asm xchg ebx,ebx
338575ce8ef8fa86a502dabe152293320676922dcfebart            __asm mov _zzq_result, edx
339575ce8ef8fa86a502dabe152293320676922dcfebart    }
340575ce8ef8fa86a502dabe152293320676922dcfebart    return _zzq_result;
341575ce8ef8fa86a502dabe152293320676922dcfebart}
3427f489813d200fb614a0856fca05e2f9ebf66dd48bart
3437f489813d200fb614a0856fca05e2f9ebf66dd48bart#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
3447f489813d200fb614a0856fca05e2f9ebf66dd48bart  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
3457f489813d200fb614a0856fca05e2f9ebf66dd48bart    volatile unsigned int __addr;                                 \
3467f489813d200fb614a0856fca05e2f9ebf66dd48bart    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
3477f489813d200fb614a0856fca05e2f9ebf66dd48bart            /* %EAX = guest_NRADDR */                             \
3487f489813d200fb614a0856fca05e2f9ebf66dd48bart            __asm xchg ecx,ecx                                    \
3497f489813d200fb614a0856fca05e2f9ebf66dd48bart            __asm mov __addr, eax                                 \
3507f489813d200fb614a0856fca05e2f9ebf66dd48bart    }                                                             \
3517f489813d200fb614a0856fca05e2f9ebf66dd48bart    _zzq_orig->nraddr = __addr;                                   \
3527f489813d200fb614a0856fca05e2f9ebf66dd48bart  }
3537f489813d200fb614a0856fca05e2f9ebf66dd48bart
3547f489813d200fb614a0856fca05e2f9ebf66dd48bart#define VALGRIND_CALL_NOREDIR_EAX ERROR
3557f489813d200fb614a0856fca05e2f9ebf66dd48bart
356bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
357bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
358bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                       \
359bb913cd4cc1e56d7d7798a8b754361a05d01f916florian            __asm xchg edi,edi                                   \
360bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    }                                                            \
361bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
362bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
3637f489813d200fb614a0856fca05e2f9ebf66dd48bart#else
3647f489813d200fb614a0856fca05e2f9ebf66dd48bart#error Unsupported compiler.
3657f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
3667f489813d200fb614a0856fca05e2f9ebf66dd48bart
3677f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif /* PLAT_x86_win32 */
3680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
369f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
3700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
371f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
372c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
373c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
374c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
375c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned long long int nraddr; /* where's the code? */
376c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
377c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
378c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
3790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
3811a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
3820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
383575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
384575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
3859af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
386575ce8ef8fa86a502dabe152293320676922dcfebart    __extension__                                                 \
387575ce8ef8fa86a502dabe152293320676922dcfebart    ({ volatile unsigned long long int _zzq_args[6];              \
3880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned long long int _zzq_result;                  \
3890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
3900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
3910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
3920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
3930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
3949af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
3950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RDX = client_request ( %RAX ) */         \
3970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rbx,%%rbx"                          \
3980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
3990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
4000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
4010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
402575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
403575ce8ef8fa86a502dabe152293320676922dcfebart    })
4040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
405c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
406c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
407c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned long long int __addr;                       \
4080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
4090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RAX = guest_NRADDR */                    \
4100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rcx,%%rcx"                          \
4110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
4120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
4130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
4140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
415c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
4162c48c7b0a453d32375a4df17e153011b797ef28csewardj  }
4170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_RAX                                 \
4190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%RAX */                     \
4210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rdx,%%rdx\n\t"
422bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
423bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
424bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
425bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
426bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "xchgq %%rdi,%%rdi\n\t"                     \
427bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     : : : "cc", "memory"                        \
428bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                    );                                           \
429bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
430bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
431f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
4320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
433f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
4340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
435f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
436d68ac3e974d25f88492774f6baa491999afde9f9sewardj
437d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
438d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
439c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
440d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
441d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
442d68ac3e974d25f88492774f6baa491999afde9f9sewardj
4430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
4440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
4451a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
4460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
447575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
448575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
4499af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
4500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
451575ce8ef8fa86a502dabe152293320676922dcfebart    __extension__                                                 \
452575ce8ef8fa86a502dabe152293320676922dcfebart  ({         unsigned int  _zzq_args[6];                          \
4531c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int  _zzq_result;                           \
4541c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int* _zzq_ptr;                              \
4550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
4560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
4570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
4580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
4590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
4609af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
4610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
4621c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
4631c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
4641c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = client_request ( %R4 ) */           \
4661c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 1,1,1\n\t"                               \
4671c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"     /*result*/                     \
4681c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (_zzq_result)                         \
4691c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
4701c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3", "r4");               \
471575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
472575ce8ef8fa86a502dabe152293320676922dcfebart    })
4730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
474d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
475d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
4761c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    unsigned int __addr;                                          \
4770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
4780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = guest_NRADDR */                     \
4791c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 2,2,2\n\t"                               \
4801c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"                                    \
4811c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (__addr)                              \
4820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
4831c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3"                       \
4840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
485d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
4860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
4870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
4890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* branch-and-link-to-noredir *%R11 */       \
4910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "or 3,3,3\n\t"
492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
4930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
4950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
497d68ac3e974d25f88492774f6baa491999afde9f9sewardj
498d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
499d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
500d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int nraddr; /* where's the code? */
501d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int r2;  /* what tocptr do we need? */
502d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
503d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
504d68ac3e974d25f88492774f6baa491999afde9f9sewardj
5051a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
5061a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
5071a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
5081a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
509575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
510575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
5119af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
5120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
513575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
514575ce8ef8fa86a502dabe152293320676922dcfebart  ({         unsigned long long int  _zzq_args[6];                \
5158258a3a849f8bf47146ff1740d2dac429bb453a5sewardj             unsigned long long int  _zzq_result;                 \
5168258a3a849f8bf47146ff1740d2dac429bb453a5sewardj             unsigned long long int* _zzq_ptr;                    \
5171a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
5181a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
5191a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
5201a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
5211a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
5229af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
5230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
5248258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
5258258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
5268258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
5271a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = client_request ( %R4 ) */           \
5288258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 1,1,1\n\t"                               \
5298258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"     /*result*/                     \
5308258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (_zzq_result)                         \
5318258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
5328258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3", "r4");               \
533575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
534575ce8ef8fa86a502dabe152293320676922dcfebart  })
5351a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
536d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
537d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
5388258a3a849f8bf47146ff1740d2dac429bb453a5sewardj    unsigned long long int __addr;                                \
5391a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
5401a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = guest_NRADDR */                     \
5418258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 2,2,2\n\t"                               \
5428258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"                                    \
5438258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (__addr)                              \
5441a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     :                                            \
5458258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3"                       \
5461a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                    );                                            \
547d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
548d68ac3e974d25f88492774f6baa491999afde9f9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
549d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
5508258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "or 4,4,4\n\t"                               \
5518258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     "mr %0,3"                                    \
5528258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "=b" (__addr)                              \
553d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     :                                            \
5548258a3a849f8bf47146ff1740d2dac429bb453a5sewardj                     : "cc", "memory", "r3"                       \
555d68ac3e974d25f88492774f6baa491999afde9f9sewardj                    );                                            \
556d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->r2 = __addr;                                       \
5570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
5581a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
5591a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
5601a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
5611a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* branch-and-link-to-noredir *%R11 */       \
5621a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 3,3,3\n\t"
5631a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
564bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
565bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
566bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
567bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "or 5,5,5\n\t"                              \
568bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                    );                                           \
569bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
570bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
571f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
572f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
57359570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
57459570ffbe31930ab4d678754daaeec0715117a3dsewardj
57559570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
57659570ffbe31930ab4d678754daaeec0715117a3dsewardj
57759570ffbe31930ab4d678754daaeec0715117a3dsewardjtypedef
57859570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct {
57959570ffbe31930ab4d678754daaeec0715117a3dsewardj      unsigned int nraddr; /* where's the code? */
58059570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
58159570ffbe31930ab4d678754daaeec0715117a3dsewardj   OrigFn;
58259570ffbe31930ab4d678754daaeec0715117a3dsewardj
58359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
58459570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
58559570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
58659570ffbe31930ab4d678754daaeec0715117a3dsewardj
587575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
588575ce8ef8fa86a502dabe152293320676922dcfebart        _zzq_default, _zzq_request,                               \
58959570ffbe31930ab4d678754daaeec0715117a3dsewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
59059570ffbe31930ab4d678754daaeec0715117a3dsewardj                                                                  \
591575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                   \
592575ce8ef8fa86a502dabe152293320676922dcfebart  ({volatile unsigned int  _zzq_args[6];                          \
59359570ffbe31930ab4d678754daaeec0715117a3dsewardj    volatile unsigned int  _zzq_result;                           \
59459570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
59559570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
59659570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
59759570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
59859570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
59959570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
60059570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
60159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov r4, %2\n\t" /*ptr*/                     \
60259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
60359570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = client_request ( R4 ) */             \
60459570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r10, r10, r10\n\t"                      \
60559570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"     /*result*/                  \
60659570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (_zzq_result)                         \
60759570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
60859570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc","memory", "r3", "r4");                \
609575ce8ef8fa86a502dabe152293320676922dcfebart    _zzq_result;                                                  \
610575ce8ef8fa86a502dabe152293320676922dcfebart  })
61159570ffbe31930ab4d678754daaeec0715117a3dsewardj
61259570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
61359570ffbe31930ab4d678754daaeec0715117a3dsewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
61459570ffbe31930ab4d678754daaeec0715117a3dsewardj    unsigned int __addr;                                          \
61559570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
61659570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = guest_NRADDR */                      \
61759570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r11, r11, r11\n\t"                      \
61859570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"                                 \
61959570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (__addr)                              \
62059570ffbe31930ab4d678754daaeec0715117a3dsewardj                     :                                            \
62159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc", "memory", "r3"                       \
62259570ffbe31930ab4d678754daaeec0715117a3dsewardj                    );                                            \
62359570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_orig->nraddr = __addr;                                   \
62459570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
62559570ffbe31930ab4d678754daaeec0715117a3dsewardj
62659570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
62759570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
62859570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* branch-and-link-to-noredir *%R4 */        \
62959570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r12, r12, r12\n\t"
63059570ffbe31930ab4d678754daaeec0715117a3dsewardj
631bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
632bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
633bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
634bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "orr r13, r13, r13\n\t"                     \
635bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     : : : "cc", "memory"                        \
636bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                    );                                           \
637bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
638bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
63959570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
64059570ffbe31930ab4d678754daaeec0715117a3dsewardj
641b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* ------------------------ s390x-linux ------------------------ */
642b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
643b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(PLAT_s390x_linux)
644b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
645b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjtypedef
646b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  struct {
647b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj     unsigned long long int nraddr; /* where's the code? */
648b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  }
649b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj  OrigFn;
650b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
651b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
652b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * code. This detection is implemented in platform specific toIR.c
653b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * (e.g. VEX/priv/guest_s390_decoder.c).
654b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj */
655b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
656b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 15,15\n\t"                              \
657b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 1,1\n\t"                                \
658b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 2,2\n\t"                                \
659b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     "lr 3,3\n\t"
660b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
661b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
662b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
663b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
664bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define __VEX_INJECT_IR_CODE  "lr 5,5\n\t"
665b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
666575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
667575ce8ef8fa86a502dabe152293320676922dcfebart       _zzq_default, _zzq_request,                               \
668b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
669575ce8ef8fa86a502dabe152293320676922dcfebart  __extension__                                                  \
670575ce8ef8fa86a502dabe152293320676922dcfebart ({volatile unsigned long long int _zzq_args[6];                 \
671b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   volatile unsigned long long int _zzq_result;                  \
672b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
673b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
674b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
675b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
676b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
677b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
678b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   __asm__ volatile(/* r2 = args */                              \
679b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr 2,%1\n\t"                               \
680b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    /* r3 = default */                           \
681b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr 3,%2\n\t"                               \
682b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __SPECIAL_INSTRUCTION_PREAMBLE               \
683b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __CLIENT_REQUEST_CODE                        \
684b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    /* results = r3 */                           \
685b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr %0, 3\n\t"                              \
686b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "=d" (_zzq_result)                         \
687b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
688b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "cc", "2", "3", "memory"                   \
689b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                   );                                            \
690575ce8ef8fa86a502dabe152293320676922dcfebart   _zzq_result;                                                  \
691575ce8ef8fa86a502dabe152293320676922dcfebart })
692b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
693b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
694b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
695b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   volatile unsigned long long int __addr;                       \
696b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
697b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __GET_NR_CONTEXT_CODE                        \
698b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    "lgr %0, 3\n\t"                              \
699b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "=a" (__addr)                              \
700b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    :                                            \
701b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    : "cc", "3", "memory"                        \
702b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                   );                                            \
703b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   _zzq_orig->nraddr = __addr;                                   \
704b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj }
705b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
706b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define VALGRIND_CALL_NOREDIR_R1                                 \
707b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __SPECIAL_INSTRUCTION_PREAMBLE               \
708b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                    __CALL_NO_REDIR_CODE
709b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
710bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
711bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
712bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
713bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     __VEX_INJECT_IR_CODE);                      \
714bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
715bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
716b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif /* PLAT_s390x_linux */
717b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
7185db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* ------------------------- mips32-linux ---------------- */
7195db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7205db15403e889d4db339b342bc2a824ef0bfaa654sewardj#if defined(PLAT_mips32_linux)
7215db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7225db15403e889d4db339b342bc2a824ef0bfaa654sewardjtypedef
7235db15403e889d4db339b342bc2a824ef0bfaa654sewardj   struct {
7245db15403e889d4db339b342bc2a824ef0bfaa654sewardj      unsigned int nraddr; /* where's the code? */
7255db15403e889d4db339b342bc2a824ef0bfaa654sewardj   }
7265db15403e889d4db339b342bc2a824ef0bfaa654sewardj   OrigFn;
7275db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7285db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* .word  0x342
7295db15403e889d4db339b342bc2a824ef0bfaa654sewardj * .word  0x742
7305db15403e889d4db339b342bc2a824ef0bfaa654sewardj * .word  0xC2
7315db15403e889d4db339b342bc2a824ef0bfaa654sewardj * .word  0x4C2*/
7325db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE          \
7335db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "srl $0, $0, 13\n\t"       \
7345db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "srl $0, $0, 29\n\t"       \
7355db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "srl $0, $0, 3\n\t"        \
7365db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "srl $0, $0, 19\n\t"
7375db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7385db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
7395db15403e889d4db339b342bc2a824ef0bfaa654sewardj       _zzq_default, _zzq_request,                                \
7405db15403e889d4db339b342bc2a824ef0bfaa654sewardj       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
7415db15403e889d4db339b342bc2a824ef0bfaa654sewardj  __extension__                                                   \
7425db15403e889d4db339b342bc2a824ef0bfaa654sewardj  ({ volatile unsigned int _zzq_args[6];                          \
7435db15403e889d4db339b342bc2a824ef0bfaa654sewardj    volatile unsigned int _zzq_result;                            \
7445db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
7455db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
7465db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
7475db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
7485db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
7495db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
7505db15403e889d4db339b342bc2a824ef0bfaa654sewardj        __asm__ volatile("move $11, %1\n\t" /*default*/           \
7515db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "move $12, %2\n\t" /*ptr*/                   \
7525db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
7535db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     /* T3 = client_request ( T4 ) */             \
7545db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "or $13, $13, $13\n\t"                       \
7555db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "move %0, $11\n\t"     /*result*/            \
7565db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     : "=r" (_zzq_result)                         \
7575db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
7585db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     : "cc","memory", "t3", "t4");                \
7595db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_result;                                                  \
7605db15403e889d4db339b342bc2a824ef0bfaa654sewardj  })
7615db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7625db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
7635db15403e889d4db339b342bc2a824ef0bfaa654sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
7645db15403e889d4db339b342bc2a824ef0bfaa654sewardj    volatile unsigned int __addr;                                 \
7655db15403e889d4db339b342bc2a824ef0bfaa654sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
7665db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     /* %t9 = guest_NRADDR */                     \
7675db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "or $14, $14, $14\n\t"                       \
7685db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     "move %0, $11"     /*result*/                \
7695db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     : "=r" (__addr)                              \
7705db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     :                                            \
7715db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     : "cc", "memory" , "t3"                      \
7725db15403e889d4db339b342bc2a824ef0bfaa654sewardj                    );                                            \
7735db15403e889d4db339b342bc2a824ef0bfaa654sewardj    _zzq_orig->nraddr = __addr;                                   \
7745db15403e889d4db339b342bc2a824ef0bfaa654sewardj  }
7755db15403e889d4db339b342bc2a824ef0bfaa654sewardj
7765db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define VALGRIND_CALL_NOREDIR_T9                                 \
7775db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE              \
7785db15403e889d4db339b342bc2a824ef0bfaa654sewardj                     /* call-noredir *%t9 */                     \
779bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "or $15, $15, $15\n\t"
780bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
781bb913cd4cc1e56d7d7798a8b754361a05d01f916florian#define VALGRIND_VEX_INJECT_IR()                                 \
782bb913cd4cc1e56d7d7798a8b754361a05d01f916florian do {                                                            \
783bb913cd4cc1e56d7d7798a8b754361a05d01f916florian    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
784bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                     "or $11, $11, $11\n\t"                      \
785bb913cd4cc1e56d7d7798a8b754361a05d01f916florian                    );                                           \
786bb913cd4cc1e56d7d7798a8b754361a05d01f916florian } while (0)
787bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
788bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
7895db15403e889d4db339b342bc2a824ef0bfaa654sewardj#endif /* PLAT_mips32_linux */
7905db15403e889d4db339b342bc2a824ef0bfaa654sewardj
791f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Insert assembly code for other platforms here... */
79226aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
79337091fb739760631f436043c47de612cf9fd2dd1sewardj#endif /* NVALGRIND */
7942e93c50dc50235189661b70e3f27a4098d5cccccsewardj
79569d9c4625034b60c08e04cc246fcf8093d23fde5nethercote
79630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
797f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ugly.  It's the least-worst tradeoff I can think of.               */
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
8000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* This section defines magic (a.k.a appalling-hack) macros for doing
8020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   guaranteed-no-redirection macros, so as to get from function
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   wrappers to the functions they are wrapping.  The whole point is to
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   construct standard call sequences, but to do the call itself with a
8050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   special no-redirect call pseudo-instruction that the JIT
8060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   understands and handles specially.  This section is long and
8070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   repetitious, and I can't see a way to make it shorter.
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The naming scheme is as follows:
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
8120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   'W' stands for "word" and 'v' for "void".  Hence there are
8140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   and for each, the possibility of returning a word-typed result, or
8160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   no result.
8170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj*/
8180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Use these to write the name of your wrapper.  NOTE: duplicates
82085cf90056b7a8d98d88335b47c599a35b35ff7casewardj   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
82185cf90056b7a8d98d88335b47c599a35b35ff7casewardj   the default behaviour equivalance class tag "0000" into the name.
82285cf90056b7a8d98d88335b47c599a35b35ff7casewardj   See pub_tool_redir.h for details -- normally you don't need to
82385cf90056b7a8d98d88335b47c599a35b35ff7casewardj   think about this, though. */
8240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8255f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn/* Use an extra level of macroisation so as to ensure the soname/fnname
8265f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   args are fully macro-expanded before pasting them together. */
8275f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
8285f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
8290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
83096044842731e581702c9ed4104d2949fcde20fd8sewardj   VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
8310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
83396044842731e581702c9ed4104d2949fcde20fd8sewardj   VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
8340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
835d68ac3e974d25f88492774f6baa491999afde9f9sewardj/* Use this macro from within a wrapper function to collect the
836d68ac3e974d25f88492774f6baa491999afde9f9sewardj   context (address and possibly other info) of the original function.
837d68ac3e974d25f88492774f6baa491999afde9f9sewardj   Once you have that you can then use it in one of the CALL_FN_
838d68ac3e974d25f88492774f6baa491999afde9f9sewardj   macros.  The type of the argument _lval is OrigFn. */
839d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
841573f8bc106cf3646bdb62748820287c9c44bd432sewardj/* Also provide end-user facilities for function replacement, rather
842573f8bc106cf3646bdb62748820287c9c44bd432sewardj   than wrapping.  A replacement function differs from a wrapper in
843573f8bc106cf3646bdb62748820287c9c44bd432sewardj   that it has no way to get hold of the original function being
844573f8bc106cf3646bdb62748820287c9c44bd432sewardj   called, and hence no way to call onwards to it.  In a replacement
845573f8bc106cf3646bdb62748820287c9c44bd432sewardj   function, VALGRIND_GET_ORIG_FN always returns zero. */
846573f8bc106cf3646bdb62748820287c9c44bd432sewardj
847573f8bc106cf3646bdb62748820287c9c44bd432sewardj#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
848573f8bc106cf3646bdb62748820287c9c44bd432sewardj   VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
849573f8bc106cf3646bdb62748820287c9c44bd432sewardj
850573f8bc106cf3646bdb62748820287c9c44bd432sewardj#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
851573f8bc106cf3646bdb62748820287c9c44bd432sewardj   VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
852573f8bc106cf3646bdb62748820287c9c44bd432sewardj
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Derivatives of the main macros below, for calling functions
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   returning void. */
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_v(fnptr)                                        \
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_v(_junk,fnptr); } while (0)
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_W(fnptr, arg1)                                  \
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8685ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
8695ce4b150ce5d32c9af07a24717081ea34568388asewardj   do { volatile unsigned long _junk;                             \
8705ce4b150ce5d32c9af07a24717081ea34568388asewardj        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
8715ce4b150ce5d32c9af07a24717081ea34568388asewardj
8722b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
8732b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
8742b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
8752b5f0a90334a2271791c110548a842fadb5ffc65njn
8762b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
8772b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
8782b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
8792b5f0a90334a2271791c110548a842fadb5ffc65njn
8802b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
8812b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
8822b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
8832b5f0a90334a2271791c110548a842fadb5ffc65njn
8842b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
8852b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
8862b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
8872b5f0a90334a2271791c110548a842fadb5ffc65njn
888f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
8890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
890f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
8910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call.  No need to mention eax
8930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   as gcc can already see that, plus causes gcc to bomb. */
8940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
8950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom/* Macros to save and align the stack before making a function
8974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   call and restore it afterwards as gcc may not keep the stack
8984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   pointer aligned if it doesn't realise calls are being made
8994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   to other functions. */
9004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
9014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_ALIGN_STACK               \
9024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "movl %%esp,%%edi\n\t"               \
9034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "andl $0xfffffff0,%%esp\n\t"
9044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_RESTORE_STACK             \
9054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "movl %%edi,%%esp\n\t"
9064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
9070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
9080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 4. */
9090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
91066226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_v(lval, orig)                                   \
9110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
91266226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
9140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
91566226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
9174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
9180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
9210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
9240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
92866226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
9290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
93066226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
9320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
93366226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
9364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
93787a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
9380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
9420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
9450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
94966226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
9500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
95166226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
9530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
95466226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
9584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
95987a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
9600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
9610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
9650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9669e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*in*/    "a" (&_argvec[0])                            \
9674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
9689e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      );                                                          \
9699e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      lval = (__typeof__(lval)) _res;                             \
9709e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   } while (0)
9719e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
9729e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
9739e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   do {                                                           \
9749e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile OrigFn        _orig = (orig);                      \
9759e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _argvec[4];                          \
9769e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _res;                                \
9779e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9789e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[1] = (unsigned long)(arg1);                         \
9799e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[2] = (unsigned long)(arg2);                         \
9809e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[3] = (unsigned long)(arg3);                         \
9819e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      __asm__ volatile(                                           \
9824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
98387a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
9849e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 12(%%eax)\n\t"                                    \
9859e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 8(%%eax)\n\t"                                     \
9869e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 4(%%eax)\n\t"                                     \
9879e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9889e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
9909e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*out*/   "=a" (_res)                                  \
9910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
9930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
99766226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
9980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
99966226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
10000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[5];                          \
10010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
100266226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
10050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
10060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
10070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
10090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
10100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
10110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
10120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
10130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
10160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
10190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
102366226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
10240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
102566226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
10260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[6];                          \
10270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
102866226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
10310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
10320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
10330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
10340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
103687a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
10370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
10380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
10390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
10400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
10410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
10420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
10450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
10480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
105266226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
10530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
105466226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
10550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[7];                          \
10560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
105766226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
10600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
10610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
10620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
10630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
10640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
106687a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
10670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
10680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
10690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
10700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
10710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
10720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
10730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
10760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
10790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
108366226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
108466226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7)                            \
10850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
108666226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
10870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[8];                          \
10880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
108966226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
10920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
10930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
10940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
10950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
10960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
10970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
109987a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
11000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
11010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
11020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
11030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
11040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
11050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
11060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
11070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
11080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
11094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
11100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
11130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
111766226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
111866226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7,arg8)                       \
11190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
112066226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
11210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[9];                          \
11220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
112366226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
11250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
11260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
11270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
11280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
11290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
11300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
11310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
11320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
11334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
11340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
11350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
11360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
11370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
11380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
11390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
11400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
11410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
11420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
11430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
11444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
11450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
11480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
115245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
115345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                 arg7,arg8,arg9)                  \
115445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
115545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
115645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[10];                         \
115745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
115845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
115945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
116045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
116145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
116245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
116345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
116445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
116545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
116645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
116745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
116845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
11694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
117087a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $12, %%esp\n\t"                                    \
117145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
117245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
117345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
117445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
117545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
117645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
117745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
117845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
117945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
118045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
118145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
11824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
118345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
118445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
11854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
118645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
118745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
118845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
118945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
119045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
119145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                  arg7,arg8,arg9,arg10)           \
119245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
119345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
119445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[11];                         \
119545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
119645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
119745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
119845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
119945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
120045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
120145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
120245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
120345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
120445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
120545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
120645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[10] = (unsigned long)(arg10);                       \
120745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
12084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
120987a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $8, %%esp\n\t"                                     \
121045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 40(%%eax)\n\t"                                    \
121145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
121245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
121345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
121445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
121545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
121645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
121745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
121845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
121945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
122045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
122145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
12224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
122345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
122445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
12254118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
122645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
122745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
122845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
122945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
12305ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
12315ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg6,arg7,arg8,arg9,arg10,      \
12325ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg11)                          \
12335ce4b150ce5d32c9af07a24717081ea34568388asewardj   do {                                                           \
12345ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile OrigFn        _orig = (orig);                      \
12355ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _argvec[12];                         \
12365ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _res;                                \
12375ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
12385ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[1] = (unsigned long)(arg1);                         \
12395ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[2] = (unsigned long)(arg2);                         \
12405ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[3] = (unsigned long)(arg3);                         \
12415ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[4] = (unsigned long)(arg4);                         \
12425ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[5] = (unsigned long)(arg5);                         \
12435ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[6] = (unsigned long)(arg6);                         \
12445ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[7] = (unsigned long)(arg7);                         \
12455ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[8] = (unsigned long)(arg8);                         \
12465ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[9] = (unsigned long)(arg9);                         \
12475ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[10] = (unsigned long)(arg10);                       \
12485ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[11] = (unsigned long)(arg11);                       \
12495ce4b150ce5d32c9af07a24717081ea34568388asewardj      __asm__ volatile(                                           \
12504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
125187a287b47f496063f5869dc5039a81baeb6a29aesewardj         "subl $4, %%esp\n\t"                                     \
12525ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 44(%%eax)\n\t"                                    \
12535ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 40(%%eax)\n\t"                                    \
12545ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 36(%%eax)\n\t"                                    \
12555ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 32(%%eax)\n\t"                                    \
12565ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 28(%%eax)\n\t"                                    \
12575ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 24(%%eax)\n\t"                                    \
12585ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 20(%%eax)\n\t"                                    \
12595ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 16(%%eax)\n\t"                                    \
12605ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 12(%%eax)\n\t"                                    \
12615ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 8(%%eax)\n\t"                                     \
12625ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 4(%%eax)\n\t"                                     \
12635ce4b150ce5d32c9af07a24717081ea34568388asewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
12645ce4b150ce5d32c9af07a24717081ea34568388asewardj         VALGRIND_CALL_NOREDIR_EAX                                \
12654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
12665ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*out*/   "=a" (_res)                                  \
12675ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*in*/    "a" (&_argvec[0])                            \
12684118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
12695ce4b150ce5d32c9af07a24717081ea34568388asewardj      );                                                          \
12705ce4b150ce5d32c9af07a24717081ea34568388asewardj      lval = (__typeof__(lval)) _res;                             \
12715ce4b150ce5d32c9af07a24717081ea34568388asewardj   } while (0)
12725ce4b150ce5d32c9af07a24717081ea34568388asewardj
127366226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
127466226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
127566226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg11,arg12)                    \
12760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
127766226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
12780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[13];                         \
12790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
128066226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
12810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
12820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
12830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
12840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
12850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
12860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
12870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
12880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
12890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[9] = (unsigned long)(arg9);                         \
12900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[10] = (unsigned long)(arg10);                       \
12910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[11] = (unsigned long)(arg11);                       \
12920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[12] = (unsigned long)(arg12);                       \
12930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
12944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
12950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 48(%%eax)\n\t"                                    \
12960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 44(%%eax)\n\t"                                    \
12970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 40(%%eax)\n\t"                                    \
12980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 36(%%eax)\n\t"                                    \
12990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
13000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
13010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
13020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
13030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
13040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
13050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
13060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
13070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
13080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
13094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
13100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
13110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
13124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
13130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
13140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
13150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
13160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1317f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
13180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1319f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
13200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1321f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
13220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
13230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
13240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
13250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
13260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
13270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                            "rdi", "r8", "r9", "r10", "r11"
13280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1329dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj/* This is all pretty complex.  It's so as to make stack unwinding
1330dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   work reliably.  See bug 243270.  The basic problem is the sub and
1331dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   add of 128 of %rsp in all of the following macros.  If gcc believes
1332dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   the CFA is in %rsp, then unwinding may fail, because what's at the
1333dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   CFA is not what gcc "expected" when it constructs the CFIs for the
1334dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   places where the macros are instantiated.
1335dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1336dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   But we can't just add a CFI annotation to increase the CFA offset
1337dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   by 128, to match the sub of 128 from %rsp, because we don't know
1338dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   whether gcc has chosen %rsp as the CFA at that point, or whether it
1339dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   has chosen some other register (eg, %rbp).  In the latter case,
1340dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   adding a CFI annotation to change the CFA offset is simply wrong.
1341dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1342dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   So the solution is to get hold of the CFA using
13438d1dc150a77fe495682a928949c5d5b7443b045csewardj   __builtin_dwarf_cfa(), put it in a known register, and add a
1344dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   CFI annotation to say what the register is.  We choose %rbp for
1345dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   this (perhaps perversely), because:
1346dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1347dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   (1) %rbp is already subject to unwinding.  If a new register was
1348dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       chosen then the unwinder would have to unwind it in all stack
1349dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       traces, which is expensive, and
1350dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1351dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   (2) %rbp is already subject to precise exception updates in the
1352dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       JIT.  If a new register was chosen, we'd have to have precise
1353dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       exceptions for it too, which reduces performance of the
1354dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj       generated code.
1355dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1356dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   However .. one extra complication.  We can't just whack the result
13578d1dc150a77fe495682a928949c5d5b7443b045csewardj   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1358dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   list of trashed registers at the end of the inline assembly
1359dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   fragments; gcc won't allow %rbp to appear in that list.  Hence
1360dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   instead we need to stash %rbp in %r15 for the duration of the asm,
1361dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   and say that %r15 is trashed instead.  gcc seems happy to go with
1362dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   that.
1363dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
1364dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   Oh .. and this all needs to be conditionalised so that it is
1365dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj   unchanged from before this commit, when compiled with older gccs
13668d1dc150a77fe495682a928949c5d5b7443b045csewardj   that don't support __builtin_dwarf_cfa.  Furthermore, since
13678d1dc150a77fe495682a928949c5d5b7443b045csewardj   this header file is freestanding, it has to be independent of
13688d1dc150a77fe495682a928949c5d5b7443b045csewardj   config.h, and so the following conditionalisation cannot depend on
13698d1dc150a77fe495682a928949c5d5b7443b045csewardj   configure time checks.
13708d1dc150a77fe495682a928949c5d5b7443b045csewardj
13718d1dc150a77fe495682a928949c5d5b7443b045csewardj   Although it's not clear from
13728d1dc150a77fe495682a928949c5d5b7443b045csewardj   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
13738d1dc150a77fe495682a928949c5d5b7443b045csewardj   this expression excludes Darwin.
13748d1dc150a77fe495682a928949c5d5b7443b045csewardj   .cfi directives in Darwin assembly appear to be completely
13758d1dc150a77fe495682a928949c5d5b7443b045csewardj   different and I haven't investigated how they work.
13768d1dc150a77fe495682a928949c5d5b7443b045csewardj
13778d1dc150a77fe495682a928949c5d5b7443b045csewardj   For even more entertainment value, note we have to use the
13788d1dc150a77fe495682a928949c5d5b7443b045csewardj   completely undocumented __builtin_dwarf_cfa(), which appears to
13798d1dc150a77fe495682a928949c5d5b7443b045csewardj   really compute the CFA, whereas __builtin_frame_address(0) claims
13808d1dc150a77fe495682a928949c5d5b7443b045csewardj   to but actually doesn't.  See
13818d1dc150a77fe495682a928949c5d5b7443b045csewardj   https://bugs.kde.org/show_bug.cgi?id=243270#c47
1382dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj*/
13838d1dc150a77fe495682a928949c5d5b7443b045csewardj#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1384dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define __FRAME_POINTER                                         \
13858d1dc150a77fe495682a928949c5d5b7443b045csewardj      ,"r"(__builtin_dwarf_cfa())
1386dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
1387dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      "movq %%rbp, %%r15\n\t"                                     \
13888d1dc150a77fe495682a928949c5d5b7443b045csewardj      "movq %2, %%rbp\n\t"                                        \
13898d1dc150a77fe495682a928949c5d5b7443b045csewardj      ".cfi_remember_state\n\t"                                   \
1390dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      ".cfi_def_cfa rbp, 0\n\t"
1391dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_EPILOGUE                                   \
1392dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      "movq %%r15, %%rbp\n\t"                                     \
1393dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj      ".cfi_restore_state\n\t"
1394dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#else
1395dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define __FRAME_POINTER
1396dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_PROLOGUE
1397dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#  define VALGRIND_CFI_EPILOGUE
1398dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj#endif
1399dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
14004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom/* Macros to save and align the stack before making a function
14014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   call and restore it afterwards as gcc may not keep the stack
14024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   pointer aligned if it doesn't realise calls are being made
14034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   to other functions. */
14044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
14054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_ALIGN_STACK               \
14064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "movq %%rsp,%%r14\n\t"               \
14074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "andq $0xfffffffffffffff0,%%rsp\n\t"
14084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_RESTORE_STACK             \
14094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "movq %%r14,%%rsp\n\t"
1410dfa55cf5263d1a105425fef13aff164e8cbb30f6sewardj
14110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
14120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 8. */
14130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1414a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1415a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   macros.  In order not to trash the stack redzone, we need to drop
1416a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   %rsp by 128 before the hidden call, and restore afterwards.  The
1417a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   nastyness is that it is only by luck that the stack still appears
1418a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   to be unwindable during the hidden call - since then the behaviour
1419a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   of any routine using this macro does not match what the CFI data
1420a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   says.  Sigh.
1421a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1422a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Why is this important?  Imagine that a wrapper has a stack
1423a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   allocated local, and passes to the hidden call, a pointer to it.
1424a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Because gcc does not know about the hidden call, it may allocate
1425a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   that local in the redzone.  Unfortunately the hidden call may then
1426a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   trash it before it comes to use it.  So we must step clear of the
1427a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   redzone, for the duration of the hidden call, to make it safe.
1428a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1429a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Probably the same problem afflicts the other redzone-style ABIs too
14306e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj   (ppc64-linux); but for those, the stack is
1431a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   self describing (none of this CFI nonsense) so at least messing
1432a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   with the stack pointer doesn't give a danger of non-unwindable
1433a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   stack. */
1434a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
14354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_v(lval, orig)                                        \
14364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
14374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
14384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[1];                               \
14394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
14404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
14414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
14424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
14434118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
14444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
14454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
14464118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
14474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
14484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
14494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
14504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
14514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
14524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
14534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
14544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
14554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
14564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_W(lval, orig, arg1)                                  \
14574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
14584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
14594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[2];                               \
14604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
14614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
14624118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
14634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
14644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
14654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
14664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
14674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
14684118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
14694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
14704118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
14714118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
14724118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
14734118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
14744118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
14754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
14764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
14774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
14784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
14794118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
14804118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
14814118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
14824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[3];                               \
14834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
14844118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
14854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
14864118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
14874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
14884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
14894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
14904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
14914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
14924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
14934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
14944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
14954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
14964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
14974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
14984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
14994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
15004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
15014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
15024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
15034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
15044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
15054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
15064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
15074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[4];                               \
15084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
15094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
15104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
15114118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
15124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
15134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
15144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
15154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
15164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
15174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
15184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
15194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
15204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
15214118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
15224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
15234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
15244118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
15254118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
15264118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
15274118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
15284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
15294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
15304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
15314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
15324118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
15334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
15344118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[5];                               \
15354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
15364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
15374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
15384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
15394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
15404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
15414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
15424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
15434118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
15444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
15454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
15464118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
15474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
15484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
15494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
15504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
15514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
15524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
15534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
15544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
15554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
15564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
15574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
15584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
15594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
15604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
15614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
15624118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
15634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[6];                               \
15644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
15654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
15664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
15674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
15684118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
15694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
15704118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
15714118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
15724118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
15734118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
15744118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
15754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
15764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
15774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
15784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
15794118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
15804118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
15814118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
15824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
15834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
15844118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
15854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
15864118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
15874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
15884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
15894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
15904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
15914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
15924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
15934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
15944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[7];                               \
15954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
15964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
15974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
15984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
15994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
16004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
16014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
16024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
16034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
16044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
16054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
16064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
16074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
16084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
16094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
16104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
16114118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
16124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
16134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
16144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
16154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
16164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
16174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
16184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
16194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
16204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
16214118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
16224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
16234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
16244118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
16254118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                 arg7)                                 \
16264118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
16274118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
16284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[8];                               \
16294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
16304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
16314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
16324118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
16334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
16344118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
16354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
16364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
16374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
16384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
16394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
16404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
16414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $136,%%rsp\n\t"                                         \
16424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
16434118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
16444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
16454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
16464118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
16474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
16484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
16494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
16504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
16514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
16524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
16534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
16544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
16554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
16564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
16574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
16584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
16594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
16604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
16614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                 arg7,arg8)                            \
16624118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
16634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
16644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[9];                               \
16654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
16664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
16674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
16684118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
16694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
16704118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
16714118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
16724118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
16734118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
16744118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[8] = (unsigned long)(arg8);                              \
16754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
16764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
16774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
16784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
16794118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 64(%%rax)\n\t"                                         \
16804118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
16814118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
16824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
16834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
16844118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
16854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
16864118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
16874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
16884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
16894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
16904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
16914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
16924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
16934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
16944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
16954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
16964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
16974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
16984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
16994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                 arg7,arg8,arg9)                       \
17004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
17014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
17024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[10];                              \
17034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
17044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
17054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
17064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
17074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
17084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
17094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
17104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
17114118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
17124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[8] = (unsigned long)(arg8);                              \
17134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[9] = (unsigned long)(arg9);                              \
17144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
17154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
17164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
17174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $136,%%rsp\n\t"                                         \
17184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 72(%%rax)\n\t"                                         \
17194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 64(%%rax)\n\t"                                         \
17204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
17214118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
17224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
17234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
17244118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
17254118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
17264118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
17274118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
17284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
17294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
17304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
17314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
17324118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
17334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
17344118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
17354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
17364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
17374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
17384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
17394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                  arg7,arg8,arg9,arg10)                \
17404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
17414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
17424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[11];                              \
17434118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
17444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
17454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
17464118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
17474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
17484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
17494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
17504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
17514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
17524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[8] = (unsigned long)(arg8);                              \
17534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[9] = (unsigned long)(arg9);                              \
17544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[10] = (unsigned long)(arg10);                            \
17554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
17564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
17574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
17584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
17594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 80(%%rax)\n\t"                                         \
17604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 72(%%rax)\n\t"                                         \
17614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 64(%%rax)\n\t"                                         \
17624118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
17634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
17644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
17654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
17664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
17674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
17684118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
17694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
17704118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
17714118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
17724118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
17734118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
17744118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
17754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
17764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
17774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
17784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
17794118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
17804118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
17814118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                  arg7,arg8,arg9,arg10,arg11)          \
17824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
17834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
17844118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[12];                              \
17854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
17864118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
17874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
17884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
17894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
17904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
17914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
17924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
17934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
17944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[8] = (unsigned long)(arg8);                              \
17954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[9] = (unsigned long)(arg9);                              \
17964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[10] = (unsigned long)(arg10);                            \
17974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[11] = (unsigned long)(arg11);                            \
17984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
17994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
18004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
18014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $136,%%rsp\n\t"                                         \
18024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 88(%%rax)\n\t"                                         \
18034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 80(%%rax)\n\t"                                         \
18044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 72(%%rax)\n\t"                                         \
18054118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 64(%%rax)\n\t"                                         \
18064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
18074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
18084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
18094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
18104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
18114118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
18124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
18134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
18144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
18154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
18164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
18174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
18184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
18194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
18204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
18214118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
18224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   } while (0)
18234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
18244118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
18254118e0f0df0468b3eccf2515d13c3d9c478d6f16tom                                arg7,arg8,arg9,arg10,arg11,arg12)      \
18264118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   do {                                                                \
18274118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile OrigFn        _orig = (orig);                           \
18284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _argvec[13];                              \
18294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      volatile unsigned long _res;                                     \
18304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[0] = (unsigned long)_orig.nraddr;                        \
18314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[1] = (unsigned long)(arg1);                              \
18324118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[2] = (unsigned long)(arg2);                              \
18334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[3] = (unsigned long)(arg3);                              \
18344118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[4] = (unsigned long)(arg4);                              \
18354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[5] = (unsigned long)(arg5);                              \
18364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[6] = (unsigned long)(arg6);                              \
18374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[7] = (unsigned long)(arg7);                              \
18384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[8] = (unsigned long)(arg8);                              \
18394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[9] = (unsigned long)(arg9);                              \
18404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[10] = (unsigned long)(arg10);                            \
18414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[11] = (unsigned long)(arg11);                            \
18424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      _argvec[12] = (unsigned long)(arg12);                            \
18434118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      __asm__ volatile(                                                \
18444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_PROLOGUE                                         \
18454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                          \
18464118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "subq $128,%%rsp\n\t"                                         \
18474118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 96(%%rax)\n\t"                                         \
18484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 88(%%rax)\n\t"                                         \
18494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 80(%%rax)\n\t"                                         \
18504118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 72(%%rax)\n\t"                                         \
18514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 64(%%rax)\n\t"                                         \
18524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "pushq 56(%%rax)\n\t"                                         \
18534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 48(%%rax), %%r9\n\t"                                    \
18544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 40(%%rax), %%r8\n\t"                                    \
18554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 32(%%rax), %%rcx\n\t"                                   \
18564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 24(%%rax), %%rdx\n\t"                                   \
18574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 16(%%rax), %%rsi\n\t"                                   \
18584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq 8(%%rax), %%rdi\n\t"                                    \
18594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
18604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CALL_NOREDIR_RAX                                     \
18614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                        \
18624118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_CFI_EPILOGUE                                         \
18634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*out*/   "=a" (_res)                                       \
18644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
18654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
18664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      );                                                               \
18674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      lval = (__typeof__(lval)) _res;                                  \
1868a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1869a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1870f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
18710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1872f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
18730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1874f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
18750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1876ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* This is useful for finding out about the on-stack stuff:
1877ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1878ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f9  ( int,int,int,int,int,int,int,int,int );
1879ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1880ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1881ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1882ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1883ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g9 ( void ) {
1884ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f9(11,22,33,44,55,66,77,88,99);
1885ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1886ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g10 ( void ) {
1887ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f10(11,22,33,44,55,66,77,88,99,110);
1888ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1889ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g11 ( void ) {
1890ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f11(11,22,33,44,55,66,77,88,99,110,121);
1891ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1892ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g12 ( void ) {
1893ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1894ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1895ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj*/
1896ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
18970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
18980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
18990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
1900ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define __CALLER_SAVED_REGS                                       \
1901ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "lr", "ctr", "xer",                                            \
1902ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1903ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1904ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r11", "r12", "r13"
19050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
19064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom/* Macros to save and align the stack before making a function
19074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   call and restore it afterwards as gcc may not keep the stack
19084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   pointer aligned if it doesn't realise calls are being made
19094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   to other functions. */
19104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
19114118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_ALIGN_STACK               \
19124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "mr 28,1\n\t"                        \
19134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "rlwinm 1,1,0,0,27\n\t"
19144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_RESTORE_STACK             \
19154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "mr 1,28\n\t"
19164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
1917ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* These CALL_FN_ macros assume that on ppc32-linux,
1918ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   sizeof(unsigned long) == 4. */
19190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
192038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_v(lval, orig)                                   \
19210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1922d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
19230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
19240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1925d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
19260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
19274118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
19280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
19290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
19300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
19314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
19320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
19330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
19340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
19354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
19360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
19370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
19380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
19390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
194038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
19410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
194238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
19430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
19440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
194538de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
19460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
19470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
19484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
19490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
19500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
19510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
19520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
19534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
19540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
19550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
19560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
19574118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
19580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
19590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
19600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
19610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
196238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
19630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
196438de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
19650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
19660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
196738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
19680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
19690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)arg2;                           \
19700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
19714118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
19720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
19730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
19740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 4,8(11)\n\t"                                        \
19750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
19760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
19774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
19780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
19790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
19800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
19814118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
19820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
19830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
19840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
19850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1986ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1987ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1988ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1989ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[4];                          \
1990ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1991ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1992ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1993ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1994ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1995ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
19964118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
1997ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1998ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1999ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2000ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2001ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2002ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20034118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2004ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2005ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2006ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
20074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2008ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2009ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2010ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2011ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2012ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2013ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2014ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2015ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[5];                          \
2016ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2017ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2018ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2019ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2020ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2021ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2022ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
20234118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2024ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2025ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2026ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2027ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2028ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2029ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2030ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20314118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2032ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2033ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2034ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
20354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2036ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2037ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2038ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2039ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2040ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2041ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2042ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2043ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[6];                          \
2044ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2045ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2046ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2047ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2048ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2049ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2050ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2051ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
20524118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2053ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2054ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2055ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2056ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2057ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2058ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2059ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2060ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2062ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2063ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2064ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
20654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2066ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2067ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2068ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2069ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2070ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2071ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2072ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2073ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[7];                          \
2074ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2075ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2076ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2077ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2078ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2079ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2080ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2081ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2082ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
20834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2084ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2085ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2086ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2087ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2088ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2089ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2090ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2091ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2092ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2094ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2095ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2096ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
20974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2098ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2099ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2100ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2101ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2102ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2103ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7)                            \
2104ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2105ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2106ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[8];                          \
2107ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2108ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2109ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2110ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2111ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2112ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2113ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2114ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2115ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2116ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
21174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2118ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2119ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2120ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2121ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2122ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2123ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2124ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2125ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2126ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2127ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
21284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2129ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2130ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2131ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
21324118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2133ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2134ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2135ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2136ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2137ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2138ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8)                       \
2139ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2140ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2141ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[9];                          \
2142ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2143ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2144ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2145ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2146ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2147ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2148ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2149ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2150ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2151ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2152ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
21534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2154ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2155ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2156ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2157ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2158ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2159ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2160ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2161ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2162ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2163ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2164ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
21654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2166ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2167ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2168ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
21694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2170ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2171ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2172ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2173ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2174ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2175ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8,arg9)                  \
2176ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2177ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2178ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[10];                         \
2179ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2180ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2181ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2182ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2183ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2184ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2185ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2186ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2187ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2188ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2189ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2190ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
21914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2192ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2193ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
2194ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2195ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2196ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2197ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2198ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2199ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2200ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2201ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2202ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2203ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2204ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2205ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2206ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2207ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
22084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2209ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2210ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2211ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
22124118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2213ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2214ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2215ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2216ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2217ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2218ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10)           \
2219ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2220ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2221ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[11];                         \
2222ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2223ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2224ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2225ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2226ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2227ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2228ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2229ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2230ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2231ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2232ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2233ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2234ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
22354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2236ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2237ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
2238ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2239ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2240ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2241ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2242ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2243ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2244ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2245ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2246ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2247ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2248ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2249ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2250ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2251ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2252ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2253ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2254ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
22554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2256ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2257ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2258ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
22594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2260ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2261ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2262ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2263ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2264ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2265ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2266ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2267ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2268ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[12];                         \
2269ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2270ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2271ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2272ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2273ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2274ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2275ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2276ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2277ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2278ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2279ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2280ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2281ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
2282ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
22834118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2284ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2285ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
2286ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
2287ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
2288ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
2289ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2290ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2291ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2292ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2293ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2294ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2295ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2296ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2297ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2298ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2299ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2300ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2301ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2302ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2303ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2304ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2305ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
23064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2307ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2308ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2309ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
23104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2311ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2312ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2313ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2314ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2315ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2316ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2317ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
2318ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
2319ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[13];                         \
2320ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
2321ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
2322ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
2323ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
2324ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
2325ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
2326ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
2327ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
2328ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
2329ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
2330ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
2331ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
2332ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
2333ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[12] = (unsigned long)arg12;                         \
2334ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
23354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2336ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
2337ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
2338ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg12 */                                              \
2339ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,48(11)\n\t"                                       \
2340ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,20(1)\n\t"                                        \
2341ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
2342ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
2343ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
2344ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
2345ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
2346ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
2347ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
2348ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
2349ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
2350ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
2351ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
2352ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
2353ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
2354ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
2355ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
2356ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
2357ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
2358ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
2359ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
2360ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
23614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2362ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
2363ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
2364ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
23654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2366ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
2367ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2368ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2369ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2370f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
23710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2372f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
23730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2374f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
23759734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
23769734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
23779734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
23789734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These regs are trashed by the hidden call. */
2379cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define __CALLER_SAVED_REGS                                       \
2380cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "lr", "ctr", "xer",                                            \
2381cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2382cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2383cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r11", "r12", "r13"
23849734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
23854118e0f0df0468b3eccf2515d13c3d9c478d6f16tom/* Macros to save and align the stack before making a function
23864118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   call and restore it afterwards as gcc may not keep the stack
23874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   pointer aligned if it doesn't realise calls are being made
23884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   to other functions. */
23894118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
23904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_ALIGN_STACK               \
23914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "mr 28,1\n\t"                        \
23924118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "rldicr 1,1,0,59\n\t"
23934118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_RESTORE_STACK             \
23944118e0f0df0468b3eccf2515d13c3d9c478d6f16tom      "mr 1,28\n\t"
23954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
23969734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
23979734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   long) == 8. */
23989734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2399d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_v(lval, orig)                                   \
24009734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2401d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2402d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+0];                        \
24039734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2404d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2405d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
2406d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
24079734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
24084118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
24099734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2410d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2411d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2412d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
24139734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
24149734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
24159734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
24164118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
24174118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
24189734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2419d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
24204118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
24219734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
24229734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
24239734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
24249734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2425d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
24269734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2427d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2428d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+1];                        \
24299734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2430d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2431d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2432d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2433d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
24349734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
24354118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
24369734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2437d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2438d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2439d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2440d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
24419734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
24429734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
24439734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
24444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
24454118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
24469734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2447d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
24484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
24499734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
24509734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
24519734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
24529734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2453d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
24549734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2455d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2456d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+2];                        \
24579734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2458d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2459d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2460d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2461d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2462d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
24639734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
24644118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
24659734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2466d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2467d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2468d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2469cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2470cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2471cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2472cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2473cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
24744118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
24754118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2476cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2477cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
24784118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2479cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2480cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2481cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2482cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2483cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2484cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2485cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2486cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+3];                        \
2487cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2488cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2489cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2490cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2491cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2492cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2493cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2494cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
24954118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2496cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2497cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2498cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2499cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2500cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2501cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2502d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
25039734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
25049734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
25059734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
25064118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
25074118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
25089734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2509d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
25104118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2511cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2512cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2513cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2514cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2515cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2516cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2517cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2518cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+4];                        \
2519cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2520cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2521cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2522cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2523cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2524cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2525cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2526cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2527cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
25284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2529cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2530cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2531cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2532cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2533cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2534cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2535cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2536cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2537cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2538cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2539cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
25404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
25414118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2542cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2543cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
25444118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2545cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2546cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2547cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2548cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2549cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2550cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2551cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2552cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+5];                        \
2553cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2554cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2555cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2556cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2557cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2558cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2559cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2560cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2561cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2562cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
25634118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2564cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2565cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2566cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2567cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2568cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2569cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2570cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2571cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2572cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2573cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2574cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2575cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
25764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
25774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2578cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2579cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
25804118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2581cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2582cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2583cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2584cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2585cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2586cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2587cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2588cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+6];                        \
2589cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2590cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2591cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2592cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2593cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2594cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2595cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2596cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2597cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2598cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2599cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
26004118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2601cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2602cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2603cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2604cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2605cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2606cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2607cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2608cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2609cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2610cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2611cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2612cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2613cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
26144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
26154118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2616cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2617cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
26184118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2619cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2620cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2621cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2622cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2623cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2624cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7)                            \
2625cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2626cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2627cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+7];                        \
2628cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2629cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2630cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2631cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2632cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2633cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2634cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2635cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2636cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2637cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2638cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2639cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
26404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2641cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2642cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2643cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2644cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2645cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2646cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2647cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2648cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2649cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2650cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2651cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2652cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2653cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2654cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
26554118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
26564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2657cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2658cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
26594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2660cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2661cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2662cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2663cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2664cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2665cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8)                       \
2666cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2667cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2668cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+8];                        \
2669cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2670cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2671cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2672cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2673cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2674cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2675cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2676cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2677cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2678cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2679cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2680cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2681cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
26824118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2683cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2684cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2685cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2686cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2687cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2688cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2689cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2690cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2691cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2692cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2693cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2694cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2695cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2696cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2697cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
26984118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
26994118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2700cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2701cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
27024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2703cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2704cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2705cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2706cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2707cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2708cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8,arg9)                  \
2709cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2710cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2711cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+9];                        \
2712cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2713cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2714cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2715cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2716cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2717cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2718cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2719cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2720cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2721cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2722cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2723cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2724cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2725cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
27264118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2727cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2728cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2729cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2730cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2731cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2732cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2733cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2734cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2735cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2736cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2737cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2738cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2739cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2740cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2741cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2742cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2743cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2744cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2745cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2746cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2747cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
27484118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2749cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2750cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
27514118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2752cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2753cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2754cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2755cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2756cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2757cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10)           \
2758cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2759cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2760cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+10];                       \
2761cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2762cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2763cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2764cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2765cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2766cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2767cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2768cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2769cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2770cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2771cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2772cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2773cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2774cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2775cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
27764118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2777cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2778cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2779cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2780cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2781cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2782cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2783cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2784cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2785cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2786cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2787cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2788cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2789cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2790cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2791cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2792cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2793cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2794cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2795cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2796cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2797cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2798cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2799cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2800cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
28014118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2802cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2803cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
28044118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2805cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2806cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2807cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2808cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2809cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2810cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2811cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2812cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2813cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+11];                       \
2814cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2815cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2816cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2817cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2818cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2819cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2820cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2821cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2822cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2823cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2824cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2825cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2826cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2827cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2828cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2829cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
28304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2831cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2832cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2833cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2834cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2835cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2836cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2837cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2838cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2839cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2840cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2841cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2842cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2843cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2844cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2845cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2846cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2847cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2848cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2849cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2850cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2851cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2852cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2853cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2854cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2855cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2856cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2857cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
28584118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2859cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2860cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
28614118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
2862cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2863cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2864cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2865cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2866cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2867cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2868cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2869cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2870cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+12];                       \
2871cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2872cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2873cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2874cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2875cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2876cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2877cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2878cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2879cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2880cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2881cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2882cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2883cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2884cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2885cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2886cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
2887cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
28884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
2889cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2890cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2891cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2892cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2893cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg12 */                                              \
2894cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,96(11)\n\t"                                       \
2895cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,136(1)\n\t"                                       \
2896cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2897cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2898cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2899cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2900cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2901cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2902cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2903cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2904cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2905cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2906cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2907cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2908cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2909cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2910cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2911cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2912cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2913cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2914cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2915cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2916cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2917cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2918cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
29194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
2920cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2921cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
29224118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
29239734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
29249734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
29259734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
29269734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2927f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
2928f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
292959570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
293059570ffbe31930ab4d678754daaeec0715117a3dsewardj
293159570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
293259570ffbe31930ab4d678754daaeec0715117a3dsewardj
293359570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These regs are trashed by the hidden call. */
293459570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
293559570ffbe31930ab4d678754daaeec0715117a3dsewardj
29364118e0f0df0468b3eccf2515d13c3d9c478d6f16tom/* Macros to save and align the stack before making a function
29374118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   call and restore it afterwards as gcc may not keep the stack
29384118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   pointer aligned if it doesn't realise calls are being made
29394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom   to other functions. */
29404118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
2941567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj/* This is a bit tricky.  We store the original stack pointer in r10
2942567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   as it is callee-saves.  gcc doesn't allow the use of r11 for some
2943567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   reason.  Also, we can't directly "bic" the stack pointer in thumb
2944567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   mode since r13 isn't an allowed register number in that context.
2945567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   So use r4 as a temporary, since that is about to get trashed
2946567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   anyway, just after each use of this macro.  Side effect is we need
2947567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   to be very careful about any future changes, since
2948567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj   VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
29494118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_ALIGN_STACK               \
2950567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj      "mov r10, sp\n\t"                    \
2951567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj      "mov r4,  sp\n\t"                    \
2952567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj      "bic r4,  r4, #7\n\t"                \
2953567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj      "mov sp,  r4\n\t"
29544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom#define VALGRIND_RESTORE_STACK             \
2955567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj      "mov sp,  r10\n\t"
29564118e0f0df0468b3eccf2515d13c3d9c478d6f16tom
295759570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
295859570ffbe31930ab4d678754daaeec0715117a3dsewardj   long) == 4. */
295959570ffbe31930ab4d678754daaeec0715117a3dsewardj
296059570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_v(lval, orig)                                   \
296159570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
296259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
296359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[1];                          \
296459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
296559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
296659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
29674118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
296859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
296959570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
29704118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
297159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
297259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
297359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
2974567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
297559570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
297659570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
297759570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
297859570ffbe31930ab4d678754daaeec0715117a3dsewardj
297959570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
298059570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
298159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
298259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[2];                          \
298359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
298459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
298559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
298659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
29874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
298859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
298959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
299059570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
29914118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
299259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
299359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
299459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
2995567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
299659570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
299759570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
299859570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
299959570ffbe31930ab4d678754daaeec0715117a3dsewardj
300059570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
300159570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
300259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
300359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[3];                          \
300459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
300559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
300659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
300759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
300859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
30094118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
301059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
301159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
301259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
301359570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
30144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
301559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
301659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
301759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3018567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
301959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
302059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
302159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
302259570ffbe31930ab4d678754daaeec0715117a3dsewardj
302359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
302459570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
302559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
302659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[4];                          \
302759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
302859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
302959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
303059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
303159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
303259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
30334118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
303459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
303559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
303659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
303759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
303859570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
30394118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
304059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
304159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
304259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3043567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
304459570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
304559570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
304659570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
304759570ffbe31930ab4d678754daaeec0715117a3dsewardj
304859570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
304959570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
305059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
305159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[5];                          \
305259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
305359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
305459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
305559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
305659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
305759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
305859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
30594118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
306059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
306159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
306259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
306359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
306459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
306559570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
30664118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
306759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
306859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
306959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3070567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
307159570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
307259570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
307359570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
307459570ffbe31930ab4d678754daaeec0715117a3dsewardj
307559570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
307659570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
307759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
307859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[6];                          \
307959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
308059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
308159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
308259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
308359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
308459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
308559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
308659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
30874118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
30884118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "sub sp, sp, #4 \n\t"                                    \
308959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
309059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
309159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
309259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
309359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
309459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
309559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
309659570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
30974118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
309859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
309959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
310059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3101567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
310259570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
310359570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
310459570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
310559570ffbe31930ab4d678754daaeec0715117a3dsewardj
310659570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
310759570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
310859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
310959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[7];                          \
311059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
311159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
311259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
311359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
311459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
311559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
311659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
311759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
311859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
31194118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
312059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
312159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
312259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
312359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
312459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
312559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
312659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
312759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
312859570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
31294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
313059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
313159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
313259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3133567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
313459570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
313559570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
313659570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
313759570ffbe31930ab4d678754daaeec0715117a3dsewardj
313859570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
313959570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7)                            \
314059570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
314159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
314259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[8];                          \
314359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
314459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
314559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
314659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
314759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
314859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
314959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
315059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
315159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
315259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
31534118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
31544118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "sub sp, sp, #4 \n\t"                                    \
315559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
315659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
315759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
315859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
315959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
316059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
316159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
316259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
316359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
316459570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
31654118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
316659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
316759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
316859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3169567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
317059570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
317159570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
317259570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
317359570ffbe31930ab4d678754daaeec0715117a3dsewardj
317459570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
317559570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8)                       \
317659570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
317759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
317859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[9];                          \
317959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
318059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
318159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
318259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
318359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
318459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
318559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
318659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
318759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
318859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
318959570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
31904118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
319159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
319259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
319359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
319459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
319559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3} \n\t"                             \
319659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
319759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
319859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
319959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
320059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
320159570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
32024118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
320359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
320459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
320559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3206567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
320759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
320859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
320959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
321059570ffbe31930ab4d678754daaeec0715117a3dsewardj
321159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
321259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8,arg9)                  \
321359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
321459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
321559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[10];                         \
321659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
321759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
321859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
321959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
322059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
322159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
322259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
322359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
322459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
322559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
322659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
322759570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
32284118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
32294118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "sub sp, sp, #4 \n\t"                                    \
323059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
323159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
323259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
323359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
323459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
323559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
323659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
323759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
323859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
323959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
324059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
324159570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
32424118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
324359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
324459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
324559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3246567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
324759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
324859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
324959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
325059570ffbe31930ab4d678754daaeec0715117a3dsewardj
325159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
325259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg7,arg8,arg9,arg10)           \
325359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
325459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
325559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[11];                         \
325659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
325759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
325859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
325959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
326059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
326159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
326259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
326359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
326459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
326559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
326659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
326759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
326859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
32694118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
327059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
327159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
327259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
327359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
327459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
327559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
327659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
327759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
327859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
327959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
328059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
328159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
328259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
328359570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
32844118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
328559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
328659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
328759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3288567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
328959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
329059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
329159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
329259570ffbe31930ab4d678754daaeec0715117a3dsewardj
329359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
329459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
329559570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11)                          \
329659570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
329759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
329859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[12];                         \
329959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
330059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
330159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
330259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
330359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
330459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
330559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
330659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
330759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
330859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
330959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
331059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
331159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
331259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
33134118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
33144118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         "sub sp, sp, #4 \n\t"                                    \
331559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
331659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
331759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
331859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
331959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
332059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
332159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
332259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
332359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
332459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
332559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
332659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
332759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
332859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
332959570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
33304118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
333159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
333259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
333359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3334567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
333559570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
333659570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
333759570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
333859570ffbe31930ab4d678754daaeec0715117a3dsewardj
333959570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
334059570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
334159570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11,arg12)                    \
334259570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
334359570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
334459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[13];                         \
334559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
334659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
334759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
334859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
334959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
335059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
335159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
335259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
335359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
335459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
335559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
335659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
335759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
335859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[12] = (unsigned long)(arg12);                       \
335959570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
33604118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_ALIGN_STACK                                     \
336159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
336259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
336359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #48] \n\t"                                 \
336459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
336559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
336659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
336759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
336859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
336959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
337059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
337159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
337259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
337359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
337459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
337559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
337659570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
33774118e0f0df0468b3eccf2515d13c3d9c478d6f16tom         VALGRIND_RESTORE_STACK                                   \
337859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
337959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
338059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
3381567e5bb6edf4c1f5d8fe3e41aa0bbe63682bfeacsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
338259570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
338359570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
338459570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
338559570ffbe31930ab4d678754daaeec0715117a3dsewardj
338659570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
338759570ffbe31930ab4d678754daaeec0715117a3dsewardj
3388b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* ------------------------- s390x-linux ------------------------- */
3389b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3390b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(PLAT_s390x_linux)
3391b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3392b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* Similar workaround as amd64 (see above), but we use r11 as frame
3393b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   pointer and save the old r11 in r7. r11 might be used for
3394b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   argvec, therefore we copy argvec in r1 since r1 is clobbered
3395b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   after the call anyway.  */
3396b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3397b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define __FRAME_POINTER                                         \
3398b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ,"d"(__builtin_dwarf_cfa())
3399b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
3400b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_remember_state\n\t"                                   \
3401b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
3402b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 7,11\n\t"                                              \
3403b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 11,%2\n\t"                                             \
3404b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_def_cfa r11, 0\n\t"
3405b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_EPILOGUE                                   \
3406b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 11, 7\n\t"                                             \
3407b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      ".cfi_restore_state\n\t"
3408b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#else
3409b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define __FRAME_POINTER
3410b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_PROLOGUE                                   \
3411b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      "lgr 1,%1\n\t"
3412b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define VALGRIND_CFI_EPILOGUE
3413b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif
3414b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
34159af940f5f1832ab887b89598c7f0df519d47a092florian/* Nb: On s390 the stack pointer is properly aligned *at all times*
34169af940f5f1832ab887b89598c7f0df519d47a092florian   according to the s390 GCC maintainer. (The ABI specification is not
34179af940f5f1832ab887b89598c7f0df519d47a092florian   precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
34189af940f5f1832ab887b89598c7f0df519d47a092florian   VALGRIND_RESTORE_STACK are not defined here. */
3419b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3420b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* These regs are trashed by the hidden call. Note that we overwrite
3421b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3422b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   function a proper return address. All others are ABI defined call
3423b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   clobbers. */
3424b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3425b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                           "f0","f1","f2","f3","f4","f5","f6","f7"
3426b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
34279af940f5f1832ab887b89598c7f0df519d47a092florian/* Nb: Although r11 is modified in the asm snippets below (inside
34289af940f5f1832ab887b89598c7f0df519d47a092florian   VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
34299af940f5f1832ab887b89598c7f0df519d47a092florian   two reasons:
34309af940f5f1832ab887b89598c7f0df519d47a092florian   (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
34319af940f5f1832ab887b89598c7f0df519d47a092florian       modified
34329af940f5f1832ab887b89598c7f0df519d47a092florian   (2) GCC will complain that r11 cannot appear inside a clobber section,
34339af940f5f1832ab887b89598c7f0df519d47a092florian       when compiled with -O -fno-omit-frame-pointer
34349af940f5f1832ab887b89598c7f0df519d47a092florian */
3435b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3436b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_v(lval, orig)                                  \
3437b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3438b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3439b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long  _argvec[1];                        \
3440b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3441b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3442b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3443b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3444b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3445b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
3446b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3447b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3448b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3449b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3450b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3451b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
3452b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3453b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3454b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3455b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3456b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3457b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* The call abi has the arguments in r2-r6 and stack */
3458b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_W(lval, orig, arg1)                            \
3459b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3460b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3461b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[2];                         \
3462b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3463b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3464b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3465b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3466b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3467b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3468b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3469b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3470b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3471b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3472b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3473b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3474b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3475b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3476b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3477b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3478b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3479b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3480b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3481b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
3482b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3483b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3484b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[3];                         \
3485b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3486b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3487b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3488b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3489b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3490b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3491b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3492b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3493b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3494b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3495b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3496b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3497b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3498b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3499b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3500b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3501b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3502b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3503b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3504b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3505b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3506b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
3507b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3508b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3509b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[4];                         \
3510b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3511b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3512b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3513b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3514b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3515b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3516b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3517b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3518b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3519b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3520b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3521b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3522b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3523b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3524b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3525b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3526b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3527b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3528b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3529b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3530b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3531b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3532b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3533b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
3534b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3535b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3536b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[5];                         \
3537b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3538b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3539b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3540b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3541b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3542b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3543b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3544b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3545b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3546b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3547b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3548b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3549b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3550b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3551b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3552b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3553b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3554b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3555b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3556b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3557b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
3558b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3559b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3560b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3561b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3562b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
3563b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3564b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3565b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[6];                         \
3566b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3567b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3568b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3569b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3570b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3571b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3572b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3573b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3574b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3575b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-160\n\t"                                      \
3576b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3577b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3578b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3579b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3580b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3581b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3582b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3583b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3584b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,160\n\t"                                       \
3585b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3586b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3587b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3588b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3589b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3590b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3591b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3592b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3593b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3594b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6)                                       \
3595b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3596b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3597b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[7];                         \
3598b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3599b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3600b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3601b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3602b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3603b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3604b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3605b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3606b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3607b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3608b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-168\n\t"                                      \
3609b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3610b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3611b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3612b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3613b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3614b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3615b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3616b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3617b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3618b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,168\n\t"                                       \
3619b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3620b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3621b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3622b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3623b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3624b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3625b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3626b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3627b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3628b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7)                                 \
3629b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3630b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3631b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[8];                         \
3632b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3633b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3634b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3635b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3636b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3637b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3638b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3639b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3640b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3641b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3642b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3643b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-176\n\t"                                      \
3644b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3645b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3646b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3647b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3648b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3649b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3650b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3651b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3652b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3653b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3654b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,176\n\t"                                       \
3655b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3656b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3657b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3658b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3659b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3660b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3661b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3662b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3663b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3664b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8)                           \
3665b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3666b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3667b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[9];                         \
3668b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3669b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3670b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3671b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3672b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3673b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3674b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3675b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3676b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3677b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3678b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3679b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3680b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-184\n\t"                                      \
3681b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3682b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3683b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3684b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3685b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3686b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3687b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3688b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3689b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3690b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3691b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3692b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,184\n\t"                                       \
3693b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3694b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3695b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3696b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3697b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3698b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3699b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3700b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3701b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
3702b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9)                     \
3703b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3704b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3705b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[10];                        \
3706b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3707b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3708b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3709b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3710b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3711b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3712b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3713b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3714b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3715b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3716b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3717b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3718b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3719b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-192\n\t"                                      \
3720b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3721b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3722b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3723b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3724b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3725b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3726b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3727b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3728b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3729b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3730b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3731b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3732b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,192\n\t"                                       \
3733b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3734b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3735b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3736b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3737b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3738b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3739b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3740b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3741b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3742b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10)              \
3743b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3744b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3745b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[11];                        \
3746b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3747b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3748b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3749b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3750b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3751b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3752b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3753b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3754b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3755b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3756b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3757b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3758b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3759b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3760b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-200\n\t"                                      \
3761b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3762b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3763b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3764b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3765b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3766b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3767b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3768b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3769b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3770b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3771b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3772b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3773b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3774b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,200\n\t"                                       \
3775b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3776b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3777b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3778b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3779b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3780b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3781b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3782b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3783b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3784b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
3785b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3786b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3787b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[12];                        \
3788b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3789b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3790b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3791b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3792b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3793b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3794b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3795b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3796b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3797b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3798b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3799b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3800b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[11] = (unsigned long)arg11;                        \
3801b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3802b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3803b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-208\n\t"                                      \
3804b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3805b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3806b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3807b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3808b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3809b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3810b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3811b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3812b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3813b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3814b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 200(8,15), 88(1)\n\t"                              \
3815b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3816b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3817b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3818b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,208\n\t"                                       \
3819b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3820b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3821b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3822b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3823b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3824b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3825b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3826b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3827b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
3828b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3829b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   do {                                                          \
3830b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile OrigFn        _orig = (orig);                     \
3831b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _argvec[13];                        \
3832b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      volatile unsigned long _res;                               \
3833b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                  \
3834b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[1] = (unsigned long)arg1;                          \
3835b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[2] = (unsigned long)arg2;                          \
3836b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[3] = (unsigned long)arg3;                          \
3837b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[4] = (unsigned long)arg4;                          \
3838b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[5] = (unsigned long)arg5;                          \
3839b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[6] = (unsigned long)arg6;                          \
3840b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[7] = (unsigned long)arg7;                          \
3841b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[8] = (unsigned long)arg8;                          \
3842b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[9] = (unsigned long)arg9;                          \
3843b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[10] = (unsigned long)arg10;                        \
3844b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[11] = (unsigned long)arg11;                        \
3845b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      _argvec[12] = (unsigned long)arg12;                        \
3846b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      __asm__ volatile(                                          \
3847b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_PROLOGUE                                   \
3848b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,-216\n\t"                                      \
3849b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 2, 8(1)\n\t"                                        \
3850b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 3,16(1)\n\t"                                        \
3851b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 4,24(1)\n\t"                                        \
3852b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 5,32(1)\n\t"                                        \
3853b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 6,40(1)\n\t"                                        \
3854b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 160(8,15), 48(1)\n\t"                              \
3855b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 168(8,15), 56(1)\n\t"                              \
3856b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 176(8,15), 64(1)\n\t"                              \
3857b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 184(8,15), 72(1)\n\t"                              \
3858b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 192(8,15), 80(1)\n\t"                              \
3859b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 200(8,15), 88(1)\n\t"                              \
3860b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "mvc 208(8,15), 96(1)\n\t"                              \
3861b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lg 1, 0(1)\n\t"                                        \
3862b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CALL_NOREDIR_R1                                \
3863b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "lgr %0, 2\n\t"                                         \
3864b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         "aghi 15,216\n\t"                                       \
3865b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         VALGRIND_CFI_EPILOGUE                                   \
3866b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*out*/   "=d" (_res)                                 \
3867b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
3868b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3869b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      );                                                         \
3870b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      lval = (__typeof__(lval)) _res;                            \
3871b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   } while (0)
3872b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3873b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
3874b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif /* PLAT_s390x_linux */
3875b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
38765db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* ------------------------- mips-linux ------------------------- */
38775db15403e889d4db339b342bc2a824ef0bfaa654sewardj
38785db15403e889d4db339b342bc2a824ef0bfaa654sewardj#if defined(PLAT_mips32_linux)
38795db15403e889d4db339b342bc2a824ef0bfaa654sewardj
38805db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* These regs are trashed by the hidden call. */
38815db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
38825db15403e889d4db339b342bc2a824ef0bfaa654sewardj"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
38835db15403e889d4db339b342bc2a824ef0bfaa654sewardj"$25", "$31"
38845db15403e889d4db339b342bc2a824ef0bfaa654sewardj
38855db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
38865db15403e889d4db339b342bc2a824ef0bfaa654sewardj   long) == 4. */
38875db15403e889d4db339b342bc2a824ef0bfaa654sewardj
38885db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_v(lval, orig)                                   \
38895db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
38905db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
38915db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[1];                          \
38925db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
38935db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
38945db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
38955db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
38965db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
38975db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
38985db15403e889d4db339b342bc2a824ef0bfaa654sewardj        "subu $29, $29, 16 \n\t"                                 \
38995db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
39005db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
39015db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 16\n\t"                                  \
39025db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
39035db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
39045db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 8 \n\t"                                  \
39055db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
39065db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
39075db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
39085db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
39095db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
39105db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
39115db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
39125db15403e889d4db339b342bc2a824ef0bfaa654sewardj
39135db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
39145db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
39155db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
39165db15403e889d4db339b342bc2a824ef0bfaa654sewardj     volatile unsigned long _argvec[2];                           \
39175db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
39185db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
39195db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
39205db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
39215db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
39225db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
39235db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
39245db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 16 \n\t"                                 \
39255db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"   /* arg1*/                         \
39265db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
39275db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
39285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 16 \n\t"                                 \
39295db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
39305db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
39315db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 8 \n\t"                                  \
39325db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
39335db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
39345db15403e889d4db339b342bc2a824ef0bfaa654sewardj        : /*in*/    "0" (&_argvec[0])                             \
39355db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
39365db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
39375db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
39385db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
39395db15403e889d4db339b342bc2a824ef0bfaa654sewardj
39405db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
39415db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
39425db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
39435db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[3];                          \
39445db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
39455db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
39465db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
39475db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
39485db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
39495db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
39505db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
39515db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
39525db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 16 \n\t"                                 \
39535db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
39545db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
39555db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
39565db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
39575db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 16 \n\t"                                 \
39585db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
39595db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
39605db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 8 \n\t"                                  \
39615db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
39625db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
39635db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
39645db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
39655db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
39665db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
39675db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
39685db15403e889d4db339b342bc2a824ef0bfaa654sewardj
39695db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
39705db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
39715db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
39725db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[4];                          \
39735db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
39745db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
39755db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
39765db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
39775db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
39785db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
39795db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
39805db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
39815db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
39825db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 16 \n\t"                                 \
39835db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
39845db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
39855db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
39865db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
39875db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
39885db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 16 \n\t"                                 \
39895db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
39905db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
39915db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 8 \n\t"                                  \
39925db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
39935db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
39945db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
39955db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
39965db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
39975db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
39985db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
39995db15403e889d4db339b342bc2a824ef0bfaa654sewardj
40005db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
40015db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
40025db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
40035db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[5];                          \
40045db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
40055db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
40065db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
40075db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
40085db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
40095db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
40105db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
40115db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
40125db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
40135db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
40145db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 16 \n\t"                                 \
40155db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
40165db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
40175db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
40185db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
40195db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
40205db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
40215db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 16 \n\t"                                 \
40225db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
40235db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
40245db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 8 \n\t"                                  \
40255db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
40265db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
40275db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
40285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
40295db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
40305db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
40315db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
40325db15403e889d4db339b342bc2a824ef0bfaa654sewardj
40335db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
40345db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
40355db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
40365db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[6];                          \
40375db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
40385db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
40395db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
40405db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
40415db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
40425db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
40435db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
40445db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
40455db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
40465db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
40475db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
40485db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
40495db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 24\n\t"                                  \
40505db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
40515db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
40525db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
40535db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
40545db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
40555db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
40565db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
40575db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $29, $29, 24 \n\t"                                 \
40585db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
40595db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
40605db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
40615db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
40625db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
40635db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
40645db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
40655db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
40665db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
40675db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
40685db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
40695db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
40705db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
40715db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[7];                          \
40725db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
40735db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
40745db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
40755db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
40765db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
40775db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
40785db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
40795db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
40805db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
40815db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
40825db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
40835db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
40845db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
40855db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 32\n\t"                                  \
40865db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
40875db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
40885db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "nop\n\t"                                                \
40895db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
40905db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
40915db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
40925db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
40935db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
40945db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
40955db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
40965db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 32 \n\t"                                 \
40975db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
40985db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
40995db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
41005db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
41015db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
41025db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
41035db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
41045db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
41055db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
41065db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
41075db15403e889d4db339b342bc2a824ef0bfaa654sewardj
41085db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
41095db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                 arg7)                            \
41105db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
41115db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
41125db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[8];                          \
41135db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
41145db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
41155db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
41165db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
41175db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
41185db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
41195db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
41205db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
41215db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
41225db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
41235db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
41245db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
41255db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
41265db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
41275db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 32\n\t"                                  \
41285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
41295db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
41305db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
41315db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
41325db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
41335db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
41345db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
41355db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
41365db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
41375db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
41385db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
41395db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 32 \n\t"                                 \
41405db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
41415db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
41425db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
41435db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
41445db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
41455db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
41465db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
41475db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
41485db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
41495db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
41505db15403e889d4db339b342bc2a824ef0bfaa654sewardj
41515db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
41525db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                 arg7,arg8)                       \
41535db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
41545db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
41555db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[9];                          \
41565db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
41575db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
41585db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
41595db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
41605db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
41615db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
41625db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
41635db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
41645db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
41655db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[8] = (unsigned long)(arg8);                         \
41665db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
41675db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
41685db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
41695db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
41705db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
41715db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 40\n\t"                                  \
41725db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
41735db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
41745db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
41755db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
41765db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
41775db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 32(%1) \n\t"                                    \
41785db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 28($sp) \n\t"                                   \
41795db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
41805db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
41815db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
41825db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
41835db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
41845db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
41855db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 40 \n\t"                                 \
41865db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
41875db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
41885db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
41895db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
41905db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
41915db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
41925db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
41935db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
41945db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
41955db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
41965db15403e889d4db339b342bc2a824ef0bfaa654sewardj
41975db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
41985db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                 arg7,arg8,arg9)                  \
41995db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
42005db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
42015db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[10];                         \
42025db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
42035db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
42045db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
42055db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
42065db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
42075db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
42085db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
42095db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
42105db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
42115db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[8] = (unsigned long)(arg8);                         \
42125db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[9] = (unsigned long)(arg9);                         \
42135db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
42145db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
42155db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
42165db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
42175db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
42185db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 40\n\t"                                  \
42195db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
42205db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
42215db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
42225db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
42235db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
42245db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 32(%1) \n\t"                                    \
42255db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 28($sp) \n\t"                                   \
42265db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 36(%1) \n\t"                                    \
42275db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 32($sp) \n\t"                                   \
42285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
42295db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
42305db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
42315db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
42325db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
42335db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
42345db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 40 \n\t"                                 \
42355db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
42365db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
42375db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
42385db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
42395db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
42405db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
42415db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
42425db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
42435db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
42445db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
42455db15403e889d4db339b342bc2a824ef0bfaa654sewardj
42465db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
42475db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                  arg7,arg8,arg9,arg10)           \
42485db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
42495db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
42505db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[11];                         \
42515db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
42525db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
42535db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
42545db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
42555db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
42565db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
42575db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
42585db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
42595db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
42605db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[8] = (unsigned long)(arg8);                         \
42615db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[9] = (unsigned long)(arg9);                         \
42625db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[10] = (unsigned long)(arg10);                       \
42635db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
42645db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
42655db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
42665db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
42675db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
42685db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 48\n\t"                                  \
42695db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
42705db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
42715db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
42725db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
42735db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
42745db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 32(%1) \n\t"                                    \
42755db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 28($sp) \n\t"                                   \
42765db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 36(%1) \n\t"                                    \
42775db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 32($sp) \n\t"                                   \
42785db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 40(%1) \n\t"                                    \
42795db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 36($sp) \n\t"                                   \
42805db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
42815db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
42825db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
42835db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
42845db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
42855db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
42865db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 48 \n\t"                                 \
42875db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
42885db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
42895db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
42905db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
42915db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
42925db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
42935db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
42945db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
42955db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
42965db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
42975db15403e889d4db339b342bc2a824ef0bfaa654sewardj
42985db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
42995db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
43005db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                  arg11)                          \
43015db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
43025db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
43035db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[12];                         \
43045db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
43055db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
43065db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
43075db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
43085db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
43095db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
43105db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
43115db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
43125db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
43135db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[8] = (unsigned long)(arg8);                         \
43145db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[9] = (unsigned long)(arg9);                         \
43155db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[10] = (unsigned long)(arg10);                       \
43165db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[11] = (unsigned long)(arg11);                       \
43175db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
43185db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
43195db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
43205db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
43215db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
43225db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 48\n\t"                                  \
43235db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
43245db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
43255db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
43265db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
43275db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
43285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 32(%1) \n\t"                                    \
43295db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 28($sp) \n\t"                                   \
43305db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 36(%1) \n\t"                                    \
43315db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 32($sp) \n\t"                                   \
43325db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 40(%1) \n\t"                                    \
43335db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 36($sp) \n\t"                                   \
43345db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 44(%1) \n\t"                                    \
43355db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 40($sp) \n\t"                                   \
43365db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
43375db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
43385db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
43395db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
43405db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
43415db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
43425db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 48 \n\t"                                 \
43435db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
43445db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
43455db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
43465db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
43475db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
43485db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
43495db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
43505db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
43515db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
43525db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
43535db15403e889d4db339b342bc2a824ef0bfaa654sewardj
43545db15403e889d4db339b342bc2a824ef0bfaa654sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
43555db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
43565db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                  arg11,arg12)                    \
43575db15403e889d4db339b342bc2a824ef0bfaa654sewardj   do {                                                           \
43585db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile OrigFn        _orig = (orig);                      \
43595db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _argvec[13];                         \
43605db15403e889d4db339b342bc2a824ef0bfaa654sewardj      volatile unsigned long _res;                                \
43615db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
43625db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[1] = (unsigned long)(arg1);                         \
43635db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[2] = (unsigned long)(arg2);                         \
43645db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[3] = (unsigned long)(arg3);                         \
43655db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[4] = (unsigned long)(arg4);                         \
43665db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[5] = (unsigned long)(arg5);                         \
43675db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[6] = (unsigned long)(arg6);                         \
43685db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[7] = (unsigned long)(arg7);                         \
43695db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[8] = (unsigned long)(arg8);                         \
43705db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[9] = (unsigned long)(arg9);                         \
43715db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[10] = (unsigned long)(arg10);                       \
43725db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[11] = (unsigned long)(arg11);                       \
43735db15403e889d4db339b342bc2a824ef0bfaa654sewardj      _argvec[12] = (unsigned long)(arg12);                       \
43745db15403e889d4db339b342bc2a824ef0bfaa654sewardj      __asm__ volatile(                                           \
43755db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $29, $29, 8 \n\t"                                  \
43765db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $gp, 0($sp) \n\t"                                    \
43775db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $ra, 4($sp) \n\t"                                    \
43785db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 20(%1) \n\t"                                    \
43795db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "subu $sp, $sp, 56\n\t"                                  \
43805db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 16($sp) \n\t"                                   \
43815db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 24(%1) \n\t"                                    \
43825db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 20($sp) \n\t"                                   \
43835db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 28(%1) \n\t"                                    \
43845db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 24($sp) \n\t"                                   \
43855db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 32(%1) \n\t"                                    \
43865db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 28($sp) \n\t"                                   \
43875db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 36(%1) \n\t"                                    \
43885db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 32($sp) \n\t"                                   \
43895db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 40(%1) \n\t"                                    \
43905db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 36($sp) \n\t"                                   \
43915db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 44(%1) \n\t"                                    \
43925db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 40($sp) \n\t"                                   \
43935db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 48(%1) \n\t"                                    \
43945db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "sw $a0, 44($sp) \n\t"                                   \
43955db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a0, 4(%1) \n\t"                                     \
43965db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a1, 8(%1) \n\t"                                     \
43975db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a2, 12(%1) \n\t"                                    \
43985db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $a3, 16(%1) \n\t"                                    \
43995db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $t9, 0(%1) \n\t"  /* target->t9 */                   \
44005db15403e889d4db339b342bc2a824ef0bfaa654sewardj         VALGRIND_CALL_NOREDIR_T9                                 \
44015db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 56 \n\t"                                 \
44025db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $gp, 0($sp) \n\t"                                    \
44035db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "lw $ra, 4($sp) \n\t"                                    \
44045db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "addu $sp, $sp, 8 \n\t"                                  \
44055db15403e889d4db339b342bc2a824ef0bfaa654sewardj         "move %0, $v0\n"                                         \
44065db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*out*/   "=r" (_res)                                  \
44075db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*in*/    "0" (&_argvec[0])                            \
44085db15403e889d4db339b342bc2a824ef0bfaa654sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
44095db15403e889d4db339b342bc2a824ef0bfaa654sewardj      );                                                          \
44105db15403e889d4db339b342bc2a824ef0bfaa654sewardj      lval = (__typeof__(lval)) _res;                             \
44115db15403e889d4db339b342bc2a824ef0bfaa654sewardj   } while (0)
44125db15403e889d4db339b342bc2a824ef0bfaa654sewardj
44135db15403e889d4db339b342bc2a824ef0bfaa654sewardj#endif /* PLAT_mips32_linux */
44145db15403e889d4db339b342bc2a824ef0bfaa654sewardj
44150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
44160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
44170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
44180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/*                                                                    */
441930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
442030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
44212e93c50dc50235189661b70e3f27a4098d5cccccsewardj/* Some request codes.  There are many more of these, but most are not
44222e93c50dc50235189661b70e3f27a4098d5cccccsewardj   exposed to end-user view.  These are the public ones, all of the
4423e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   form 0x1000 + small_number.
4424d799418996812817596beaa8b59563e3f3cb2ddanjn
44250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
44260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ones start at 0x2000.
44272e93c50dc50235189661b70e3f27a4098d5cccccsewardj*/
44282e93c50dc50235189661b70e3f27a4098d5cccccsewardj
44290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These macros are used by tools -- they must be public, but don't
44300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   embed them into other programs. */
4431fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_USERREQ_TOOL_BASE(a,b) \
44324c791211835f0e90cbde578187c06e563de3b023njn   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
4433fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_IS_TOOL_USERREQ(a, b, v) \
4434fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
443534042515c1715b3e0c5c0a5e0bd033e9d4858f01sewardj
44365ce4b150ce5d32c9af07a24717081ea34568388asewardj/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
44375ce4b150ce5d32c9af07a24717081ea34568388asewardj   This enum comprises an ABI exported by Valgrind to programs
44385ce4b150ce5d32c9af07a24717081ea34568388asewardj   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
44395ce4b150ce5d32c9af07a24717081ea34568388asewardj   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
4440e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjntypedef
44414c791211835f0e90cbde578187c06e563de3b023njn   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
44424c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
44433e88418f808bf2840646504481d6a5be1df16541njn
44440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These allow any function to be called from the simulated
44450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             CPU but run on the real CPU.  Nb: the first arg passed to
44460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             the function is always the ThreadId of the running
44470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             thread!  So CLIENT_CALL0 actually requires a 1 arg
4448d4795be03ad94334c7517d93d3f5b35a97c7bba0njn             function, etc. */
44494c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL0 = 0x1101,
44504c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL1 = 0x1102,
44514c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL2 = 0x1103,
44524c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL3 = 0x1104,
44533e88418f808bf2840646504481d6a5be1df16541njn
44540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* Can be useful in regression testing suites -- eg. can
44550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             send Valgrind's output to /dev/null and still count
44560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             errors. */
44574c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__COUNT_ERRORS = 0x1201,
445847363aba8fa03b094195bca99fc232ce5f85605dnjn
44593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          /* Allows a string (gdb monitor command) to be passed to the tool
44603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             Used for interaction with vgdb/gdb */
44613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
44623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
44630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These are useful and can be interpreted by any tool that
44640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             tracks malloc() et al, by using vg_replace_malloc.c. */
4465d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
4466913473803432ee37d6edaf232e21978d4f426125bart          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
4467d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
4468bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          /* Memory pool support. */
4469bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
4470bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
4471bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
4472bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
44732c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
4474c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
4475c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
4476c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
4477d799418996812817596beaa8b59563e3f3cb2ddanjn
447839de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge          /* Allow printfs to valgrind log. */
4479c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* The first two pass the va_list argument by value, which
4480c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             assumes it is the same size as or smaller than a UWord,
4481c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             which generally isn't the case.  Hence are deprecated.
4482c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             The second two pass the vargs by reference and so are
4483c560fb380ac83ad1957d3fdf92751645a55cf167sewardj             immune to this problem. */
4484c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* both :: char* fmt, va_list vargs (DEPRECATED) */
448530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn          VG_USERREQ__PRINTF           = 0x1401,
44860140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
4487c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          /* both :: char* fmt, va_list* vargs */
4488c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
4489c560fb380ac83ad1957d3fdf92751645a55cf167sewardj          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
44900140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
44910140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          /* Stack support. */
44920140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_REGISTER   = 0x1501,
44930140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_DEREGISTER = 0x1502,
4494c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__STACK_CHANGE     = 0x1503,
4495c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
4496c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          /* Wine support */
44975c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
44985c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj
44995c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj          /* Querying of debug info. */
4500dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
4501dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
4502dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj          /* Disable/enable error reporting level.  Takes a single
4503dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             Word arg which is the delta to this thread's error
4504dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             disablement indicator.  Hence 1 disables or further
4505dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             disables errors, and -1 moves back towards enablement.
4506dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj             Other values are not allowed. */
4507bb913cd4cc1e56d7d7798a8b754361a05d01f916florian          VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801,
4508bb913cd4cc1e56d7d7798a8b754361a05d01f916florian
4509bb913cd4cc1e56d7d7798a8b754361a05d01f916florian          /* Initialise IR injection */
4510bb913cd4cc1e56d7d7798a8b754361a05d01f916florian          VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901
4511e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   } Vg_ClientRequest;
45122e93c50dc50235189661b70e3f27a4098d5cccccsewardj
45130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if !defined(__GNUC__)
45140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define __extension__ /* */
4515c9b365507e9bd5d500476e3e83f4d30f9c68a351mueller#endif
45162e93c50dc50235189661b70e3f27a4098d5cccccsewardj
4517fa5115adb77868b1ee3efc8dce061b881e7833c5bart
45180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Returns the number of Valgrinds this code is running under.  That
45190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   is, 0 if running natively, 1 if running under Valgrind, 2 if
45200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   running under Valgrind which is running under another Valgrind,
45210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   etc. */
4522fa5115adb77868b1ee3efc8dce061b881e7833c5bart#define RUNNING_ON_VALGRIND                                           \
4523575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
4524fa5115adb77868b1ee3efc8dce061b881e7833c5bart                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
4525fa5115adb77868b1ee3efc8dce061b881e7833c5bart                                    0, 0, 0, 0, 0)                    \
4526de4a1d01951937632098a6cda45859afa587a06fsewardj
4527de4a1d01951937632098a6cda45859afa587a06fsewardj
452818d7513cc08bf982711c8a22b70d56af6aa87b33sewardj/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
452918d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
453018d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   since it provides a way to make sure valgrind will retranslate the
453118d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   invalidated area.  Returns no value. */
45324b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
45334b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
45344b3a74204894e943c43cb8e8aae39d813040702csewardj                                    _qzz_addr, _qzz_len, 0, 0, 0)
453518d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
453626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
45370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These requests are for getting Valgrind itself to print something.
4538d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   Possibly with a backtrace.  This is a really ugly hack.  The return value
4539d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   is the number of characters printed, excluding the "**<pid>** " part at the
4540d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   start and the backtrace (if present). */
45410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
454242f83fe6c64da13801d4eb54fa2aa6530679848abart#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
45437eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj/* Modern GCC will optimize the static routine out if unused,
45447eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   and unused attribute will shut down warnings about it.  */
45457eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF(const char *format, ...)
45467eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
45477f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
45487eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
45490da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
45500da2c772047f3f6795dbb43dde5f5c9b43be73bbbart__inline
45510da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
4552a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF(const char *format, ...)
455339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
45548c7e25f496b1771f21712db0b1f35935bacfaff3bart#if defined(NVALGRIND)
45558c7e25f496b1771f21712db0b1f35935bacfaff3bart   return 0;
45568c7e25f496b1771f21712db0b1f35935bacfaff3bart#else /* NVALGRIND */
4557575ce8ef8fa86a502dabe152293320676922dcfebart#if defined(_MSC_VER)
4558575ce8ef8fa86a502dabe152293320676922dcfebart   uintptr_t _qzz_res;
4559575ce8ef8fa86a502dabe152293320676922dcfebart#else
4560c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
4561575ce8ef8fa86a502dabe152293320676922dcfebart#endif
4562c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_list vargs;
4563c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_start(vargs, format);
45640da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
4565575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
45660da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              VG_USERREQ__PRINTF_VALIST_BY_REF,
4567fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)format,
4568fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)&vargs,
45690da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              0, 0, 0);
45700da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#else
4571575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4572c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              VG_USERREQ__PRINTF_VALIST_BY_REF,
457305b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
4574c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              (unsigned long)&vargs,
45759af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
45760da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
4577c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_end(vargs);
4578c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
45798c7e25f496b1771f21712db0b1f35935bacfaff3bart#endif /* NVALGRIND */
458039de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
458139de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
458242f83fe6c64da13801d4eb54fa2aa6530679848abart#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
45837eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
45847eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
45857f489813d200fb614a0856fca05e2f9ebf66dd48bart#endif
45867eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
45870da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
45880da2c772047f3f6795dbb43dde5f5c9b43be73bbbart__inline
45890da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
4590a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF_BACKTRACE(const char *format, ...)
459139de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
45928c7e25f496b1771f21712db0b1f35935bacfaff3bart#if defined(NVALGRIND)
45938c7e25f496b1771f21712db0b1f35935bacfaff3bart   return 0;
45948c7e25f496b1771f21712db0b1f35935bacfaff3bart#else /* NVALGRIND */
4595575ce8ef8fa86a502dabe152293320676922dcfebart#if defined(_MSC_VER)
4596575ce8ef8fa86a502dabe152293320676922dcfebart   uintptr_t _qzz_res;
4597575ce8ef8fa86a502dabe152293320676922dcfebart#else
4598c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
4599575ce8ef8fa86a502dabe152293320676922dcfebart#endif
4600c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_list vargs;
4601c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_start(vargs, format);
46020da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#if defined(_MSC_VER)
4603575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
46040da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
4605fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)format,
4606fa5115adb77868b1ee3efc8dce061b881e7833c5bart                              (uintptr_t)&vargs,
46070da2c772047f3f6795dbb43dde5f5c9b43be73bbbart                              0, 0, 0);
46080da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#else
4609575ce8ef8fa86a502dabe152293320676922dcfebart   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
4610c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
461105b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
4612c560fb380ac83ad1957d3fdf92751645a55cf167sewardj                              (unsigned long)&vargs,
46139af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
46140da2c772047f3f6795dbb43dde5f5c9b43be73bbbart#endif
4615c560fb380ac83ad1957d3fdf92751645a55cf167sewardj   va_end(vargs);
4616c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
461739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#endif /* NVALGRIND */
46188c7e25f496b1771f21712db0b1f35935bacfaff3bart}
461918d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
46200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
46213e88418f808bf2840646504481d6a5be1df16541njn/* These requests allow control to move from the simulated CPU to the
46221319b49115bd0763628273b8a3fe08ac30712e31njn   real CPU, calling an arbitary function.
46231319b49115bd0763628273b8a3fe08ac30712e31njn
46241319b49115bd0763628273b8a3fe08ac30712e31njn   Note that the current ThreadId is inserted as the first argument.
46251319b49115bd0763628273b8a3fe08ac30712e31njn   So this call:
46261319b49115bd0763628273b8a3fe08ac30712e31njn
46271319b49115bd0763628273b8a3fe08ac30712e31njn     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
46281319b49115bd0763628273b8a3fe08ac30712e31njn
46291319b49115bd0763628273b8a3fe08ac30712e31njn   requires f to have this signature:
46301319b49115bd0763628273b8a3fe08ac30712e31njn
46311319b49115bd0763628273b8a3fe08ac30712e31njn     Word f(Word tid, Word arg1, Word arg2)
46321319b49115bd0763628273b8a3fe08ac30712e31njn
46331319b49115bd0763628273b8a3fe08ac30712e31njn   where "Word" is a word-sized type.
463445fb4d304f59e4e4cca917d372278eeb75be2c33njn
463545fb4d304f59e4e4cca917d372278eeb75be2c33njn   Note that these client requests are not entirely reliable.  For example,
463645fb4d304f59e4e4cca917d372278eeb75be2c33njn   if you call a function with them that subsequently calls printf(),
463745fb4d304f59e4e4cca917d372278eeb75be2c33njn   there's a high chance Valgrind will crash.  Generally, your prospects of
463845fb4d304f59e4e4cca917d372278eeb75be2c33njn   these working are made higher if the called function does not refer to
463945fb4d304f59e4e4cca917d372278eeb75be2c33njn   any global variables, and does not refer to any libc or other functions
464045fb4d304f59e4e4cca917d372278eeb75be2c33njn   (printf et al).  Any kind of entanglement with libc or dynamic linking is
464145fb4d304f59e4e4cca917d372278eeb75be2c33njn   likely to have a bad outcome, for tricky reasons which we've grappled
464245fb4d304f59e4e4cca917d372278eeb75be2c33njn   with a lot in the past.
46431319b49115bd0763628273b8a3fe08ac30712e31njn*/
46440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
4645575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
4646575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL0,     \
4647575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                      \
4648575ce8ef8fa86a502dabe152293320676922dcfebart                                    0, 0, 0, 0)
4649575ce8ef8fa86a502dabe152293320676922dcfebart
4650575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
4651575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4652575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL1,          \
4653575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                           \
4654575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, 0, 0, 0)
4655575ce8ef8fa86a502dabe152293320676922dcfebart
4656575ce8ef8fa86a502dabe152293320676922dcfebart#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
4657575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
4658575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL2,          \
4659575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                           \
4660575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, _qyy_arg2, 0, 0)
46613e88418f808bf2840646504481d6a5be1df16541njn
46620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
4663575ce8ef8fa86a502dabe152293320676922dcfebart    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
4664575ce8ef8fa86a502dabe152293320676922dcfebart                                    VG_USERREQ__CLIENT_CALL3,           \
4665575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_fn,                            \
4666575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg1, _qyy_arg2,               \
4667575ce8ef8fa86a502dabe152293320676922dcfebart                                    _qyy_arg3, 0)
46683e88418f808bf2840646504481d6a5be1df16541njn
46693e88418f808bf2840646504481d6a5be1df16541njn
46707cc9c239f785f2903b597cdb34418bed42d25331nethercote/* Counts the number of errors that have been recorded by a tool.  Nb:
46717cc9c239f785f2903b597cdb34418bed42d25331nethercote   the tool must record the errors with VG_(maybe_record_error)() or
467247363aba8fa03b094195bca99fc232ce5f85605dnjn   VG_(unique_error)() for them to be counted. */
46730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_COUNT_ERRORS                                     \
4674575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
4675575ce8ef8fa86a502dabe152293320676922dcfebart                               0 /* default return */,            \
46760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__COUNT_ERRORS,          \
4677575ce8ef8fa86a502dabe152293320676922dcfebart                               0, 0, 0, 0, 0)
467847363aba8fa03b094195bca99fc232ce5f85605dnjn
46793ac96953bf8c912a2aaa2870652dda8b9b75337bnjn/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
46803ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   when heap blocks are allocated in order to give accurate results.  This
46813ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happens automatically for the standard allocator functions such as
46823ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
46833ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   delete[], etc.
46843ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
46853ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   But if your program uses a custom allocator, this doesn't automatically
46863ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happen, and Valgrind will not do as well.  For example, if you allocate
46873ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   superblocks with mmap() and then allocates chunks of the superblocks, all
46883ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind's observations will be at the mmap() level and it won't know that
46893ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   the chunks should be considered separate entities.  In Memcheck's case,
46903ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that means you probably won't get heap block overrun detection (because
46913ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   there won't be redzones marked as unaddressable) and you definitely won't
46923ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   get any leak detection.
46933ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
46943ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   The following client requests allow a custom allocator to be annotated so
46953ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that it can be handled accurately by Valgrind.
46963ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
46973ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
46983ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   by a malloc()-like function.  For Memcheck (an illustrative case), this
46993ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   does two things:
47003ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47013ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been allocated.  This means any addresses
47023ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     within the block mentioned in error messages will be
47033ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     identified as belonging to the block.  It also means that if the block
47043ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     isn't freed it will be detected by the leak checker.
47053ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47063ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being addressable and undefined (if 'is_zeroed' is
47073ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     not set), or addressable and defined (if 'is_zeroed' is set).  This
47083ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     controls how accesses to the block by the program are handled.
47093ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47103ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   'addr' is the start of the usable block (ie. after any
47113ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
47123ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   can apply redzones -- these are blocks of padding at the start and end of
47133ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   each block.  Adding redzones is recommended as it makes it much more likely
47143ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
47153ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroed (or filled with another predictable value), as is the case for
47163ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   calloc().
47173ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47183ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
47193ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block -- that will be used by the client program -- is allocated.
47203ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   It's best to put it at the outermost level of the allocator if possible;
47213ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   for example, if you have a function my_alloc() which calls
47223ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   internal_alloc(), and the client request is put inside internal_alloc(),
47233ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   stack traces relating to the heap block will contain entries for both
47243ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   my_alloc() and internal_alloc(), which is probably not what you want.
47253ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
4726b965efb4990bdedc3215ffcca8ea566d25874d26njn   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
4727b965efb4990bdedc3215ffcca8ea566d25874d26njn   custom blocks from within a heap block, B, that has been allocated with
4728b965efb4990bdedc3215ffcca8ea566d25874d26njn   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
4729b965efb4990bdedc3215ffcca8ea566d25874d26njn   -- the custom blocks will take precedence.
4730b965efb4990bdedc3215ffcca8ea566d25874d26njn
47313ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
47323ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Memcheck, it does two things:
47333ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47343ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been deallocated.  This assumes that the
47353ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     block was annotated as having been allocated via
47363ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
47373ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47383ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being unaddressable.
47393ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47403ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
47413ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block is deallocated.
47423ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
4743913473803432ee37d6edaf232e21978d4f426125bart   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
4744913473803432ee37d6edaf232e21978d4f426125bart   Memcheck, it does four things:
4745913473803432ee37d6edaf232e21978d4f426125bart
4746913473803432ee37d6edaf232e21978d4f426125bart   - It records that the size of a block has been changed.  This assumes that
4747913473803432ee37d6edaf232e21978d4f426125bart     the block was annotated as having been allocated via
4748913473803432ee37d6edaf232e21978d4f426125bart     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
4749913473803432ee37d6edaf232e21978d4f426125bart
4750913473803432ee37d6edaf232e21978d4f426125bart   - If the block shrunk, it marks the freed memory as being unaddressable.
4751913473803432ee37d6edaf232e21978d4f426125bart
4752913473803432ee37d6edaf232e21978d4f426125bart   - If the block grew, it marks the new area as undefined and defines a red
4753913473803432ee37d6edaf232e21978d4f426125bart     zone past the end of the new block.
4754913473803432ee37d6edaf232e21978d4f426125bart
4755913473803432ee37d6edaf232e21978d4f426125bart   - The V-bits of the overlap between the old and the new block are preserved.
4756913473803432ee37d6edaf232e21978d4f426125bart
4757913473803432ee37d6edaf232e21978d4f426125bart   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
4758913473803432ee37d6edaf232e21978d4f426125bart   and before deallocation of the old block.
4759913473803432ee37d6edaf232e21978d4f426125bart
4760913473803432ee37d6edaf232e21978d4f426125bart   In many cases, these three client requests will not be enough to get your
47613ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator working well with Memcheck.  More specifically, if your allocator
47623ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
47633ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   will be necessary to mark the memory as addressable just before the zeroing
47643ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   occurs, otherwise you'll get a lot of invalid write errors.  For example,
47653ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   you'll need to do this if your allocator recycles freed blocks, but it
47663ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
47673ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Alternatively, if your allocator reuses freed blocks for allocator-internal
47683ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
47693ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
47703ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Really, what's happening is a blurring of the lines between the client
47713ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
47723ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   memory should be considered unaddressable to the client program, but the
47733ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator knows more than the rest of the client program and so may be able
47743ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   to safely access it.  Extra client requests are necessary for Valgrind to
47753ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   understand the distinction between the allocator and the rest of the
47763ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program.
47773ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
477832f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
47793ac96953bf8c912a2aaa2870652dda8b9b75337bnjn*/
47804b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
47814b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
47824b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, sizeB, rzB, is_zeroed, 0)
4783d799418996812817596beaa8b59563e3f3cb2ddanjn
478432f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
478532f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
478632f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn*/
47874b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
47884b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
47894b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, oldSizeB, newSizeB, rzB, 0)
4790913473803432ee37d6edaf232e21978d4f426125bart
4791913473803432ee37d6edaf232e21978d4f426125bart/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
4792913473803432ee37d6edaf232e21978d4f426125bart   Ignored if addr == 0.
4793913473803432ee37d6edaf232e21978d4f426125bart*/
47944b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
47954b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
47964b3a74204894e943c43cb8e8aae39d813040702csewardj                                    addr, rzB, 0, 0, 0)
4797d799418996812817596beaa8b59563e3f3cb2ddanjn
4798bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Create a memory pool. */
47990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
48004b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
48014b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, rzB, is_zeroed, 0, 0)
4802bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4803bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Destroy a memory pool. */
48040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
48054b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
48064b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, 0, 0, 0, 0)
4807bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4808bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Associate a piece of memory with a memory pool. */
48090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
48104b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
48114b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, size, 0, 0)
4812bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4813bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Disassociate a piece of memory from a memory pool. */
48140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
48154b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
48164b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, 0, 0, 0)
4817bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
48182c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj/* Disassociate any pieces outside a particular range. */
48192c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
48204b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
48214b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addr, size, 0, 0)
48222c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj
4823c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
4824c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
48254b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
48264b3a74204894e943c43cb8e8aae39d813040702csewardj                                    poolA, poolB, 0, 0, 0)
4827c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
4828c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
4829c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
48304b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
48314b3a74204894e943c43cb8e8aae39d813040702csewardj                                    pool, addrA, addrB, size, 0)
4832c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
4833c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Return 1 if a mempool exists, else 0. */
4834c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
4835575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
4836c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_EXISTS,        \
4837575ce8ef8fa86a502dabe152293320676922dcfebart                               pool, 0, 0, 0, 0)
4838c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
48390140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Mark a piece of memory as being a stack. Returns a stack id. */
48400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_REGISTER(start, end)                       \
4841575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
48420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_REGISTER,        \
4843575ce8ef8fa86a502dabe152293320676922dcfebart                               start, end, 0, 0, 0)
48440140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
48450140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Unmark the piece of memory associated with a stack id as being a
48460140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   stack. */
48470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_DEREGISTER(id)                             \
48484b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
48494b3a74204894e943c43cb8e8aae39d813040702csewardj                                    id, 0, 0, 0, 0)
48500140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
48510140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Change the start and end address of the stack id. */
48520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_CHANGE(id, start, end)                     \
48534b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
48544b3a74204894e943c43cb8e8aae39d813040702csewardj                                    id, start, end, 0, 0)
48550140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
4856c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* Load PDB debug info for Wine PE image_map. */
48574b3a74204894e943c43cb8e8aae39d813040702csewardj#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
48584b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
48594b3a74204894e943c43cb8e8aae39d813040702csewardj                                    fd, ptr, total_size, delta, 0)
4860c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
48615c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj/* Map a code address to a source file name and line number.  buf64
48625c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   must point to a 64-byte buffer in the caller's address space.  The
48635c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   result will be dumped in there and is guaranteed to be zero
48645c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj   terminated.  If no info is found, the first byte is set to zero. */
48655c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
4866575ce8ef8fa86a502dabe152293320676922dcfebart    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
48675c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
4868575ce8ef8fa86a502dabe152293320676922dcfebart                               addr, buf64, 0, 0, 0)
48695c65962f59fb226d327a4860dfab27a1b19ce2e3sewardj
4870dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj/* Disable error reporting for this thread.  Behaves in a stack like
4871dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   way, so you can safely call this multiple times provided that
4872dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
4873dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   to re-enable reporting.  The first call of this macro disables
4874dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   reporting.  Subsequent calls have no effect except to increase the
4875dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
4876dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   reporting.  Child threads do not inherit this setting from their
4877dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   parents -- they are always created with reporting enabled. */
487806e9bf06cf953602adaf5e2a0a3f5522e4dc7f50bart#define VALGRIND_DISABLE_ERROR_REPORTING                                \
48794b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
48804b3a74204894e943c43cb8e8aae39d813040702csewardj                                    1, 0, 0, 0, 0)
4881dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
4882dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj/* Re-enable error reporting, as per comments on
4883dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   VALGRIND_DISABLE_ERROR_REPORTING. */
488406e9bf06cf953602adaf5e2a0a3f5522e4dc7f50bart#define VALGRIND_ENABLE_ERROR_REPORTING                                 \
48854b3a74204894e943c43cb8e8aae39d813040702csewardj    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
48864b3a74204894e943c43cb8e8aae39d813040702csewardj                                    -1, 0, 0, 0, 0)
48870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4888c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_x86_darwin
4889c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_amd64_darwin
4890c112c8ea1262761630f2f17ada4d53697b1242fasewardj#undef PLAT_x86_win32
4891f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
4892f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
4893f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
4894f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
489559570ffbe31930ab4d678754daaeec0715117a3dsewardj#undef PLAT_arm_linux
4896b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#undef PLAT_s390x_linux
48975db15403e889d4db339b342bc2a824ef0bfaa654sewardj#undef PLAT_mips32_linux
48980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
48993e88418f808bf2840646504481d6a5be1df16541njn#endif   /* __VALGRIND_H */
4900