valgrind.h revision c8259b85b701d25d72aabe9dc0a8154517f96913
1ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/* -*- c -*-
2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe   ----------------------------------------------------------------
3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe
4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe   Notice that the following BSD-style license applies to this one
5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe   file (valgrind.h) only.  The rest of Valgrind is licensed under the
6ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   terms of the GNU General Public License, version 2, unless
7ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   otherwise indicated.  See the COPYING file in the source
8ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   distribution for details.
9ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
10ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   ----------------------------------------------------------------
11ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
12ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   This file is part of Valgrind, a dynamic binary instrumentation
13ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   framework.
14ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
155fdd124a3b811993542825847f207587d5f4661eJens Axboe   Copyright (C) 2000-2009 Julian Seward.  All rights reserved.
167292056a38857ded6f7a64f11d14d642772c31bdJens Axboe
170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   Redistribution and use in source and binary forms, with or without
187292056a38857ded6f7a64f11d14d642772c31bdJens Axboe   modification, are permitted provided that the following conditions
190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   are met:
20ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
21ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   1. Redistributions of source code must retain the above copyright
22ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      notice, this list of conditions and the following disclaimer.
23b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
24b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   2. The origin of this software must not be misrepresented; you must
259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      not claim that you wrote the original software.  If you use this
269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      software in a product, an acknowledgment in the product
27b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      documentation would be appreciated but is not required.
280fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
29b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   3. Altered source versions must be plainly marked as such, and must
30ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      not be misrepresented as being the original software.
31de890a1e48d40238dac69f302708dde8719de240Steven Lang
32de890a1e48d40238dac69f302708dde8719de240Steven Lang   4. The name of the author may not be used to endorse or promote
33de890a1e48d40238dac69f302708dde8719de240Steven Lang      products derived from this software without specific prior written
34de890a1e48d40238dac69f302708dde8719de240Steven Lang      permission.
35de890a1e48d40238dac69f302708dde8719de240Steven Lang
366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37de890a1e48d40238dac69f302708dde8719de240Steven Lang   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38de890a1e48d40238dac69f302708dde8719de240Steven Lang   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46b96d243044023b28731341d290943b5d47a5f794Jens Axboe   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47b96d243044023b28731341d290943b5d47a5f794Jens Axboe
480fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   ----------------------------------------------------------------
490fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   Notice that the above BSD-style license applies to this one file
510fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   (valgrind.h) only.  The entire rest of Valgrind is licensed under
52664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   the terms of the GNU General Public License, version 2.  See the
53664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   COPYING file in the source distribution for details.
54de890a1e48d40238dac69f302708dde8719de240Steven Lang
55de890a1e48d40238dac69f302708dde8719de240Steven Lang   ----------------------------------------------------------------
56de890a1e48d40238dac69f302708dde8719de240Steven Lang*/
57de890a1e48d40238dac69f302708dde8719de240Steven Lang
58de890a1e48d40238dac69f302708dde8719de240Steven Lang
59de890a1e48d40238dac69f302708dde8719de240Steven Lang/* This file is for inclusion into client (your!) code.
60de890a1e48d40238dac69f302708dde8719de240Steven Lang
61de890a1e48d40238dac69f302708dde8719de240Steven Lang   You can use these macros to manipulate and query Valgrind's
62de890a1e48d40238dac69f302708dde8719de240Steven Lang   execution inside your own programs.
63de890a1e48d40238dac69f302708dde8719de240Steven Lang
64de890a1e48d40238dac69f302708dde8719de240Steven Lang   The resulting executables will still run without Valgrind, just a
65de890a1e48d40238dac69f302708dde8719de240Steven Lang   little bit more slowly than they otherwise would, but otherwise
66de890a1e48d40238dac69f302708dde8719de240Steven Lang   unchanged.  When not running on valgrind, each client request
67de890a1e48d40238dac69f302708dde8719de240Steven Lang   consumes very few (eg. 7) instructions, so the resulting performance
68de890a1e48d40238dac69f302708dde8719de240Steven Lang   loss is negligible unless you plan to execute client requests
69de890a1e48d40238dac69f302708dde8719de240Steven Lang   millions of times per second.  Nevertheless, if that is still a
70de890a1e48d40238dac69f302708dde8719de240Steven Lang   problem, you can compile with the NVALGRIND symbol defined (gcc
71de890a1e48d40238dac69f302708dde8719de240Steven Lang   -DNVALGRIND) so that client requests are not even compiled in.  */
72de890a1e48d40238dac69f302708dde8719de240Steven Lang
73de890a1e48d40238dac69f302708dde8719de240Steven Lang#ifndef __VALGRIND_H
74de890a1e48d40238dac69f302708dde8719de240Steven Lang#define __VALGRIND_H
75de890a1e48d40238dac69f302708dde8719de240Steven Lang
76de890a1e48d40238dac69f302708dde8719de240Steven Lang#include <stdarg.h>
77de890a1e48d40238dac69f302708dde8719de240Steven Lang
78de890a1e48d40238dac69f302708dde8719de240Steven Lang/* Nb: this file might be included in a file compiled with -ansi.  So
79de890a1e48d40238dac69f302708dde8719de240Steven Lang   we can't use C++ style "//" comments nor the "asm" keyword (instead
80de890a1e48d40238dac69f302708dde8719de240Steven Lang   use "__asm__"). */
81de890a1e48d40238dac69f302708dde8719de240Steven Lang
82de890a1e48d40238dac69f302708dde8719de240Steven Lang/* Derive some tags indicating what the target platform is.  Note
83de890a1e48d40238dac69f302708dde8719de240Steven Lang   that in this file we're using the compiler's CPP symbols for
84f5cc3d0ea8acf13c8e722da6c2d485889968d132Bruce Cran   identifying architectures, which are different to the ones we use
85de890a1e48d40238dac69f302708dde8719de240Steven Lang   within the rest of Valgrind.  Note, __powerpc__ is active for both
86de890a1e48d40238dac69f302708dde8719de240Steven Lang   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
87de890a1e48d40238dac69f302708dde8719de240Steven Lang   latter (on Linux, that is). */
88de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_x86_linux
89de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_amd64_linux
90de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_ppc32_linux
91de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_ppc64_linux
92de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_ppc32_aix5
93de890a1e48d40238dac69f302708dde8719de240Steven Lang#undef PLAT_ppc64_aix5
94de890a1e48d40238dac69f302708dde8719de240Steven Lang
95de890a1e48d40238dac69f302708dde8719de240Steven Lang#if !defined(_AIX) && defined(__i386__)
96de890a1e48d40238dac69f302708dde8719de240Steven Lang#  define PLAT_x86_linux 1
97de890a1e48d40238dac69f302708dde8719de240Steven Lang#elif !defined(_AIX) && defined(__x86_64__)
98de890a1e48d40238dac69f302708dde8719de240Steven Lang#  define PLAT_amd64_linux 1
996f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
1006f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#  define PLAT_ppc32_linux 1
1016f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
1026f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#  define PLAT_ppc64_linux 1
1036f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#elif defined(_AIX) && defined(__64BIT__)
1046f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#  define PLAT_ppc64_aix5 1
105de890a1e48d40238dac69f302708dde8719de240Steven Lang#elif defined(_AIX) && !defined(__64BIT__)
106de890a1e48d40238dac69f302708dde8719de240Steven Lang#  define PLAT_ppc32_aix5 1
107de890a1e48d40238dac69f302708dde8719de240Steven Lang#endif
108de890a1e48d40238dac69f302708dde8719de240Steven Lang
109371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
110371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* If we're not compiling for our target platform, don't generate
111371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe   any inline asms.  */
112371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
113371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe    && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
114371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe    && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
115371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#  if !defined(NVALGRIND)
116371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#    define NVALGRIND 1
117371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#  endif
118371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#endif
119371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
120371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
121371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* ------------------------------------------------------------------ */
122371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
123371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* in here of use to end-users -- skip to the next section.           */
124d5b388a560783a61af7b424757bc6dead2309c28Jens Axboe/* ------------------------------------------------------------------ */
125371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
126371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#if defined(NVALGRIND)
127371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
128371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe/* Define NVALGRIND to completely remove the Valgrind magic sequence
129371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe   from the compiled code (analogous to NDEBUG's effects on
130371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe   assert()) */
131371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
132371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
133371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
134371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe   {                                                              \
135371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe      (_zzq_rlval) = (_zzq_default);                              \
136371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe   }
137371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
138371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe#else  /* ! NVALGRIND */
139371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe
140ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe/* The following defines the magic code sequences which the JITter
141ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   spots and handles magically.  Don't look too closely at them as
142de890a1e48d40238dac69f302708dde8719de240Steven Lang   they will rot your brain.
143ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
1447a6499dada619928267d26b4629b0c8623dc423aJens Axboe   The assembly code sequences for all architectures is in this one
1457a6499dada619928267d26b4629b0c8623dc423aJens Axboe   file.  This is because this file must be stand-alone, and we don't
1467a6499dada619928267d26b4629b0c8623dc423aJens Axboe   want to have multiple files.
147de890a1e48d40238dac69f302708dde8719de240Steven Lang
148de890a1e48d40238dac69f302708dde8719de240Steven Lang   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
149de890a1e48d40238dac69f302708dde8719de240Steven Lang   value gets put in the return slot, so that everything works when
150de890a1e48d40238dac69f302708dde8719de240Steven Lang   this is executed not under Valgrind.  Args are passed in a memory
151de890a1e48d40238dac69f302708dde8719de240Steven Lang   block, and so there's no intrinsic limit to the number that could
152e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe   be passed, but it's currently five.
1537a6499dada619928267d26b4629b0c8623dc423aJens Axboe
154ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   The macro args are:
1553f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran      _zzq_rlval    result lvalue
156f85ac25a7d5c9d5ba4d5c73363a6a2a461a9b013Jens Axboe      _zzq_default  default value (result returned when running on real CPU)
157ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _zzq_request  request code
158ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _zzq_arg1..5  request params
1595921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
160cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe   The other two macros are used to support function wrapping, and are
161ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
1629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   guest's NRADDR pseudo-register and whatever other information is
1637a6499dada619928267d26b4629b0c8623dc423aJens Axboe   needed to safely run the call original from the wrapper: on
1649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   ppc64-linux, the R2 value at the divert point is also needed.  This
165cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe   information is abstracted into a user-visible type, OrigFn.
1669cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1679cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
1689cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   guest, but guarantees that the branch instruction will not be
1699cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
1709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
1719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   complete inline asm, since it needs to be combined with more magic
1729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   inline asm stuff to be useful.
1739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe*/
1749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1759cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* ------------------------- x86-linux ------------------------- */
176f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe
1779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#if defined(PLAT_x86_linux)
1789cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
1799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboetypedef
1809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   struct {
1819cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      unsigned int nraddr; /* where's the code? */
1829cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   }
183cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe   OrigFn;
1849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
185cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
1869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
1879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "roll $29, %%edi ; roll $19, %%edi\n\t"
1889cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
189cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
1909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
1919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
1929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  { volatile unsigned int _zzq_args[6];                           \
193cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    volatile unsigned int _zzq_result;                            \
1949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
195cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
196cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
1979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
1989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
199cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
200cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
201cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     /* %EDX = client_request ( %EAX ) */         \
202cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     "xchgl %%ebx,%%ebx"                          \
203cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     : "=d" (_zzq_result)                         \
204cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "cc", "memory"                             \
2069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                    );                                            \
2079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_rlval = _zzq_result;                                     \
2089cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  }
2099cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2109cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
2119cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
212cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    volatile unsigned int __addr;                                 \
2139cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2149cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     /* %EAX = guest_NRADDR */                    \
2159cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "xchgl %%ecx,%%ecx"                          \
2169cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "=a" (__addr)                              \
2179cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     :                                            \
2189cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "cc", "memory"                             \
2199cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                    );                                            \
2209cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_orig->nraddr = __addr;                                   \
2219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  }
222cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
223f657a2fbbb0deaf455edc478d73b664929bcb766Jens Axboe#define VALGRIND_CALL_NOREDIR_EAX                                 \
2249cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2259cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     /* call-noredir *%EAX */                     \
2269cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "xchgl %%edx,%%edx\n\t"
227cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#endif /* PLAT_x86_linux */
2289cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
2299cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe/* ------------------------ amd64-linux ------------------------ */
2309cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
231cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#if defined(PLAT_amd64_linux)
2329cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
233cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboetypedef
234cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe   struct {
2359cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      unsigned long long int nraddr; /* where's the code? */
2369cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   }
2379cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   OrigFn;
238cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
239cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2409cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
241cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
242cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
243cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
244cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
245cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
246cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe  { volatile unsigned long long int _zzq_args[6];                 \
247ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe    volatile unsigned long long int _zzq_result;                  \
248cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
2499cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
2509cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
251cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
252cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
253cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
254cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     /* %RDX = client_request ( %RAX ) */         \
2569cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "xchgq %%rbx,%%rbx"                          \
2579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "=d" (_zzq_result)                         \
2589cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2599cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "cc", "memory"                             \
260cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                    );                                            \
261cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    _zzq_rlval = _zzq_result;                                     \
2629cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  }
263cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
2649cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
2659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
266cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    volatile unsigned long long int __addr;                       \
267cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
268cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     /* %RAX = guest_NRADDR */                    \
269cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     "xchgq %%rcx,%%rcx"                          \
2709cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "=a" (__addr)                              \
2719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     :                                            \
2729cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "cc", "memory"                             \
2739cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                    );                                            \
2749cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_orig->nraddr = __addr;                                   \
275cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe  }
276cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe
2779cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#define VALGRIND_CALL_NOREDIR_RAX                                 \
278cd963e18de21e08ebb2ed86366f07347b4c58e3dJens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     /* call-noredir *%RAX */                     \
2805921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe                     "xchgq %%rdx,%%rdx\n\t"
2815921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#endif /* PLAT_amd64_linux */
2825921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
283af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe/* ------------------------ ppc32-linux ------------------------ */
2845921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
2855921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#if defined(PLAT_ppc32_linux)
2865921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
2875921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboetypedef
2885921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe   struct {
289af8771b9b91eb2cd23a40aaa729bad4f78acb928Jens Axboe      unsigned int nraddr; /* where's the code? */
2905921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe   }
2915921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe   OrigFn;
2925921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
2939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
2959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
296414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
297de890a1e48d40238dac69f302708dde8719de240Steven Lang#define VALGRIND_DO_CLIENT_REQUEST(                               \
2986f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
299371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
300664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                                                                  \
301de890a1e48d40238dac69f302708dde8719de240Steven Lang  {          unsigned int  _zzq_args[6];                          \
30262b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe             unsigned int  _zzq_result;                           \
30362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe             unsigned int* _zzq_ptr;                              \
304664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
30562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
30662b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
307664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
308664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
309664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
310664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_ptr = _zzq_args;                                         \
3115921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
3126f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     "mr 4,%2\n\t" /*ptr*/                        \
3136f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
314664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* %R3 = client_request ( %R4 ) */           \
3155921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe                     "or 1,1,1\n\t"                               \
316664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "mr %0,3"     /*result*/                     \
317664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "=b" (_zzq_result)                         \
318664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
319664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "cc", "memory", "r3", "r4");               \
320664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_rlval = _zzq_result;                                     \
3219cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  }
322664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
323664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
324664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
325664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    unsigned int __addr;                                          \
326664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
327664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* %R3 = guest_NRADDR */                     \
328664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "or 2,2,2\n\t"                               \
329664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "mr %0,3"                                    \
330664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "=b" (__addr)                              \
331664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     :                                            \
332664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "cc", "memory", "r3"                       \
333664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                    );                                            \
334664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_orig->nraddr = __addr;                                   \
335664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe  }
336664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
337664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
338b96d243044023b28731341d290943b5d47a5f794Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
339664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* branch-and-link-to-noredir *%R11 */       \
340664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "or 3,3,3\n\t"
341664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe#endif /* PLAT_ppc32_linux */
342664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
343664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* ------------------------ ppc64-linux ------------------------ */
3449cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3459cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe#if defined(PLAT_ppc64_linux)
346414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
3479cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboetypedef
348414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe   struct {
349de890a1e48d40238dac69f302708dde8719de240Steven Lang      unsigned long long int nraddr; /* where's the code? */
3506f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe      unsigned long long int r2;  /* what tocptr do we need? */
351664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   }
352664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe   OrigFn;
353de890a1e48d40238dac69f302708dde8719de240Steven Lang
3545ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
35562b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
356664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
357664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
35862b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
359664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
360664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
361664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                                                                  \
362664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe  {          unsigned long long int  _zzq_args[6];                \
363664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    register unsigned long long int  _zzq_result __asm__("r3");   \
364664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    register unsigned long long int* _zzq_ptr __asm__("r4");      \
365664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
366664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
367664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
368664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
3697d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
3707d988f68c7f0ff6bd4c9e558c4defbd9a544b167Jens Axboe    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
3719cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_ptr = _zzq_args;                                         \
372664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
373664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* %R3 = client_request ( %R4 ) */           \
374664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "or 1,1,1"                                   \
375664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "=r" (_zzq_result)                         \
376664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "0" (_zzq_default), "r" (_zzq_ptr)         \
377414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe                     : "cc", "memory");                           \
378664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_rlval = _zzq_result;                                     \
3799cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe  }
3809cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe
3816f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
3826f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
3839cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    register unsigned long long int __addr __asm__("r3");         \
3849cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
385de890a1e48d40238dac69f302708dde8719de240Steven Lang                     /* %R3 = guest_NRADDR */                     \
3869cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     "or 2,2,2"                                   \
3879cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                     : "=r" (__addr)                              \
3886f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     :                                            \
389de890a1e48d40238dac69f302708dde8719de240Steven Lang                     : "cc", "memory"                             \
390de890a1e48d40238dac69f302708dde8719de240Steven Lang                    );                                            \
3919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe    _zzq_orig->nraddr = __addr;                                   \
392414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
393414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe                     /* %R3 = guest_NRADDR_GPR2 */                \
3946f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     "or 4,4,4"                                   \
395de890a1e48d40238dac69f302708dde8719de240Steven Lang                     : "=r" (__addr)                              \
396de890a1e48d40238dac69f302708dde8719de240Steven Lang                     :                                            \
397414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe                     : "cc", "memory"                             \
3989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe                    );                                            \
399414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    _zzq_orig->r2 = __addr;                                       \
400d4f12dd05cfb2e8e7a72604cd870e10f2394914eJens Axboe  }
4017a6499dada619928267d26b4629b0c8623dc423aJens Axboe
402ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
403cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
40422819ec237297fc39435ed566bee01a4225bfb39Jens Axboe                     /* branch-and-link-to-noredir *%R11 */       \
405cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe                     "or 3,3,3\n\t"
406cec6b55da1c282b5b91ad346c7804171fccf151eJens Axboe
40736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe#endif /* PLAT_ppc64_linux */
408414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
409414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe/* ------------------------ ppc32-aix5 ------------------------- */
410414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
4116f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#if defined(PLAT_ppc32_aix5)
412414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe
413414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboetypedef
414414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe   struct {
415414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe      unsigned int nraddr; /* where's the code? */
416ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      unsigned int r2;  /* what tocptr do we need? */
417ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   }
41836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe   OrigFn;
419e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe
420ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
42136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
422ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
423ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
4246f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
4256f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
4266f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
4276f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                                                                  \
4286f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe  {          unsigned int  _zzq_args[7];                          \
4296f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    register unsigned int  _zzq_result;                           \
4306f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    register unsigned int* _zzq_ptr;                              \
4316f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
4326f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
4336f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
4346f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
4356f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
4366f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
4376f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
4386f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    _zzq_ptr = _zzq_args;                                         \
4396f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe    __asm__ volatile("mr 4,%1\n\t"                                \
4406f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     "lwz 3, 24(4)\n\t"                           \
4416f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4426f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     /* %R3 = client_request ( %R4 ) */           \
4436f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     "or 1,1,1\n\t"                               \
4446f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     "mr %0,3"                                    \
4456f73a7f8e2498f96aeb3df6cefba2496e17aad77Jens Axboe                     : "=b" (_zzq_result)                         \
446b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     : "b" (_zzq_ptr)                             \
447ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe                     : "r3", "r4", "cc", "memory");               \
448b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe    _zzq_rlval = _zzq_result;                                     \
449de890a1e48d40238dac69f302708dde8719de240Steven Lang  }
4500fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
451414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
452de890a1e48d40238dac69f302708dde8719de240Steven Lang  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
4530fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe    register unsigned int __addr;                                 \
454414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
455de890a1e48d40238dac69f302708dde8719de240Steven Lang                     /* %R3 = guest_NRADDR */                     \
4560fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     "or 2,2,2\n\t"                               \
457414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe                     "mr %0,3"                                    \
458de890a1e48d40238dac69f302708dde8719de240Steven Lang                     : "=b" (__addr)                              \
4590fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     :                                            \
4600fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     : "r3", "cc", "memory"                       \
4610fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                    );                                            \
462de890a1e48d40238dac69f302708dde8719de240Steven Lang    _zzq_orig->nraddr = __addr;                                   \
4630fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
4640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     /* %R3 = guest_NRADDR_GPR2 */                \
4650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     "or 4,4,4\n\t"                               \
466ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe                     "mr %0,3"                                    \
4670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     : "=b" (__addr)                              \
468b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     :                                            \
469b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     : "r3", "cc", "memory"                       \
470b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                    );                                            \
471ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe    _zzq_orig->r2 = __addr;                                       \
472ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe  }
473de890a1e48d40238dac69f302708dde8719de240Steven Lang
474414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
475de890a1e48d40238dac69f302708dde8719de240Steven Lang                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     /* branch-and-link-to-noredir *%R11 */       \
477414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe                     "or 3,3,3\n\t"
4780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#endif /* PLAT_ppc32_aix5 */
480b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe
4810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe/* ------------------------ ppc64-aix5 ------------------------- */
4820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#if defined(PLAT_ppc64_aix5)
4840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
4850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboetypedef
4860fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   struct {
4870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      unsigned long long int nraddr; /* where's the code? */
4880fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      unsigned long long int r2;  /* what tocptr do we need? */
4890fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   }
4900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   OrigFn;
491b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe
4920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
4930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
494ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
495ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
496ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#define VALGRIND_DO_CLIENT_REQUEST(                               \
497ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe        _zzq_rlval, _zzq_default, _zzq_request,                   \
498ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
499b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                                                                  \
5005fdd124a3b811993542825847f207587d5f4661eJens Axboe  {          unsigned long long int  _zzq_args[7];                \
501b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe    register unsigned long long int  _zzq_result;                 \
502de890a1e48d40238dac69f302708dde8719de240Steven Lang    register unsigned long long int* _zzq_ptr;                    \
5035ba13ea6968cf2773f10d34376afe28ef81aeee5Jens Axboe    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
504859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
5055fdd124a3b811993542825847f207587d5f4661eJens Axboe    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
506de890a1e48d40238dac69f302708dde8719de240Steven Lang    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
507414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
508414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
509414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
510414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe    _zzq_ptr = _zzq_args;                                         \
511859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe    __asm__ volatile("mr 4,%1\n\t"                                \
512859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     "ld 3, 48(4)\n\t"                            \
513859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
5146d86144dd10b05e8b82e9b895c35dd778e5e71abJens Axboe                     /* %R3 = client_request ( %R4 ) */           \
5155fdd124a3b811993542825847f207587d5f4661eJens Axboe                     "or 1,1,1\n\t"                               \
516371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe                     "mr %0,3"                                    \
517859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     : "=b" (_zzq_result)                         \
5180c09442b26216aed16f758712f744a2c54726cdbJens Axboe                     : "b" (_zzq_ptr)                             \
519371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe                     : "r3", "r4", "cc", "memory");               \
520371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe    _zzq_rlval = _zzq_result;                                     \
521371d456c48b73c8a424e4c807c511fc891a38e7dJens Axboe  }
522859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe
523b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
5245fdd124a3b811993542825847f207587d5f4661eJens Axboe  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
5250cae16ffe3e4ca17cdb88fe64d357b7cde643f6aJens Axboe    register unsigned long long int __addr;                       \
526859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
527b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     /* %R3 = guest_NRADDR */                     \
528859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     "or 2,2,2\n\t"                               \
529859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     "mr %0,3"                                    \
530859088d3939ce6eccfc59a0d5559922e29e58a47Jens Axboe                     : "=b" (__addr)                              \
531b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     :                                            \
532b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe                     : "r3", "cc", "memory"                       \
533664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                    );                                            \
534664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    _zzq_orig->nraddr = __addr;                                   \
535664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
536664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* %R3 = guest_NRADDR_GPR2 */                \
53762b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe                     "or 4,4,4\n\t"                               \
538664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "mr %0,3"                                    \
539664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "=b" (__addr)                              \
540b96d243044023b28731341d290943b5d47a5f794Jens Axboe                     :                                            \
541664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     : "r3", "cc", "memory"                       \
542664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                    );                                            \
54362b38926a8f02a03534813fc80e73e5e169bf03eJens Axboe    _zzq_orig->r2 = __addr;                                       \
544664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe  }
545664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
546664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
547664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     __SPECIAL_INSTRUCTION_PREAMBLE               \
548664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     /* branch-and-link-to-noredir *%R11 */       \
549664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe                     "or 3,3,3\n\t"
550664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
551de890a1e48d40238dac69f302708dde8719de240Steven Lang#endif /* PLAT_ppc64_aix5 */
552664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
553664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* Insert assembly code for other platforms here... */
554664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
555664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe#endif /* NVALGRIND */
556664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
557de890a1e48d40238dac69f302708dde8719de240Steven Lang
558664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* ------------------------------------------------------------------ */
559664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
560664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* ugly.  It's the least-worst tradeoff I can think of.               */
561664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe/* ------------------------------------------------------------------ */
562664fb3bde9ed3b61d0520b6b4f3d0ba9599834b0Jens Axboe
563b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* This section defines magic (a.k.a appalling-hack) macros for doing
564b96d243044023b28731341d290943b5d47a5f794Jens Axboe   guaranteed-no-redirection macros, so as to get from function
565b96d243044023b28731341d290943b5d47a5f794Jens Axboe   wrappers to the functions they are wrapping.  The whole point is to
566b96d243044023b28731341d290943b5d47a5f794Jens Axboe   construct standard call sequences, but to do the call itself with a
567b96d243044023b28731341d290943b5d47a5f794Jens Axboe   special no-redirect call pseudo-instruction that the JIT
568b96d243044023b28731341d290943b5d47a5f794Jens Axboe   understands and handles specially.  This section is long and
569b96d243044023b28731341d290943b5d47a5f794Jens Axboe   repetitious, and I can't see a way to make it shorter.
570b96d243044023b28731341d290943b5d47a5f794Jens Axboe
571b96d243044023b28731341d290943b5d47a5f794Jens Axboe   The naming scheme is as follows:
572b96d243044023b28731341d290943b5d47a5f794Jens Axboe
573b96d243044023b28731341d290943b5d47a5f794Jens Axboe      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
574b96d243044023b28731341d290943b5d47a5f794Jens Axboe
575b96d243044023b28731341d290943b5d47a5f794Jens Axboe   'W' stands for "word" and 'v' for "void".  Hence there are
576b96d243044023b28731341d290943b5d47a5f794Jens Axboe   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
577b96d243044023b28731341d290943b5d47a5f794Jens Axboe   and for each, the possibility of returning a word-typed result, or
578b96d243044023b28731341d290943b5d47a5f794Jens Axboe   no result.
579b96d243044023b28731341d290943b5d47a5f794Jens Axboe*/
580b96d243044023b28731341d290943b5d47a5f794Jens Axboe
581b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* Use these to write the name of your wrapper.  NOTE: duplicates
582b96d243044023b28731341d290943b5d47a5f794Jens Axboe   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
583b96d243044023b28731341d290943b5d47a5f794Jens Axboe
584b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
585b96d243044023b28731341d290943b5d47a5f794Jens Axboe   _vgwZU_##soname##_##fnname
586b96d243044023b28731341d290943b5d47a5f794Jens Axboe
587b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
588b96d243044023b28731341d290943b5d47a5f794Jens Axboe   _vgwZZ_##soname##_##fnname
589b96d243044023b28731341d290943b5d47a5f794Jens Axboe
590b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* Use this macro from within a wrapper function to collect the
591b96d243044023b28731341d290943b5d47a5f794Jens Axboe   context (address and possibly other info) of the original function.
592b96d243044023b28731341d290943b5d47a5f794Jens Axboe   Once you have that you can then use it in one of the CALL_FN_
593b96d243044023b28731341d290943b5d47a5f794Jens Axboe   macros.  The type of the argument _lval is OrigFn. */
594b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
595b96d243044023b28731341d290943b5d47a5f794Jens Axboe
596b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* Derivatives of the main macros below, for calling functions
597b96d243044023b28731341d290943b5d47a5f794Jens Axboe   returning void. */
598b96d243044023b28731341d290943b5d47a5f794Jens Axboe
599b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define CALL_FN_v_v(fnptr)                                        \
600b96d243044023b28731341d290943b5d47a5f794Jens Axboe   do { volatile unsigned long _junk;                             \
601b96d243044023b28731341d290943b5d47a5f794Jens Axboe        CALL_FN_W_v(_junk,fnptr); } while (0)
602b96d243044023b28731341d290943b5d47a5f794Jens Axboe
603b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define CALL_FN_v_W(fnptr, arg1)                                  \
604b96d243044023b28731341d290943b5d47a5f794Jens Axboe   do { volatile unsigned long _junk;                             \
605b96d243044023b28731341d290943b5d47a5f794Jens Axboe        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
606b96d243044023b28731341d290943b5d47a5f794Jens Axboe
607b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
608b96d243044023b28731341d290943b5d47a5f794Jens Axboe   do { volatile unsigned long _junk;                             \
609b96d243044023b28731341d290943b5d47a5f794Jens Axboe        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
610b96d243044023b28731341d290943b5d47a5f794Jens Axboe
611b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
612b96d243044023b28731341d290943b5d47a5f794Jens Axboe   do { volatile unsigned long _junk;                             \
613b96d243044023b28731341d290943b5d47a5f794Jens Axboe        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
614b96d243044023b28731341d290943b5d47a5f794Jens Axboe
615b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* ------------------------- x86-linux ------------------------- */
616b96d243044023b28731341d290943b5d47a5f794Jens Axboe
617b96d243044023b28731341d290943b5d47a5f794Jens Axboe#if defined(PLAT_x86_linux)
618b96d243044023b28731341d290943b5d47a5f794Jens Axboe
619b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* These regs are trashed by the hidden call.  No need to mention eax
620b96d243044023b28731341d290943b5d47a5f794Jens Axboe   as gcc can already see that, plus causes gcc to bomb. */
621b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
622b96d243044023b28731341d290943b5d47a5f794Jens Axboe
623b96d243044023b28731341d290943b5d47a5f794Jens Axboe/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
624b96d243044023b28731341d290943b5d47a5f794Jens Axboe   long) == 4. */
625b96d243044023b28731341d290943b5d47a5f794Jens Axboe
626b96d243044023b28731341d290943b5d47a5f794Jens Axboe#define CALL_FN_W_v(lval, orig)                                   \
627b96d243044023b28731341d290943b5d47a5f794Jens Axboe   do {                                                           \
628b96d243044023b28731341d290943b5d47a5f794Jens Axboe      volatile OrigFn        _orig = (orig);                      \
629b96d243044023b28731341d290943b5d47a5f794Jens Axboe      volatile unsigned long _argvec[1];                          \
630b96d243044023b28731341d290943b5d47a5f794Jens Axboe      volatile unsigned long _res;                                \
631b96d243044023b28731341d290943b5d47a5f794Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
632b96d243044023b28731341d290943b5d47a5f794Jens Axboe      __asm__ volatile(                                           \
633b96d243044023b28731341d290943b5d47a5f794Jens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
634b96d243044023b28731341d290943b5d47a5f794Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
635b96d243044023b28731341d290943b5d47a5f794Jens Axboe         : /*out*/   "=a" (_res)                                  \
636b96d243044023b28731341d290943b5d47a5f794Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
637b96d243044023b28731341d290943b5d47a5f794Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
638b96d243044023b28731341d290943b5d47a5f794Jens Axboe      );                                                          \
639b96d243044023b28731341d290943b5d47a5f794Jens Axboe      lval = (__typeof__(lval)) _res;                             \
640b96d243044023b28731341d290943b5d47a5f794Jens Axboe   } while (0)
6410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6420fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#define CALL_FN_W_W(lval, orig, arg1)                             \
643b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   do {                                                           \
644b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile OrigFn        _orig = (orig);                      \
645b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile unsigned long _argvec[2];                          \
646166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe      volatile unsigned long _res;                                \
647166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
648166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
649166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe      __asm__ volatile(                                           \
650166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe         "pushl 4(%%eax)\n\t"                                     \
651166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
652166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
653166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe         "addl $4, %%esp\n"                                       \
654166dce4bdf2573a1641c1de5243e2465b190f0ddJens Axboe         : /*out*/   "=a" (_res)                                  \
655b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe         : /*in*/    "a" (&_argvec[0])                            \
656b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
657b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      );                                                          \
658b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      lval = (__typeof__(lval)) _res;                             \
659b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   } while (0)
660b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
661b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
662b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   do {                                                           \
663b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile OrigFn        _orig = (orig);                      \
664b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile unsigned long _argvec[3];                          \
6655fdd124a3b811993542825847f207587d5f4661eJens Axboe      volatile unsigned long _res;                                \
666b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
667b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
6685fdd124a3b811993542825847f207587d5f4661eJens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
6695fdd124a3b811993542825847f207587d5f4661eJens Axboe      __asm__ volatile(                                           \
6705fdd124a3b811993542825847f207587d5f4661eJens Axboe         "pushl 8(%%eax)\n\t"                                     \
6715fdd124a3b811993542825847f207587d5f4661eJens Axboe         "pushl 4(%%eax)\n\t"                                     \
6725fdd124a3b811993542825847f207587d5f4661eJens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
6730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
6740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "addl $8, %%esp\n"                                       \
6750fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*out*/   "=a" (_res)                                  \
6760fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
6770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
6780fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      );                                                          \
6790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      lval = (__typeof__(lval)) _res;                             \
6800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   } while (0)
6810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
6820fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
6830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   do {                                                           \
684de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile OrigFn        _orig = (orig);                      \
6850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      volatile unsigned long _argvec[4];                          \
686de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile unsigned long _res;                                \
6870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
688de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[1] = (unsigned long)(arg1);                         \
689de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[2] = (unsigned long)(arg2);                         \
6900fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
691de890a1e48d40238dac69f302708dde8719de240Steven Lang      __asm__ volatile(                                           \
6920fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 12(%%eax)\n\t"                                    \
6930fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 8(%%eax)\n\t"                                     \
6940fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
6950fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
6960fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
6970fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "addl $12, %%esp\n"                                      \
6980fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*out*/   "=a" (_res)                                  \
6990fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
7000fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7010fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      );                                                          \
7020fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      lval = (__typeof__(lval)) _res;                             \
7030fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   } while (0)
7040fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
7050fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
7060fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   do {                                                           \
7070fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      volatile OrigFn        _orig = (orig);                      \
7080fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      volatile unsigned long _argvec[5];                          \
7090fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      volatile unsigned long _res;                                \
7100fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7110fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
7120fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
7130fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
7140fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
7150fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      __asm__ volatile(                                           \
7160fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 16(%%eax)\n\t"                                    \
7170fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 12(%%eax)\n\t"                                    \
718b94cba47cfdf96e72ec894080b3a7bf645a86e9cJens Axboe         "pushl 8(%%eax)\n\t"                                     \
7190fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
7200fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7210fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
7220fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "addl $16, %%esp\n"                                      \
7230fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*out*/   "=a" (_res)                                  \
7240fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
7250fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7260fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      );                                                          \
7270fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      lval = (__typeof__(lval)) _res;                             \
728ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   } while (0)
729b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
730de890a1e48d40238dac69f302708dde8719de240Steven Lang#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
731414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe   do {                                                           \
732ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      volatile OrigFn        _orig = (orig);                      \
733de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile unsigned long _argvec[6];                          \
734414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe      volatile unsigned long _res;                                \
735414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
736414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
737414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
7380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
739ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
740e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
741ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      __asm__ volatile(                                           \
742ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 20(%%eax)\n\t"                                    \
743ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 16(%%eax)\n\t"                                    \
744ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 12(%%eax)\n\t"                                    \
745ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 8(%%eax)\n\t"                                     \
746e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe         "pushl 4(%%eax)\n\t"                                     \
747ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
748ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
7496bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe         "addl $20, %%esp\n"                                      \
7506bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe         : /*out*/   "=a" (_res)                                  \
751e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe         : /*in*/    "a" (&_argvec[0])                            \
7526bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7536bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe      );                                                          \
7546bedbfafcffbc7202b5bb621ac5886aafdc0f362Jens Axboe      lval = (__typeof__(lval)) _res;                             \
755ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   } while (0)
756b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
757b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
758b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   do {                                                           \
759ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      volatile OrigFn        _orig = (orig);                      \
760b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile unsigned long _argvec[7];                          \
761e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe      volatile unsigned long _res;                                \
762ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
763ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
7640fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
7650fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
7660fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
7670fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
7680fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      _argvec[6] = (unsigned long)(arg6);                         \
769de890a1e48d40238dac69f302708dde8719de240Steven Lang      __asm__ volatile(                                           \
7700fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 24(%%eax)\n\t"                                    \
7710fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 20(%%eax)\n\t"                                    \
772de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 16(%%eax)\n\t"                                    \
7730fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 12(%%eax)\n\t"                                    \
7740fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 8(%%eax)\n\t"                                     \
775de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 4(%%eax)\n\t"                                     \
776de890a1e48d40238dac69f302708dde8719de240Steven Lang         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7770fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
778de890a1e48d40238dac69f302708dde8719de240Steven Lang         "addl $24, %%esp\n"                                      \
7790fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*out*/   "=a" (_res)                                  \
7800fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
7810fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
782de890a1e48d40238dac69f302708dde8719de240Steven Lang      );                                                          \
7830fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe      lval = (__typeof__(lval)) _res;                             \
7840fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe   } while (0)
7850fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe
786e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
7870fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe                                 arg7)                            \
788ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   do {                                                           \
789ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      volatile OrigFn        _orig = (orig);                      \
790ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      volatile unsigned long _argvec[8];                          \
791b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      volatile unsigned long _res;                                \
792ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
793ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
7949bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
795ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
796de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[4] = (unsigned long)(arg4);                         \
797af52b3455ad892322aab2791282b6bd4efdfdbf3Jens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
798ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      _argvec[6] = (unsigned long)(arg6);                         \
7993f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran      _argvec[7] = (unsigned long)(arg7);                         \
8003f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran      __asm__ volatile(                                           \
8013f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran         "pushl 28(%%eax)\n\t"                                    \
8023f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran         "pushl 24(%%eax)\n\t"                                    \
8033f457bea08a6bd60d99950c59c5432b8e78c69e2Bruce Cran         "pushl 20(%%eax)\n\t"                                    \
80416d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe         "pushl 16(%%eax)\n\t"                                    \
80516d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe         "pushl 12(%%eax)\n\t"                                    \
80616d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe         "pushl 8(%%eax)\n\t"                                     \
80716d55aae770b8b1a966d4b4a814918ce49a76ba3Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
808ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
809de890a1e48d40238dac69f302708dde8719de240Steven Lang         VALGRIND_CALL_NOREDIR_EAX                                \
810de890a1e48d40238dac69f302708dde8719de240Steven Lang         "addl $28, %%esp\n"                                      \
811de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*out*/   "=a" (_res)                                  \
812de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*in*/    "a" (&_argvec[0])                            \
813de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
814de890a1e48d40238dac69f302708dde8719de240Steven Lang      );                                                          \
815de890a1e48d40238dac69f302708dde8719de240Steven Lang      lval = (__typeof__(lval)) _res;                             \
816ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe   } while (0)
817de890a1e48d40238dac69f302708dde8719de240Steven Lang
818de890a1e48d40238dac69f302708dde8719de240Steven Lang#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
8199b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe                                 arg7,arg8)                       \
8209b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe   do {                                                           \
821de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile OrigFn        _orig = (orig);                      \
822de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile unsigned long _argvec[9];                          \
8239b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      volatile unsigned long _res;                                \
824de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8259b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
8269b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
8279b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
8289b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
8299b9860651274cfb6e5a367b653e0d465bd89344fJens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
830de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[6] = (unsigned long)(arg6);                         \
831de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[7] = (unsigned long)(arg7);                         \
832de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[8] = (unsigned long)(arg8);                         \
833443662efa60d9082bc820641e7d1d31dd58d3ae1Jens Axboe      __asm__ volatile(                                           \
834de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 32(%%eax)\n\t"                                    \
835de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 28(%%eax)\n\t"                                    \
836de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 24(%%eax)\n\t"                                    \
837414c2a3e741bb7dd7147ce6843f529c7773cea38Jens Axboe         "pushl 20(%%eax)\n\t"                                    \
8380fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 16(%%eax)\n\t"                                    \
839de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 12(%%eax)\n\t"                                    \
840de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 8(%%eax)\n\t"                                     \
8410fd666bf0d5fc373f28b1b43d1df817f8ec89605Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
842de890a1e48d40238dac69f302708dde8719de240Steven Lang         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
843ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
8447bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "addl $32, %%esp\n"                                      \
845ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         : /*out*/   "=a" (_res)                                  \
846ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         : /*in*/    "a" (&_argvec[0])                            \
847b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8489bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe      );                                                          \
849b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      lval = (__typeof__(lval)) _res;                             \
850b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe   } while (0)
851b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
85264b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
85364b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe                                 arg7,arg8,arg9)                  \
85464b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe   do {                                                           \
85564b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe      volatile OrigFn        _orig = (orig);                      \
85664b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe      volatile unsigned long _argvec[10];                         \
85764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe      volatile unsigned long _res;                                \
85864b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
859b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
860b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
861b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
862b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
863b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
864b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe      _argvec[6] = (unsigned long)(arg6);                         \
8657bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe      _argvec[7] = (unsigned long)(arg7);                         \
8667bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe      _argvec[8] = (unsigned long)(arg8);                         \
867de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[9] = (unsigned long)(arg9);                         \
868de890a1e48d40238dac69f302708dde8719de240Steven Lang      __asm__ volatile(                                           \
869de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 36(%%eax)\n\t"                                    \
870de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 32(%%eax)\n\t"                                    \
871de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 28(%%eax)\n\t"                                    \
8727bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "pushl 24(%%eax)\n\t"                                    \
8737bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "pushl 20(%%eax)\n\t"                                    \
8747bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "pushl 16(%%eax)\n\t"                                    \
8757bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "pushl 12(%%eax)\n\t"                                    \
8767bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "pushl 8(%%eax)\n\t"                                     \
87764b24cd8a5ea87bccec60e0236d93071480201e7Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
8787bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8797bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
880b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe         "addl $36, %%esp\n"                                      \
8819bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe         : /*out*/   "=a" (_res)                                  \
8829bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe         : /*in*/    "a" (&_argvec[0])                            \
8839bec88e15aad76c16ac65048270ecac8b5956a61Jens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
88436d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe      );                                                          \
88536d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe      lval = (__typeof__(lval)) _res;                             \
88636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe   } while (0)
88736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe
88836d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
8895921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe                                  arg7,arg8,arg9,arg10)           \
8909cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   do {                                                           \
8919cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      volatile OrigFn        _orig = (orig);                      \
8929cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      volatile unsigned long _argvec[11];                         \
8939cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      volatile unsigned long _res;                                \
8949cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8959cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[1] = (unsigned long)(arg1);                         \
8969cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[2] = (unsigned long)(arg2);                         \
8979cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
8989cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[4] = (unsigned long)(arg4);                         \
8999cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[5] = (unsigned long)(arg5);                         \
9009cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[6] = (unsigned long)(arg6);                         \
9019cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[7] = (unsigned long)(arg7);                         \
9029cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[8] = (unsigned long)(arg8);                         \
9039cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[9] = (unsigned long)(arg9);                         \
9049cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[10] = (unsigned long)(arg10);                       \
9059cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      __asm__ volatile(                                           \
9069cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe         "pushl 40(%%eax)\n\t"                                    \
9079cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe         "pushl 36(%%eax)\n\t"                                    \
9085921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe         "pushl 32(%%eax)\n\t"                                    \
909de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 28(%%eax)\n\t"                                    \
910de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 24(%%eax)\n\t"                                    \
911de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 20(%%eax)\n\t"                                    \
912de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 16(%%eax)\n\t"                                    \
913de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 12(%%eax)\n\t"                                    \
914de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 8(%%eax)\n\t"                                     \
915de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 4(%%eax)\n\t"                                     \
916de890a1e48d40238dac69f302708dde8719de240Steven Lang         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
91736d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
91836d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe         "addl $40, %%esp\n"                                      \
919de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*out*/   "=a" (_res)                                  \
920de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*in*/    "a" (&_argvec[0])                            \
921de890a1e48d40238dac69f302708dde8719de240Steven Lang         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
92236d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe      );                                                          \
923ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe      lval = (__typeof__(lval)) _res;                             \
9245921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe   } while (0)
925ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe
9265921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
927de890a1e48d40238dac69f302708dde8719de240Steven Lang                                  arg6,arg7,arg8,arg9,arg10,      \
928de890a1e48d40238dac69f302708dde8719de240Steven Lang                                  arg11)                          \
929de890a1e48d40238dac69f302708dde8719de240Steven Lang   do {                                                           \
930de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile OrigFn        _orig = (orig);                      \
931de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile unsigned long _argvec[12];                         \
932de890a1e48d40238dac69f302708dde8719de240Steven Lang      volatile unsigned long _res;                                \
933de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[0] = (unsigned long)_orig.nraddr;                   \
934de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[1] = (unsigned long)(arg1);                         \
935de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[2] = (unsigned long)(arg2);                         \
93636d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe      _argvec[3] = (unsigned long)(arg3);                         \
937de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[4] = (unsigned long)(arg4);                         \
938de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[5] = (unsigned long)(arg5);                         \
939de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[6] = (unsigned long)(arg6);                         \
94036d80bc7c7f7fbc2612941b7dd7ceaf645798c7fJens Axboe      _argvec[7] = (unsigned long)(arg7);                         \
9419cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[8] = (unsigned long)(arg8);                         \
9429cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      _argvec[9] = (unsigned long)(arg9);                         \
943de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[10] = (unsigned long)(arg10);                       \
944de890a1e48d40238dac69f302708dde8719de240Steven Lang      _argvec[11] = (unsigned long)(arg11);                       \
945de890a1e48d40238dac69f302708dde8719de240Steven Lang      __asm__ volatile(                                           \
946de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 44(%%eax)\n\t"                                    \
947de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 40(%%eax)\n\t"                                    \
948de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 36(%%eax)\n\t"                                    \
949de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 32(%%eax)\n\t"                                    \
950de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 28(%%eax)\n\t"                                    \
951de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 24(%%eax)\n\t"                                    \
952de890a1e48d40238dac69f302708dde8719de240Steven Lang         "pushl 20(%%eax)\n\t"                                    \
953ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 16(%%eax)\n\t"                                    \
954ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "pushl 12(%%eax)\n\t"                                    \
9559cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe         "pushl 8(%%eax)\n\t"                                     \
9565921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe         "pushl 4(%%eax)\n\t"                                     \
9579cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9585921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe         VALGRIND_CALL_NOREDIR_EAX                                \
959ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         "addl $44, %%esp\n"                                      \
960ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         : /*out*/   "=a" (_res)                                  \
961ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         : /*in*/    "a" (&_argvec[0])                            \
962ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9639cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe      );                                                          \
9645921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe      lval = (__typeof__(lval)) _res;                             \
9659cce02e89e01984a5bf58e730fb9311dc5273554Jens Axboe   } while (0)
9665921e80c5dfc9f96d2f21da6ae58f2b5d3a0b373Jens Axboe
967ed92ac0ce9ce1cc64697272d307d4fa7d18ed64cJens Axboe#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
968                                  arg6,arg7,arg8,arg9,arg10,      \
969                                  arg11,arg12)                    \
970   do {                                                           \
971      volatile OrigFn        _orig = (orig);                      \
972      volatile unsigned long _argvec[13];                         \
973      volatile unsigned long _res;                                \
974      _argvec[0] = (unsigned long)_orig.nraddr;                   \
975      _argvec[1] = (unsigned long)(arg1);                         \
976      _argvec[2] = (unsigned long)(arg2);                         \
977      _argvec[3] = (unsigned long)(arg3);                         \
978      _argvec[4] = (unsigned long)(arg4);                         \
979      _argvec[5] = (unsigned long)(arg5);                         \
980      _argvec[6] = (unsigned long)(arg6);                         \
981      _argvec[7] = (unsigned long)(arg7);                         \
982      _argvec[8] = (unsigned long)(arg8);                         \
983      _argvec[9] = (unsigned long)(arg9);                         \
984      _argvec[10] = (unsigned long)(arg10);                       \
985      _argvec[11] = (unsigned long)(arg11);                       \
986      _argvec[12] = (unsigned long)(arg12);                       \
987      __asm__ volatile(                                           \
988         "pushl 48(%%eax)\n\t"                                    \
989         "pushl 44(%%eax)\n\t"                                    \
990         "pushl 40(%%eax)\n\t"                                    \
991         "pushl 36(%%eax)\n\t"                                    \
992         "pushl 32(%%eax)\n\t"                                    \
993         "pushl 28(%%eax)\n\t"                                    \
994         "pushl 24(%%eax)\n\t"                                    \
995         "pushl 20(%%eax)\n\t"                                    \
996         "pushl 16(%%eax)\n\t"                                    \
997         "pushl 12(%%eax)\n\t"                                    \
998         "pushl 8(%%eax)\n\t"                                     \
999         "pushl 4(%%eax)\n\t"                                     \
1000         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
1001         VALGRIND_CALL_NOREDIR_EAX                                \
1002         "addl $48, %%esp\n"                                      \
1003         : /*out*/   "=a" (_res)                                  \
1004         : /*in*/    "a" (&_argvec[0])                            \
1005         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1006      );                                                          \
1007      lval = (__typeof__(lval)) _res;                             \
1008   } while (0)
1009
1010#endif /* PLAT_x86_linux */
1011
1012/* ------------------------ amd64-linux ------------------------ */
1013
1014#if defined(PLAT_amd64_linux)
1015
1016/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1017
1018/* These regs are trashed by the hidden call. */
1019#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
1020                            "rdi", "r8", "r9", "r10", "r11"
1021
1022/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1023   long) == 8. */
1024
1025/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1026   macros.  In order not to trash the stack redzone, we need to drop
1027   %rsp by 128 before the hidden call, and restore afterwards.  The
1028   nastyness is that it is only by luck that the stack still appears
1029   to be unwindable during the hidden call - since then the behaviour
1030   of any routine using this macro does not match what the CFI data
1031   says.  Sigh.
1032
1033   Why is this important?  Imagine that a wrapper has a stack
1034   allocated local, and passes to the hidden call, a pointer to it.
1035   Because gcc does not know about the hidden call, it may allocate
1036   that local in the redzone.  Unfortunately the hidden call may then
1037   trash it before it comes to use it.  So we must step clear of the
1038   redzone, for the duration of the hidden call, to make it safe.
1039
1040   Probably the same problem afflicts the other redzone-style ABIs too
1041   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
1042   self describing (none of this CFI nonsense) so at least messing
1043   with the stack pointer doesn't give a danger of non-unwindable
1044   stack. */
1045
1046#define CALL_FN_W_v(lval, orig)                                   \
1047   do {                                                           \
1048      volatile OrigFn        _orig = (orig);                      \
1049      volatile unsigned long _argvec[1];                          \
1050      volatile unsigned long _res;                                \
1051      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1052      __asm__ volatile(                                           \
1053         "subq $128,%%rsp\n\t"                                    \
1054         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1055         VALGRIND_CALL_NOREDIR_RAX                                \
1056         "addq $128,%%rsp\n\t"                                    \
1057         : /*out*/   "=a" (_res)                                  \
1058         : /*in*/    "a" (&_argvec[0])                            \
1059         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1060      );                                                          \
1061      lval = (__typeof__(lval)) _res;                             \
1062   } while (0)
1063
1064#define CALL_FN_W_W(lval, orig, arg1)                             \
1065   do {                                                           \
1066      volatile OrigFn        _orig = (orig);                      \
1067      volatile unsigned long _argvec[2];                          \
1068      volatile unsigned long _res;                                \
1069      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1070      _argvec[1] = (unsigned long)(arg1);                         \
1071      __asm__ volatile(                                           \
1072         "subq $128,%%rsp\n\t"                                    \
1073         "movq 8(%%rax), %%rdi\n\t"                               \
1074         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1075         VALGRIND_CALL_NOREDIR_RAX                                \
1076         "addq $128,%%rsp\n\t"                                    \
1077         : /*out*/   "=a" (_res)                                  \
1078         : /*in*/    "a" (&_argvec[0])                            \
1079         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1080      );                                                          \
1081      lval = (__typeof__(lval)) _res;                             \
1082   } while (0)
1083
1084#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
1085   do {                                                           \
1086      volatile OrigFn        _orig = (orig);                      \
1087      volatile unsigned long _argvec[3];                          \
1088      volatile unsigned long _res;                                \
1089      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1090      _argvec[1] = (unsigned long)(arg1);                         \
1091      _argvec[2] = (unsigned long)(arg2);                         \
1092      __asm__ volatile(                                           \
1093         "subq $128,%%rsp\n\t"                                    \
1094         "movq 16(%%rax), %%rsi\n\t"                              \
1095         "movq 8(%%rax), %%rdi\n\t"                               \
1096         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1097         VALGRIND_CALL_NOREDIR_RAX                                \
1098         "addq $128,%%rsp\n\t"                                    \
1099         : /*out*/   "=a" (_res)                                  \
1100         : /*in*/    "a" (&_argvec[0])                            \
1101         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1102      );                                                          \
1103      lval = (__typeof__(lval)) _res;                             \
1104   } while (0)
1105
1106#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1107   do {                                                           \
1108      volatile OrigFn        _orig = (orig);                      \
1109      volatile unsigned long _argvec[4];                          \
1110      volatile unsigned long _res;                                \
1111      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1112      _argvec[1] = (unsigned long)(arg1);                         \
1113      _argvec[2] = (unsigned long)(arg2);                         \
1114      _argvec[3] = (unsigned long)(arg3);                         \
1115      __asm__ volatile(                                           \
1116         "subq $128,%%rsp\n\t"                                    \
1117         "movq 24(%%rax), %%rdx\n\t"                              \
1118         "movq 16(%%rax), %%rsi\n\t"                              \
1119         "movq 8(%%rax), %%rdi\n\t"                               \
1120         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1121         VALGRIND_CALL_NOREDIR_RAX                                \
1122         "addq $128,%%rsp\n\t"                                    \
1123         : /*out*/   "=a" (_res)                                  \
1124         : /*in*/    "a" (&_argvec[0])                            \
1125         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1126      );                                                          \
1127      lval = (__typeof__(lval)) _res;                             \
1128   } while (0)
1129
1130#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1131   do {                                                           \
1132      volatile OrigFn        _orig = (orig);                      \
1133      volatile unsigned long _argvec[5];                          \
1134      volatile unsigned long _res;                                \
1135      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1136      _argvec[1] = (unsigned long)(arg1);                         \
1137      _argvec[2] = (unsigned long)(arg2);                         \
1138      _argvec[3] = (unsigned long)(arg3);                         \
1139      _argvec[4] = (unsigned long)(arg4);                         \
1140      __asm__ volatile(                                           \
1141         "subq $128,%%rsp\n\t"                                    \
1142         "movq 32(%%rax), %%rcx\n\t"                              \
1143         "movq 24(%%rax), %%rdx\n\t"                              \
1144         "movq 16(%%rax), %%rsi\n\t"                              \
1145         "movq 8(%%rax), %%rdi\n\t"                               \
1146         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1147         VALGRIND_CALL_NOREDIR_RAX                                \
1148         "addq $128,%%rsp\n\t"                                    \
1149         : /*out*/   "=a" (_res)                                  \
1150         : /*in*/    "a" (&_argvec[0])                            \
1151         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1152      );                                                          \
1153      lval = (__typeof__(lval)) _res;                             \
1154   } while (0)
1155
1156#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1157   do {                                                           \
1158      volatile OrigFn        _orig = (orig);                      \
1159      volatile unsigned long _argvec[6];                          \
1160      volatile unsigned long _res;                                \
1161      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1162      _argvec[1] = (unsigned long)(arg1);                         \
1163      _argvec[2] = (unsigned long)(arg2);                         \
1164      _argvec[3] = (unsigned long)(arg3);                         \
1165      _argvec[4] = (unsigned long)(arg4);                         \
1166      _argvec[5] = (unsigned long)(arg5);                         \
1167      __asm__ volatile(                                           \
1168         "subq $128,%%rsp\n\t"                                    \
1169         "movq 40(%%rax), %%r8\n\t"                               \
1170         "movq 32(%%rax), %%rcx\n\t"                              \
1171         "movq 24(%%rax), %%rdx\n\t"                              \
1172         "movq 16(%%rax), %%rsi\n\t"                              \
1173         "movq 8(%%rax), %%rdi\n\t"                               \
1174         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1175         VALGRIND_CALL_NOREDIR_RAX                                \
1176         "addq $128,%%rsp\n\t"                                    \
1177         : /*out*/   "=a" (_res)                                  \
1178         : /*in*/    "a" (&_argvec[0])                            \
1179         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1180      );                                                          \
1181      lval = (__typeof__(lval)) _res;                             \
1182   } while (0)
1183
1184#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1185   do {                                                           \
1186      volatile OrigFn        _orig = (orig);                      \
1187      volatile unsigned long _argvec[7];                          \
1188      volatile unsigned long _res;                                \
1189      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1190      _argvec[1] = (unsigned long)(arg1);                         \
1191      _argvec[2] = (unsigned long)(arg2);                         \
1192      _argvec[3] = (unsigned long)(arg3);                         \
1193      _argvec[4] = (unsigned long)(arg4);                         \
1194      _argvec[5] = (unsigned long)(arg5);                         \
1195      _argvec[6] = (unsigned long)(arg6);                         \
1196      __asm__ volatile(                                           \
1197         "subq $128,%%rsp\n\t"                                    \
1198         "movq 48(%%rax), %%r9\n\t"                               \
1199         "movq 40(%%rax), %%r8\n\t"                               \
1200         "movq 32(%%rax), %%rcx\n\t"                              \
1201         "movq 24(%%rax), %%rdx\n\t"                              \
1202         "movq 16(%%rax), %%rsi\n\t"                              \
1203         "movq 8(%%rax), %%rdi\n\t"                               \
1204         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1205         "addq $128,%%rsp\n\t"                                    \
1206         VALGRIND_CALL_NOREDIR_RAX                                \
1207         : /*out*/   "=a" (_res)                                  \
1208         : /*in*/    "a" (&_argvec[0])                            \
1209         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1210      );                                                          \
1211      lval = (__typeof__(lval)) _res;                             \
1212   } while (0)
1213
1214#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1215                                 arg7)                            \
1216   do {                                                           \
1217      volatile OrigFn        _orig = (orig);                      \
1218      volatile unsigned long _argvec[8];                          \
1219      volatile unsigned long _res;                                \
1220      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1221      _argvec[1] = (unsigned long)(arg1);                         \
1222      _argvec[2] = (unsigned long)(arg2);                         \
1223      _argvec[3] = (unsigned long)(arg3);                         \
1224      _argvec[4] = (unsigned long)(arg4);                         \
1225      _argvec[5] = (unsigned long)(arg5);                         \
1226      _argvec[6] = (unsigned long)(arg6);                         \
1227      _argvec[7] = (unsigned long)(arg7);                         \
1228      __asm__ volatile(                                           \
1229         "subq $128,%%rsp\n\t"                                    \
1230         "pushq 56(%%rax)\n\t"                                    \
1231         "movq 48(%%rax), %%r9\n\t"                               \
1232         "movq 40(%%rax), %%r8\n\t"                               \
1233         "movq 32(%%rax), %%rcx\n\t"                              \
1234         "movq 24(%%rax), %%rdx\n\t"                              \
1235         "movq 16(%%rax), %%rsi\n\t"                              \
1236         "movq 8(%%rax), %%rdi\n\t"                               \
1237         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1238         VALGRIND_CALL_NOREDIR_RAX                                \
1239         "addq $8, %%rsp\n"                                       \
1240         "addq $128,%%rsp\n\t"                                    \
1241         : /*out*/   "=a" (_res)                                  \
1242         : /*in*/    "a" (&_argvec[0])                            \
1243         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1244      );                                                          \
1245      lval = (__typeof__(lval)) _res;                             \
1246   } while (0)
1247
1248#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1249                                 arg7,arg8)                       \
1250   do {                                                           \
1251      volatile OrigFn        _orig = (orig);                      \
1252      volatile unsigned long _argvec[9];                          \
1253      volatile unsigned long _res;                                \
1254      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1255      _argvec[1] = (unsigned long)(arg1);                         \
1256      _argvec[2] = (unsigned long)(arg2);                         \
1257      _argvec[3] = (unsigned long)(arg3);                         \
1258      _argvec[4] = (unsigned long)(arg4);                         \
1259      _argvec[5] = (unsigned long)(arg5);                         \
1260      _argvec[6] = (unsigned long)(arg6);                         \
1261      _argvec[7] = (unsigned long)(arg7);                         \
1262      _argvec[8] = (unsigned long)(arg8);                         \
1263      __asm__ volatile(                                           \
1264         "subq $128,%%rsp\n\t"                                    \
1265         "pushq 64(%%rax)\n\t"                                    \
1266         "pushq 56(%%rax)\n\t"                                    \
1267         "movq 48(%%rax), %%r9\n\t"                               \
1268         "movq 40(%%rax), %%r8\n\t"                               \
1269         "movq 32(%%rax), %%rcx\n\t"                              \
1270         "movq 24(%%rax), %%rdx\n\t"                              \
1271         "movq 16(%%rax), %%rsi\n\t"                              \
1272         "movq 8(%%rax), %%rdi\n\t"                               \
1273         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1274         VALGRIND_CALL_NOREDIR_RAX                                \
1275         "addq $16, %%rsp\n"                                      \
1276         "addq $128,%%rsp\n\t"                                    \
1277         : /*out*/   "=a" (_res)                                  \
1278         : /*in*/    "a" (&_argvec[0])                            \
1279         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1280      );                                                          \
1281      lval = (__typeof__(lval)) _res;                             \
1282   } while (0)
1283
1284#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1285                                 arg7,arg8,arg9)                  \
1286   do {                                                           \
1287      volatile OrigFn        _orig = (orig);                      \
1288      volatile unsigned long _argvec[10];                         \
1289      volatile unsigned long _res;                                \
1290      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1291      _argvec[1] = (unsigned long)(arg1);                         \
1292      _argvec[2] = (unsigned long)(arg2);                         \
1293      _argvec[3] = (unsigned long)(arg3);                         \
1294      _argvec[4] = (unsigned long)(arg4);                         \
1295      _argvec[5] = (unsigned long)(arg5);                         \
1296      _argvec[6] = (unsigned long)(arg6);                         \
1297      _argvec[7] = (unsigned long)(arg7);                         \
1298      _argvec[8] = (unsigned long)(arg8);                         \
1299      _argvec[9] = (unsigned long)(arg9);                         \
1300      __asm__ volatile(                                           \
1301         "subq $128,%%rsp\n\t"                                    \
1302         "pushq 72(%%rax)\n\t"                                    \
1303         "pushq 64(%%rax)\n\t"                                    \
1304         "pushq 56(%%rax)\n\t"                                    \
1305         "movq 48(%%rax), %%r9\n\t"                               \
1306         "movq 40(%%rax), %%r8\n\t"                               \
1307         "movq 32(%%rax), %%rcx\n\t"                              \
1308         "movq 24(%%rax), %%rdx\n\t"                              \
1309         "movq 16(%%rax), %%rsi\n\t"                              \
1310         "movq 8(%%rax), %%rdi\n\t"                               \
1311         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1312         VALGRIND_CALL_NOREDIR_RAX                                \
1313         "addq $24, %%rsp\n"                                      \
1314         "addq $128,%%rsp\n\t"                                    \
1315         : /*out*/   "=a" (_res)                                  \
1316         : /*in*/    "a" (&_argvec[0])                            \
1317         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1318      );                                                          \
1319      lval = (__typeof__(lval)) _res;                             \
1320   } while (0)
1321
1322#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1323                                  arg7,arg8,arg9,arg10)           \
1324   do {                                                           \
1325      volatile OrigFn        _orig = (orig);                      \
1326      volatile unsigned long _argvec[11];                         \
1327      volatile unsigned long _res;                                \
1328      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1329      _argvec[1] = (unsigned long)(arg1);                         \
1330      _argvec[2] = (unsigned long)(arg2);                         \
1331      _argvec[3] = (unsigned long)(arg3);                         \
1332      _argvec[4] = (unsigned long)(arg4);                         \
1333      _argvec[5] = (unsigned long)(arg5);                         \
1334      _argvec[6] = (unsigned long)(arg6);                         \
1335      _argvec[7] = (unsigned long)(arg7);                         \
1336      _argvec[8] = (unsigned long)(arg8);                         \
1337      _argvec[9] = (unsigned long)(arg9);                         \
1338      _argvec[10] = (unsigned long)(arg10);                       \
1339      __asm__ volatile(                                           \
1340         "subq $128,%%rsp\n\t"                                    \
1341         "pushq 80(%%rax)\n\t"                                    \
1342         "pushq 72(%%rax)\n\t"                                    \
1343         "pushq 64(%%rax)\n\t"                                    \
1344         "pushq 56(%%rax)\n\t"                                    \
1345         "movq 48(%%rax), %%r9\n\t"                               \
1346         "movq 40(%%rax), %%r8\n\t"                               \
1347         "movq 32(%%rax), %%rcx\n\t"                              \
1348         "movq 24(%%rax), %%rdx\n\t"                              \
1349         "movq 16(%%rax), %%rsi\n\t"                              \
1350         "movq 8(%%rax), %%rdi\n\t"                               \
1351         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1352         VALGRIND_CALL_NOREDIR_RAX                                \
1353         "addq $32, %%rsp\n"                                      \
1354         "addq $128,%%rsp\n\t"                                    \
1355         : /*out*/   "=a" (_res)                                  \
1356         : /*in*/    "a" (&_argvec[0])                            \
1357         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1358      );                                                          \
1359      lval = (__typeof__(lval)) _res;                             \
1360   } while (0)
1361
1362#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1363                                  arg7,arg8,arg9,arg10,arg11)     \
1364   do {                                                           \
1365      volatile OrigFn        _orig = (orig);                      \
1366      volatile unsigned long _argvec[12];                         \
1367      volatile unsigned long _res;                                \
1368      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1369      _argvec[1] = (unsigned long)(arg1);                         \
1370      _argvec[2] = (unsigned long)(arg2);                         \
1371      _argvec[3] = (unsigned long)(arg3);                         \
1372      _argvec[4] = (unsigned long)(arg4);                         \
1373      _argvec[5] = (unsigned long)(arg5);                         \
1374      _argvec[6] = (unsigned long)(arg6);                         \
1375      _argvec[7] = (unsigned long)(arg7);                         \
1376      _argvec[8] = (unsigned long)(arg8);                         \
1377      _argvec[9] = (unsigned long)(arg9);                         \
1378      _argvec[10] = (unsigned long)(arg10);                       \
1379      _argvec[11] = (unsigned long)(arg11);                       \
1380      __asm__ volatile(                                           \
1381         "subq $128,%%rsp\n\t"                                    \
1382         "pushq 88(%%rax)\n\t"                                    \
1383         "pushq 80(%%rax)\n\t"                                    \
1384         "pushq 72(%%rax)\n\t"                                    \
1385         "pushq 64(%%rax)\n\t"                                    \
1386         "pushq 56(%%rax)\n\t"                                    \
1387         "movq 48(%%rax), %%r9\n\t"                               \
1388         "movq 40(%%rax), %%r8\n\t"                               \
1389         "movq 32(%%rax), %%rcx\n\t"                              \
1390         "movq 24(%%rax), %%rdx\n\t"                              \
1391         "movq 16(%%rax), %%rsi\n\t"                              \
1392         "movq 8(%%rax), %%rdi\n\t"                               \
1393         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1394         VALGRIND_CALL_NOREDIR_RAX                                \
1395         "addq $40, %%rsp\n"                                      \
1396         "addq $128,%%rsp\n\t"                                    \
1397         : /*out*/   "=a" (_res)                                  \
1398         : /*in*/    "a" (&_argvec[0])                            \
1399         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1400      );                                                          \
1401      lval = (__typeof__(lval)) _res;                             \
1402   } while (0)
1403
1404#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1405                                arg7,arg8,arg9,arg10,arg11,arg12) \
1406   do {                                                           \
1407      volatile OrigFn        _orig = (orig);                      \
1408      volatile unsigned long _argvec[13];                         \
1409      volatile unsigned long _res;                                \
1410      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1411      _argvec[1] = (unsigned long)(arg1);                         \
1412      _argvec[2] = (unsigned long)(arg2);                         \
1413      _argvec[3] = (unsigned long)(arg3);                         \
1414      _argvec[4] = (unsigned long)(arg4);                         \
1415      _argvec[5] = (unsigned long)(arg5);                         \
1416      _argvec[6] = (unsigned long)(arg6);                         \
1417      _argvec[7] = (unsigned long)(arg7);                         \
1418      _argvec[8] = (unsigned long)(arg8);                         \
1419      _argvec[9] = (unsigned long)(arg9);                         \
1420      _argvec[10] = (unsigned long)(arg10);                       \
1421      _argvec[11] = (unsigned long)(arg11);                       \
1422      _argvec[12] = (unsigned long)(arg12);                       \
1423      __asm__ volatile(                                           \
1424         "subq $128,%%rsp\n\t"                                    \
1425         "pushq 96(%%rax)\n\t"                                    \
1426         "pushq 88(%%rax)\n\t"                                    \
1427         "pushq 80(%%rax)\n\t"                                    \
1428         "pushq 72(%%rax)\n\t"                                    \
1429         "pushq 64(%%rax)\n\t"                                    \
1430         "pushq 56(%%rax)\n\t"                                    \
1431         "movq 48(%%rax), %%r9\n\t"                               \
1432         "movq 40(%%rax), %%r8\n\t"                               \
1433         "movq 32(%%rax), %%rcx\n\t"                              \
1434         "movq 24(%%rax), %%rdx\n\t"                              \
1435         "movq 16(%%rax), %%rsi\n\t"                              \
1436         "movq 8(%%rax), %%rdi\n\t"                               \
1437         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1438         VALGRIND_CALL_NOREDIR_RAX                                \
1439         "addq $48, %%rsp\n"                                      \
1440         "addq $128,%%rsp\n\t"                                    \
1441         : /*out*/   "=a" (_res)                                  \
1442         : /*in*/    "a" (&_argvec[0])                            \
1443         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1444      );                                                          \
1445      lval = (__typeof__(lval)) _res;                             \
1446   } while (0)
1447
1448#endif /* PLAT_amd64_linux */
1449
1450/* ------------------------ ppc32-linux ------------------------ */
1451
1452#if defined(PLAT_ppc32_linux)
1453
1454/* This is useful for finding out about the on-stack stuff:
1455
1456   extern int f9  ( int,int,int,int,int,int,int,int,int );
1457   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1458   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1459   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1460
1461   int g9 ( void ) {
1462      return f9(11,22,33,44,55,66,77,88,99);
1463   }
1464   int g10 ( void ) {
1465      return f10(11,22,33,44,55,66,77,88,99,110);
1466   }
1467   int g11 ( void ) {
1468      return f11(11,22,33,44,55,66,77,88,99,110,121);
1469   }
1470   int g12 ( void ) {
1471      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1472   }
1473*/
1474
1475/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1476
1477/* These regs are trashed by the hidden call. */
1478#define __CALLER_SAVED_REGS                                       \
1479   "lr", "ctr", "xer",                                            \
1480   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1481   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1482   "r11", "r12", "r13"
1483
1484/* These CALL_FN_ macros assume that on ppc32-linux,
1485   sizeof(unsigned long) == 4. */
1486
1487#define CALL_FN_W_v(lval, orig)                                   \
1488   do {                                                           \
1489      volatile OrigFn        _orig = (orig);                      \
1490      volatile unsigned long _argvec[1];                          \
1491      volatile unsigned long _res;                                \
1492      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1493      __asm__ volatile(                                           \
1494         "mr 11,%1\n\t"                                           \
1495         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1496         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1497         "mr %0,3"                                                \
1498         : /*out*/   "=r" (_res)                                  \
1499         : /*in*/    "r" (&_argvec[0])                            \
1500         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1501      );                                                          \
1502      lval = (__typeof__(lval)) _res;                             \
1503   } while (0)
1504
1505#define CALL_FN_W_W(lval, orig, arg1)                             \
1506   do {                                                           \
1507      volatile OrigFn        _orig = (orig);                      \
1508      volatile unsigned long _argvec[2];                          \
1509      volatile unsigned long _res;                                \
1510      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1511      _argvec[1] = (unsigned long)arg1;                           \
1512      __asm__ volatile(                                           \
1513         "mr 11,%1\n\t"                                           \
1514         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1515         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1516         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1517         "mr %0,3"                                                \
1518         : /*out*/   "=r" (_res)                                  \
1519         : /*in*/    "r" (&_argvec[0])                            \
1520         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1521      );                                                          \
1522      lval = (__typeof__(lval)) _res;                             \
1523   } while (0)
1524
1525#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
1526   do {                                                           \
1527      volatile OrigFn        _orig = (orig);                      \
1528      volatile unsigned long _argvec[3];                          \
1529      volatile unsigned long _res;                                \
1530      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1531      _argvec[1] = (unsigned long)arg1;                           \
1532      _argvec[2] = (unsigned long)arg2;                           \
1533      __asm__ volatile(                                           \
1534         "mr 11,%1\n\t"                                           \
1535         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1536         "lwz 4,8(11)\n\t"                                        \
1537         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1538         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1539         "mr %0,3"                                                \
1540         : /*out*/   "=r" (_res)                                  \
1541         : /*in*/    "r" (&_argvec[0])                            \
1542         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1543      );                                                          \
1544      lval = (__typeof__(lval)) _res;                             \
1545   } while (0)
1546
1547#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1548   do {                                                           \
1549      volatile OrigFn        _orig = (orig);                      \
1550      volatile unsigned long _argvec[4];                          \
1551      volatile unsigned long _res;                                \
1552      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1553      _argvec[1] = (unsigned long)arg1;                           \
1554      _argvec[2] = (unsigned long)arg2;                           \
1555      _argvec[3] = (unsigned long)arg3;                           \
1556      __asm__ volatile(                                           \
1557         "mr 11,%1\n\t"                                           \
1558         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1559         "lwz 4,8(11)\n\t"                                        \
1560         "lwz 5,12(11)\n\t"                                       \
1561         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1562         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1563         "mr %0,3"                                                \
1564         : /*out*/   "=r" (_res)                                  \
1565         : /*in*/    "r" (&_argvec[0])                            \
1566         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1567      );                                                          \
1568      lval = (__typeof__(lval)) _res;                             \
1569   } while (0)
1570
1571#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1572   do {                                                           \
1573      volatile OrigFn        _orig = (orig);                      \
1574      volatile unsigned long _argvec[5];                          \
1575      volatile unsigned long _res;                                \
1576      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1577      _argvec[1] = (unsigned long)arg1;                           \
1578      _argvec[2] = (unsigned long)arg2;                           \
1579      _argvec[3] = (unsigned long)arg3;                           \
1580      _argvec[4] = (unsigned long)arg4;                           \
1581      __asm__ volatile(                                           \
1582         "mr 11,%1\n\t"                                           \
1583         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1584         "lwz 4,8(11)\n\t"                                        \
1585         "lwz 5,12(11)\n\t"                                       \
1586         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1587         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1588         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1589         "mr %0,3"                                                \
1590         : /*out*/   "=r" (_res)                                  \
1591         : /*in*/    "r" (&_argvec[0])                            \
1592         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1593      );                                                          \
1594      lval = (__typeof__(lval)) _res;                             \
1595   } while (0)
1596
1597#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1598   do {                                                           \
1599      volatile OrigFn        _orig = (orig);                      \
1600      volatile unsigned long _argvec[6];                          \
1601      volatile unsigned long _res;                                \
1602      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1603      _argvec[1] = (unsigned long)arg1;                           \
1604      _argvec[2] = (unsigned long)arg2;                           \
1605      _argvec[3] = (unsigned long)arg3;                           \
1606      _argvec[4] = (unsigned long)arg4;                           \
1607      _argvec[5] = (unsigned long)arg5;                           \
1608      __asm__ volatile(                                           \
1609         "mr 11,%1\n\t"                                           \
1610         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1611         "lwz 4,8(11)\n\t"                                        \
1612         "lwz 5,12(11)\n\t"                                       \
1613         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1614         "lwz 7,20(11)\n\t"                                       \
1615         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1616         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1617         "mr %0,3"                                                \
1618         : /*out*/   "=r" (_res)                                  \
1619         : /*in*/    "r" (&_argvec[0])                            \
1620         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1621      );                                                          \
1622      lval = (__typeof__(lval)) _res;                             \
1623   } while (0)
1624
1625#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1626   do {                                                           \
1627      volatile OrigFn        _orig = (orig);                      \
1628      volatile unsigned long _argvec[7];                          \
1629      volatile unsigned long _res;                                \
1630      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1631      _argvec[1] = (unsigned long)arg1;                           \
1632      _argvec[2] = (unsigned long)arg2;                           \
1633      _argvec[3] = (unsigned long)arg3;                           \
1634      _argvec[4] = (unsigned long)arg4;                           \
1635      _argvec[5] = (unsigned long)arg5;                           \
1636      _argvec[6] = (unsigned long)arg6;                           \
1637      __asm__ volatile(                                           \
1638         "mr 11,%1\n\t"                                           \
1639         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1640         "lwz 4,8(11)\n\t"                                        \
1641         "lwz 5,12(11)\n\t"                                       \
1642         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1643         "lwz 7,20(11)\n\t"                                       \
1644         "lwz 8,24(11)\n\t"                                       \
1645         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1646         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1647         "mr %0,3"                                                \
1648         : /*out*/   "=r" (_res)                                  \
1649         : /*in*/    "r" (&_argvec[0])                            \
1650         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1651      );                                                          \
1652      lval = (__typeof__(lval)) _res;                             \
1653   } while (0)
1654
1655#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1656                                 arg7)                            \
1657   do {                                                           \
1658      volatile OrigFn        _orig = (orig);                      \
1659      volatile unsigned long _argvec[8];                          \
1660      volatile unsigned long _res;                                \
1661      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1662      _argvec[1] = (unsigned long)arg1;                           \
1663      _argvec[2] = (unsigned long)arg2;                           \
1664      _argvec[3] = (unsigned long)arg3;                           \
1665      _argvec[4] = (unsigned long)arg4;                           \
1666      _argvec[5] = (unsigned long)arg5;                           \
1667      _argvec[6] = (unsigned long)arg6;                           \
1668      _argvec[7] = (unsigned long)arg7;                           \
1669      __asm__ volatile(                                           \
1670         "mr 11,%1\n\t"                                           \
1671         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1672         "lwz 4,8(11)\n\t"                                        \
1673         "lwz 5,12(11)\n\t"                                       \
1674         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1675         "lwz 7,20(11)\n\t"                                       \
1676         "lwz 8,24(11)\n\t"                                       \
1677         "lwz 9,28(11)\n\t"                                       \
1678         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1679         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1680         "mr %0,3"                                                \
1681         : /*out*/   "=r" (_res)                                  \
1682         : /*in*/    "r" (&_argvec[0])                            \
1683         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1684      );                                                          \
1685      lval = (__typeof__(lval)) _res;                             \
1686   } while (0)
1687
1688#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1689                                 arg7,arg8)                       \
1690   do {                                                           \
1691      volatile OrigFn        _orig = (orig);                      \
1692      volatile unsigned long _argvec[9];                          \
1693      volatile unsigned long _res;                                \
1694      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1695      _argvec[1] = (unsigned long)arg1;                           \
1696      _argvec[2] = (unsigned long)arg2;                           \
1697      _argvec[3] = (unsigned long)arg3;                           \
1698      _argvec[4] = (unsigned long)arg4;                           \
1699      _argvec[5] = (unsigned long)arg5;                           \
1700      _argvec[6] = (unsigned long)arg6;                           \
1701      _argvec[7] = (unsigned long)arg7;                           \
1702      _argvec[8] = (unsigned long)arg8;                           \
1703      __asm__ volatile(                                           \
1704         "mr 11,%1\n\t"                                           \
1705         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1706         "lwz 4,8(11)\n\t"                                        \
1707         "lwz 5,12(11)\n\t"                                       \
1708         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1709         "lwz 7,20(11)\n\t"                                       \
1710         "lwz 8,24(11)\n\t"                                       \
1711         "lwz 9,28(11)\n\t"                                       \
1712         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1713         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1714         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1715         "mr %0,3"                                                \
1716         : /*out*/   "=r" (_res)                                  \
1717         : /*in*/    "r" (&_argvec[0])                            \
1718         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1719      );                                                          \
1720      lval = (__typeof__(lval)) _res;                             \
1721   } while (0)
1722
1723#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1724                                 arg7,arg8,arg9)                  \
1725   do {                                                           \
1726      volatile OrigFn        _orig = (orig);                      \
1727      volatile unsigned long _argvec[10];                         \
1728      volatile unsigned long _res;                                \
1729      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1730      _argvec[1] = (unsigned long)arg1;                           \
1731      _argvec[2] = (unsigned long)arg2;                           \
1732      _argvec[3] = (unsigned long)arg3;                           \
1733      _argvec[4] = (unsigned long)arg4;                           \
1734      _argvec[5] = (unsigned long)arg5;                           \
1735      _argvec[6] = (unsigned long)arg6;                           \
1736      _argvec[7] = (unsigned long)arg7;                           \
1737      _argvec[8] = (unsigned long)arg8;                           \
1738      _argvec[9] = (unsigned long)arg9;                           \
1739      __asm__ volatile(                                           \
1740         "mr 11,%1\n\t"                                           \
1741         "addi 1,1,-16\n\t"                                       \
1742         /* arg9 */                                               \
1743         "lwz 3,36(11)\n\t"                                       \
1744         "stw 3,8(1)\n\t"                                         \
1745         /* args1-8 */                                            \
1746         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1747         "lwz 4,8(11)\n\t"                                        \
1748         "lwz 5,12(11)\n\t"                                       \
1749         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1750         "lwz 7,20(11)\n\t"                                       \
1751         "lwz 8,24(11)\n\t"                                       \
1752         "lwz 9,28(11)\n\t"                                       \
1753         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1754         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1755         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1756         "addi 1,1,16\n\t"                                        \
1757         "mr %0,3"                                                \
1758         : /*out*/   "=r" (_res)                                  \
1759         : /*in*/    "r" (&_argvec[0])                            \
1760         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1761      );                                                          \
1762      lval = (__typeof__(lval)) _res;                             \
1763   } while (0)
1764
1765#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1766                                  arg7,arg8,arg9,arg10)           \
1767   do {                                                           \
1768      volatile OrigFn        _orig = (orig);                      \
1769      volatile unsigned long _argvec[11];                         \
1770      volatile unsigned long _res;                                \
1771      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1772      _argvec[1] = (unsigned long)arg1;                           \
1773      _argvec[2] = (unsigned long)arg2;                           \
1774      _argvec[3] = (unsigned long)arg3;                           \
1775      _argvec[4] = (unsigned long)arg4;                           \
1776      _argvec[5] = (unsigned long)arg5;                           \
1777      _argvec[6] = (unsigned long)arg6;                           \
1778      _argvec[7] = (unsigned long)arg7;                           \
1779      _argvec[8] = (unsigned long)arg8;                           \
1780      _argvec[9] = (unsigned long)arg9;                           \
1781      _argvec[10] = (unsigned long)arg10;                         \
1782      __asm__ volatile(                                           \
1783         "mr 11,%1\n\t"                                           \
1784         "addi 1,1,-16\n\t"                                       \
1785         /* arg10 */                                              \
1786         "lwz 3,40(11)\n\t"                                       \
1787         "stw 3,12(1)\n\t"                                        \
1788         /* arg9 */                                               \
1789         "lwz 3,36(11)\n\t"                                       \
1790         "stw 3,8(1)\n\t"                                         \
1791         /* args1-8 */                                            \
1792         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1793         "lwz 4,8(11)\n\t"                                        \
1794         "lwz 5,12(11)\n\t"                                       \
1795         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1796         "lwz 7,20(11)\n\t"                                       \
1797         "lwz 8,24(11)\n\t"                                       \
1798         "lwz 9,28(11)\n\t"                                       \
1799         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1800         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1801         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1802         "addi 1,1,16\n\t"                                        \
1803         "mr %0,3"                                                \
1804         : /*out*/   "=r" (_res)                                  \
1805         : /*in*/    "r" (&_argvec[0])                            \
1806         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1807      );                                                          \
1808      lval = (__typeof__(lval)) _res;                             \
1809   } while (0)
1810
1811#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1812                                  arg7,arg8,arg9,arg10,arg11)     \
1813   do {                                                           \
1814      volatile OrigFn        _orig = (orig);                      \
1815      volatile unsigned long _argvec[12];                         \
1816      volatile unsigned long _res;                                \
1817      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1818      _argvec[1] = (unsigned long)arg1;                           \
1819      _argvec[2] = (unsigned long)arg2;                           \
1820      _argvec[3] = (unsigned long)arg3;                           \
1821      _argvec[4] = (unsigned long)arg4;                           \
1822      _argvec[5] = (unsigned long)arg5;                           \
1823      _argvec[6] = (unsigned long)arg6;                           \
1824      _argvec[7] = (unsigned long)arg7;                           \
1825      _argvec[8] = (unsigned long)arg8;                           \
1826      _argvec[9] = (unsigned long)arg9;                           \
1827      _argvec[10] = (unsigned long)arg10;                         \
1828      _argvec[11] = (unsigned long)arg11;                         \
1829      __asm__ volatile(                                           \
1830         "mr 11,%1\n\t"                                           \
1831         "addi 1,1,-32\n\t"                                       \
1832         /* arg11 */                                              \
1833         "lwz 3,44(11)\n\t"                                       \
1834         "stw 3,16(1)\n\t"                                        \
1835         /* arg10 */                                              \
1836         "lwz 3,40(11)\n\t"                                       \
1837         "stw 3,12(1)\n\t"                                        \
1838         /* arg9 */                                               \
1839         "lwz 3,36(11)\n\t"                                       \
1840         "stw 3,8(1)\n\t"                                         \
1841         /* args1-8 */                                            \
1842         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1843         "lwz 4,8(11)\n\t"                                        \
1844         "lwz 5,12(11)\n\t"                                       \
1845         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1846         "lwz 7,20(11)\n\t"                                       \
1847         "lwz 8,24(11)\n\t"                                       \
1848         "lwz 9,28(11)\n\t"                                       \
1849         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1850         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1851         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1852         "addi 1,1,32\n\t"                                        \
1853         "mr %0,3"                                                \
1854         : /*out*/   "=r" (_res)                                  \
1855         : /*in*/    "r" (&_argvec[0])                            \
1856         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1857      );                                                          \
1858      lval = (__typeof__(lval)) _res;                             \
1859   } while (0)
1860
1861#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1862                                arg7,arg8,arg9,arg10,arg11,arg12) \
1863   do {                                                           \
1864      volatile OrigFn        _orig = (orig);                      \
1865      volatile unsigned long _argvec[13];                         \
1866      volatile unsigned long _res;                                \
1867      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1868      _argvec[1] = (unsigned long)arg1;                           \
1869      _argvec[2] = (unsigned long)arg2;                           \
1870      _argvec[3] = (unsigned long)arg3;                           \
1871      _argvec[4] = (unsigned long)arg4;                           \
1872      _argvec[5] = (unsigned long)arg5;                           \
1873      _argvec[6] = (unsigned long)arg6;                           \
1874      _argvec[7] = (unsigned long)arg7;                           \
1875      _argvec[8] = (unsigned long)arg8;                           \
1876      _argvec[9] = (unsigned long)arg9;                           \
1877      _argvec[10] = (unsigned long)arg10;                         \
1878      _argvec[11] = (unsigned long)arg11;                         \
1879      _argvec[12] = (unsigned long)arg12;                         \
1880      __asm__ volatile(                                           \
1881         "mr 11,%1\n\t"                                           \
1882         "addi 1,1,-32\n\t"                                       \
1883         /* arg12 */                                              \
1884         "lwz 3,48(11)\n\t"                                       \
1885         "stw 3,20(1)\n\t"                                        \
1886         /* arg11 */                                              \
1887         "lwz 3,44(11)\n\t"                                       \
1888         "stw 3,16(1)\n\t"                                        \
1889         /* arg10 */                                              \
1890         "lwz 3,40(11)\n\t"                                       \
1891         "stw 3,12(1)\n\t"                                        \
1892         /* arg9 */                                               \
1893         "lwz 3,36(11)\n\t"                                       \
1894         "stw 3,8(1)\n\t"                                         \
1895         /* args1-8 */                                            \
1896         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1897         "lwz 4,8(11)\n\t"                                        \
1898         "lwz 5,12(11)\n\t"                                       \
1899         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1900         "lwz 7,20(11)\n\t"                                       \
1901         "lwz 8,24(11)\n\t"                                       \
1902         "lwz 9,28(11)\n\t"                                       \
1903         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1904         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1905         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1906         "addi 1,1,32\n\t"                                        \
1907         "mr %0,3"                                                \
1908         : /*out*/   "=r" (_res)                                  \
1909         : /*in*/    "r" (&_argvec[0])                            \
1910         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1911      );                                                          \
1912      lval = (__typeof__(lval)) _res;                             \
1913   } while (0)
1914
1915#endif /* PLAT_ppc32_linux */
1916
1917/* ------------------------ ppc64-linux ------------------------ */
1918
1919#if defined(PLAT_ppc64_linux)
1920
1921/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1922
1923/* These regs are trashed by the hidden call. */
1924#define __CALLER_SAVED_REGS                                       \
1925   "lr", "ctr", "xer",                                            \
1926   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1927   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1928   "r11", "r12", "r13"
1929
1930/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
1931   long) == 8. */
1932
1933#define CALL_FN_W_v(lval, orig)                                   \
1934   do {                                                           \
1935      volatile OrigFn        _orig = (orig);                      \
1936      volatile unsigned long _argvec[3+0];                        \
1937      volatile unsigned long _res;                                \
1938      /* _argvec[0] holds current r2 across the call */           \
1939      _argvec[1] = (unsigned long)_orig.r2;                       \
1940      _argvec[2] = (unsigned long)_orig.nraddr;                   \
1941      __asm__ volatile(                                           \
1942         "mr 11,%1\n\t"                                           \
1943         "std 2,-16(11)\n\t"  /* save tocptr */                   \
1944         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
1945         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
1946         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1947         "mr 11,%1\n\t"                                           \
1948         "mr %0,3\n\t"                                            \
1949         "ld 2,-16(11)" /* restore tocptr */                      \
1950         : /*out*/   "=r" (_res)                                  \
1951         : /*in*/    "r" (&_argvec[2])                            \
1952         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1953      );                                                          \
1954      lval = (__typeof__(lval)) _res;                             \
1955   } while (0)
1956
1957#define CALL_FN_W_W(lval, orig, arg1)                             \
1958   do {                                                           \
1959      volatile OrigFn        _orig = (orig);                      \
1960      volatile unsigned long _argvec[3+1];                        \
1961      volatile unsigned long _res;                                \
1962      /* _argvec[0] holds current r2 across the call */           \
1963      _argvec[1]   = (unsigned long)_orig.r2;                     \
1964      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
1965      _argvec[2+1] = (unsigned long)arg1;                         \
1966      __asm__ volatile(                                           \
1967         "mr 11,%1\n\t"                                           \
1968         "std 2,-16(11)\n\t"  /* save tocptr */                   \
1969         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
1970         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
1971         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
1972         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1973         "mr 11,%1\n\t"                                           \
1974         "mr %0,3\n\t"                                            \
1975         "ld 2,-16(11)" /* restore tocptr */                      \
1976         : /*out*/   "=r" (_res)                                  \
1977         : /*in*/    "r" (&_argvec[2])                            \
1978         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1979      );                                                          \
1980      lval = (__typeof__(lval)) _res;                             \
1981   } while (0)
1982
1983#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
1984   do {                                                           \
1985      volatile OrigFn        _orig = (orig);                      \
1986      volatile unsigned long _argvec[3+2];                        \
1987      volatile unsigned long _res;                                \
1988      /* _argvec[0] holds current r2 across the call */           \
1989      _argvec[1]   = (unsigned long)_orig.r2;                     \
1990      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
1991      _argvec[2+1] = (unsigned long)arg1;                         \
1992      _argvec[2+2] = (unsigned long)arg2;                         \
1993      __asm__ volatile(                                           \
1994         "mr 11,%1\n\t"                                           \
1995         "std 2,-16(11)\n\t"  /* save tocptr */                   \
1996         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
1997         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
1998         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
1999         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2000         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2001         "mr 11,%1\n\t"                                           \
2002         "mr %0,3\n\t"                                            \
2003         "ld 2,-16(11)" /* restore tocptr */                      \
2004         : /*out*/   "=r" (_res)                                  \
2005         : /*in*/    "r" (&_argvec[2])                            \
2006         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2007      );                                                          \
2008      lval = (__typeof__(lval)) _res;                             \
2009   } while (0)
2010
2011#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2012   do {                                                           \
2013      volatile OrigFn        _orig = (orig);                      \
2014      volatile unsigned long _argvec[3+3];                        \
2015      volatile unsigned long _res;                                \
2016      /* _argvec[0] holds current r2 across the call */           \
2017      _argvec[1]   = (unsigned long)_orig.r2;                     \
2018      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2019      _argvec[2+1] = (unsigned long)arg1;                         \
2020      _argvec[2+2] = (unsigned long)arg2;                         \
2021      _argvec[2+3] = (unsigned long)arg3;                         \
2022      __asm__ volatile(                                           \
2023         "mr 11,%1\n\t"                                           \
2024         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2025         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2026         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2027         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2028         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2029         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2030         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2031         "mr 11,%1\n\t"                                           \
2032         "mr %0,3\n\t"                                            \
2033         "ld 2,-16(11)" /* restore tocptr */                      \
2034         : /*out*/   "=r" (_res)                                  \
2035         : /*in*/    "r" (&_argvec[2])                            \
2036         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2037      );                                                          \
2038      lval = (__typeof__(lval)) _res;                             \
2039   } while (0)
2040
2041#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2042   do {                                                           \
2043      volatile OrigFn        _orig = (orig);                      \
2044      volatile unsigned long _argvec[3+4];                        \
2045      volatile unsigned long _res;                                \
2046      /* _argvec[0] holds current r2 across the call */           \
2047      _argvec[1]   = (unsigned long)_orig.r2;                     \
2048      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2049      _argvec[2+1] = (unsigned long)arg1;                         \
2050      _argvec[2+2] = (unsigned long)arg2;                         \
2051      _argvec[2+3] = (unsigned long)arg3;                         \
2052      _argvec[2+4] = (unsigned long)arg4;                         \
2053      __asm__ volatile(                                           \
2054         "mr 11,%1\n\t"                                           \
2055         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2056         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2057         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2058         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2059         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2060         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2061         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2062         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2063         "mr 11,%1\n\t"                                           \
2064         "mr %0,3\n\t"                                            \
2065         "ld 2,-16(11)" /* restore tocptr */                      \
2066         : /*out*/   "=r" (_res)                                  \
2067         : /*in*/    "r" (&_argvec[2])                            \
2068         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2069      );                                                          \
2070      lval = (__typeof__(lval)) _res;                             \
2071   } while (0)
2072
2073#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2074   do {                                                           \
2075      volatile OrigFn        _orig = (orig);                      \
2076      volatile unsigned long _argvec[3+5];                        \
2077      volatile unsigned long _res;                                \
2078      /* _argvec[0] holds current r2 across the call */           \
2079      _argvec[1]   = (unsigned long)_orig.r2;                     \
2080      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2081      _argvec[2+1] = (unsigned long)arg1;                         \
2082      _argvec[2+2] = (unsigned long)arg2;                         \
2083      _argvec[2+3] = (unsigned long)arg3;                         \
2084      _argvec[2+4] = (unsigned long)arg4;                         \
2085      _argvec[2+5] = (unsigned long)arg5;                         \
2086      __asm__ volatile(                                           \
2087         "mr 11,%1\n\t"                                           \
2088         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2089         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2090         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2091         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2092         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2093         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2094         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2095         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2096         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2097         "mr 11,%1\n\t"                                           \
2098         "mr %0,3\n\t"                                            \
2099         "ld 2,-16(11)" /* restore tocptr */                      \
2100         : /*out*/   "=r" (_res)                                  \
2101         : /*in*/    "r" (&_argvec[2])                            \
2102         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2103      );                                                          \
2104      lval = (__typeof__(lval)) _res;                             \
2105   } while (0)
2106
2107#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2108   do {                                                           \
2109      volatile OrigFn        _orig = (orig);                      \
2110      volatile unsigned long _argvec[3+6];                        \
2111      volatile unsigned long _res;                                \
2112      /* _argvec[0] holds current r2 across the call */           \
2113      _argvec[1]   = (unsigned long)_orig.r2;                     \
2114      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2115      _argvec[2+1] = (unsigned long)arg1;                         \
2116      _argvec[2+2] = (unsigned long)arg2;                         \
2117      _argvec[2+3] = (unsigned long)arg3;                         \
2118      _argvec[2+4] = (unsigned long)arg4;                         \
2119      _argvec[2+5] = (unsigned long)arg5;                         \
2120      _argvec[2+6] = (unsigned long)arg6;                         \
2121      __asm__ volatile(                                           \
2122         "mr 11,%1\n\t"                                           \
2123         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2124         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2125         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2126         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2127         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2128         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2129         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2130         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2131         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2132         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2133         "mr 11,%1\n\t"                                           \
2134         "mr %0,3\n\t"                                            \
2135         "ld 2,-16(11)" /* restore tocptr */                      \
2136         : /*out*/   "=r" (_res)                                  \
2137         : /*in*/    "r" (&_argvec[2])                            \
2138         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2139      );                                                          \
2140      lval = (__typeof__(lval)) _res;                             \
2141   } while (0)
2142
2143#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2144                                 arg7)                            \
2145   do {                                                           \
2146      volatile OrigFn        _orig = (orig);                      \
2147      volatile unsigned long _argvec[3+7];                        \
2148      volatile unsigned long _res;                                \
2149      /* _argvec[0] holds current r2 across the call */           \
2150      _argvec[1]   = (unsigned long)_orig.r2;                     \
2151      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2152      _argvec[2+1] = (unsigned long)arg1;                         \
2153      _argvec[2+2] = (unsigned long)arg2;                         \
2154      _argvec[2+3] = (unsigned long)arg3;                         \
2155      _argvec[2+4] = (unsigned long)arg4;                         \
2156      _argvec[2+5] = (unsigned long)arg5;                         \
2157      _argvec[2+6] = (unsigned long)arg6;                         \
2158      _argvec[2+7] = (unsigned long)arg7;                         \
2159      __asm__ volatile(                                           \
2160         "mr 11,%1\n\t"                                           \
2161         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2162         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2163         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2164         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2165         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2166         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2167         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2168         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2169         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2170         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2171         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2172         "mr 11,%1\n\t"                                           \
2173         "mr %0,3\n\t"                                            \
2174         "ld 2,-16(11)" /* restore tocptr */                      \
2175         : /*out*/   "=r" (_res)                                  \
2176         : /*in*/    "r" (&_argvec[2])                            \
2177         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2178      );                                                          \
2179      lval = (__typeof__(lval)) _res;                             \
2180   } while (0)
2181
2182#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2183                                 arg7,arg8)                       \
2184   do {                                                           \
2185      volatile OrigFn        _orig = (orig);                      \
2186      volatile unsigned long _argvec[3+8];                        \
2187      volatile unsigned long _res;                                \
2188      /* _argvec[0] holds current r2 across the call */           \
2189      _argvec[1]   = (unsigned long)_orig.r2;                     \
2190      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2191      _argvec[2+1] = (unsigned long)arg1;                         \
2192      _argvec[2+2] = (unsigned long)arg2;                         \
2193      _argvec[2+3] = (unsigned long)arg3;                         \
2194      _argvec[2+4] = (unsigned long)arg4;                         \
2195      _argvec[2+5] = (unsigned long)arg5;                         \
2196      _argvec[2+6] = (unsigned long)arg6;                         \
2197      _argvec[2+7] = (unsigned long)arg7;                         \
2198      _argvec[2+8] = (unsigned long)arg8;                         \
2199      __asm__ volatile(                                           \
2200         "mr 11,%1\n\t"                                           \
2201         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2202         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2203         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2204         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2205         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2206         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2207         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2208         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2209         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2210         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2211         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2212         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2213         "mr 11,%1\n\t"                                           \
2214         "mr %0,3\n\t"                                            \
2215         "ld 2,-16(11)" /* restore tocptr */                      \
2216         : /*out*/   "=r" (_res)                                  \
2217         : /*in*/    "r" (&_argvec[2])                            \
2218         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2219      );                                                          \
2220      lval = (__typeof__(lval)) _res;                             \
2221   } while (0)
2222
2223#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2224                                 arg7,arg8,arg9)                  \
2225   do {                                                           \
2226      volatile OrigFn        _orig = (orig);                      \
2227      volatile unsigned long _argvec[3+9];                        \
2228      volatile unsigned long _res;                                \
2229      /* _argvec[0] holds current r2 across the call */           \
2230      _argvec[1]   = (unsigned long)_orig.r2;                     \
2231      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2232      _argvec[2+1] = (unsigned long)arg1;                         \
2233      _argvec[2+2] = (unsigned long)arg2;                         \
2234      _argvec[2+3] = (unsigned long)arg3;                         \
2235      _argvec[2+4] = (unsigned long)arg4;                         \
2236      _argvec[2+5] = (unsigned long)arg5;                         \
2237      _argvec[2+6] = (unsigned long)arg6;                         \
2238      _argvec[2+7] = (unsigned long)arg7;                         \
2239      _argvec[2+8] = (unsigned long)arg8;                         \
2240      _argvec[2+9] = (unsigned long)arg9;                         \
2241      __asm__ volatile(                                           \
2242         "mr 11,%1\n\t"                                           \
2243         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2244         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2245         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2246         /* arg9 */                                               \
2247         "ld  3,72(11)\n\t"                                       \
2248         "std 3,112(1)\n\t"                                       \
2249         /* args1-8 */                                            \
2250         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2251         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2252         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2253         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2254         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2255         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2256         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2257         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2258         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2259         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2260         "mr 11,%1\n\t"                                           \
2261         "mr %0,3\n\t"                                            \
2262         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2263         "addi 1,1,128"     /* restore frame */                   \
2264         : /*out*/   "=r" (_res)                                  \
2265         : /*in*/    "r" (&_argvec[2])                            \
2266         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2267      );                                                          \
2268      lval = (__typeof__(lval)) _res;                             \
2269   } while (0)
2270
2271#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2272                                  arg7,arg8,arg9,arg10)           \
2273   do {                                                           \
2274      volatile OrigFn        _orig = (orig);                      \
2275      volatile unsigned long _argvec[3+10];                       \
2276      volatile unsigned long _res;                                \
2277      /* _argvec[0] holds current r2 across the call */           \
2278      _argvec[1]   = (unsigned long)_orig.r2;                     \
2279      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2280      _argvec[2+1] = (unsigned long)arg1;                         \
2281      _argvec[2+2] = (unsigned long)arg2;                         \
2282      _argvec[2+3] = (unsigned long)arg3;                         \
2283      _argvec[2+4] = (unsigned long)arg4;                         \
2284      _argvec[2+5] = (unsigned long)arg5;                         \
2285      _argvec[2+6] = (unsigned long)arg6;                         \
2286      _argvec[2+7] = (unsigned long)arg7;                         \
2287      _argvec[2+8] = (unsigned long)arg8;                         \
2288      _argvec[2+9] = (unsigned long)arg9;                         \
2289      _argvec[2+10] = (unsigned long)arg10;                       \
2290      __asm__ volatile(                                           \
2291         "mr 11,%1\n\t"                                           \
2292         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2293         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2294         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2295         /* arg10 */                                              \
2296         "ld  3,80(11)\n\t"                                       \
2297         "std 3,120(1)\n\t"                                       \
2298         /* arg9 */                                               \
2299         "ld  3,72(11)\n\t"                                       \
2300         "std 3,112(1)\n\t"                                       \
2301         /* args1-8 */                                            \
2302         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2303         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2304         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2305         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2306         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2307         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2308         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2309         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2310         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2311         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2312         "mr 11,%1\n\t"                                           \
2313         "mr %0,3\n\t"                                            \
2314         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2315         "addi 1,1,128"     /* restore frame */                   \
2316         : /*out*/   "=r" (_res)                                  \
2317         : /*in*/    "r" (&_argvec[2])                            \
2318         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2319      );                                                          \
2320      lval = (__typeof__(lval)) _res;                             \
2321   } while (0)
2322
2323#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2324                                  arg7,arg8,arg9,arg10,arg11)     \
2325   do {                                                           \
2326      volatile OrigFn        _orig = (orig);                      \
2327      volatile unsigned long _argvec[3+11];                       \
2328      volatile unsigned long _res;                                \
2329      /* _argvec[0] holds current r2 across the call */           \
2330      _argvec[1]   = (unsigned long)_orig.r2;                     \
2331      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2332      _argvec[2+1] = (unsigned long)arg1;                         \
2333      _argvec[2+2] = (unsigned long)arg2;                         \
2334      _argvec[2+3] = (unsigned long)arg3;                         \
2335      _argvec[2+4] = (unsigned long)arg4;                         \
2336      _argvec[2+5] = (unsigned long)arg5;                         \
2337      _argvec[2+6] = (unsigned long)arg6;                         \
2338      _argvec[2+7] = (unsigned long)arg7;                         \
2339      _argvec[2+8] = (unsigned long)arg8;                         \
2340      _argvec[2+9] = (unsigned long)arg9;                         \
2341      _argvec[2+10] = (unsigned long)arg10;                       \
2342      _argvec[2+11] = (unsigned long)arg11;                       \
2343      __asm__ volatile(                                           \
2344         "mr 11,%1\n\t"                                           \
2345         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2346         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2347         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2348         /* arg11 */                                              \
2349         "ld  3,88(11)\n\t"                                       \
2350         "std 3,128(1)\n\t"                                       \
2351         /* arg10 */                                              \
2352         "ld  3,80(11)\n\t"                                       \
2353         "std 3,120(1)\n\t"                                       \
2354         /* arg9 */                                               \
2355         "ld  3,72(11)\n\t"                                       \
2356         "std 3,112(1)\n\t"                                       \
2357         /* args1-8 */                                            \
2358         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2359         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2360         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2361         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2362         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2363         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2364         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2365         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2366         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2367         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2368         "mr 11,%1\n\t"                                           \
2369         "mr %0,3\n\t"                                            \
2370         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2371         "addi 1,1,144"     /* restore frame */                   \
2372         : /*out*/   "=r" (_res)                                  \
2373         : /*in*/    "r" (&_argvec[2])                            \
2374         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2375      );                                                          \
2376      lval = (__typeof__(lval)) _res;                             \
2377   } while (0)
2378
2379#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2380                                arg7,arg8,arg9,arg10,arg11,arg12) \
2381   do {                                                           \
2382      volatile OrigFn        _orig = (orig);                      \
2383      volatile unsigned long _argvec[3+12];                       \
2384      volatile unsigned long _res;                                \
2385      /* _argvec[0] holds current r2 across the call */           \
2386      _argvec[1]   = (unsigned long)_orig.r2;                     \
2387      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2388      _argvec[2+1] = (unsigned long)arg1;                         \
2389      _argvec[2+2] = (unsigned long)arg2;                         \
2390      _argvec[2+3] = (unsigned long)arg3;                         \
2391      _argvec[2+4] = (unsigned long)arg4;                         \
2392      _argvec[2+5] = (unsigned long)arg5;                         \
2393      _argvec[2+6] = (unsigned long)arg6;                         \
2394      _argvec[2+7] = (unsigned long)arg7;                         \
2395      _argvec[2+8] = (unsigned long)arg8;                         \
2396      _argvec[2+9] = (unsigned long)arg9;                         \
2397      _argvec[2+10] = (unsigned long)arg10;                       \
2398      _argvec[2+11] = (unsigned long)arg11;                       \
2399      _argvec[2+12] = (unsigned long)arg12;                       \
2400      __asm__ volatile(                                           \
2401         "mr 11,%1\n\t"                                           \
2402         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2403         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2404         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2405         /* arg12 */                                              \
2406         "ld  3,96(11)\n\t"                                       \
2407         "std 3,136(1)\n\t"                                       \
2408         /* arg11 */                                              \
2409         "ld  3,88(11)\n\t"                                       \
2410         "std 3,128(1)\n\t"                                       \
2411         /* arg10 */                                              \
2412         "ld  3,80(11)\n\t"                                       \
2413         "std 3,120(1)\n\t"                                       \
2414         /* arg9 */                                               \
2415         "ld  3,72(11)\n\t"                                       \
2416         "std 3,112(1)\n\t"                                       \
2417         /* args1-8 */                                            \
2418         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2419         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2420         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2421         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2422         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2423         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2424         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2425         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2426         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2427         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2428         "mr 11,%1\n\t"                                           \
2429         "mr %0,3\n\t"                                            \
2430         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2431         "addi 1,1,144"     /* restore frame */                   \
2432         : /*out*/   "=r" (_res)                                  \
2433         : /*in*/    "r" (&_argvec[2])                            \
2434         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2435      );                                                          \
2436      lval = (__typeof__(lval)) _res;                             \
2437   } while (0)
2438
2439#endif /* PLAT_ppc64_linux */
2440
2441/* ------------------------ ppc32-aix5 ------------------------- */
2442
2443#if defined(PLAT_ppc32_aix5)
2444
2445/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2446
2447/* These regs are trashed by the hidden call. */
2448#define __CALLER_SAVED_REGS                                       \
2449   "lr", "ctr", "xer",                                            \
2450   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2451   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2452   "r11", "r12", "r13"
2453
2454/* Expand the stack frame, copying enough info that unwinding
2455   still works.  Trashes r3. */
2456
2457#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
2458         "addi 1,1,-" #_n_fr "\n\t"                               \
2459         "lwz  3," #_n_fr "(1)\n\t"                               \
2460         "stw  3,0(1)\n\t"
2461
2462#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
2463         "addi 1,1," #_n_fr "\n\t"
2464
2465/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
2466   long) == 4. */
2467
2468#define CALL_FN_W_v(lval, orig)                                   \
2469   do {                                                           \
2470      volatile OrigFn        _orig = (orig);                      \
2471      volatile unsigned long _argvec[3+0];                        \
2472      volatile unsigned long _res;                                \
2473      /* _argvec[0] holds current r2 across the call */           \
2474      _argvec[1] = (unsigned long)_orig.r2;                       \
2475      _argvec[2] = (unsigned long)_orig.nraddr;                   \
2476      __asm__ volatile(                                           \
2477         "mr 11,%1\n\t"                                           \
2478         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2479         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2480         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2481         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2482         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2483         "mr 11,%1\n\t"                                           \
2484         "mr %0,3\n\t"                                            \
2485         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2486         VG_CONTRACT_FRAME_BY(512)                                \
2487         : /*out*/   "=r" (_res)                                  \
2488         : /*in*/    "r" (&_argvec[2])                            \
2489         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2490      );                                                          \
2491      lval = (__typeof__(lval)) _res;                             \
2492   } while (0)
2493
2494#define CALL_FN_W_W(lval, orig, arg1)                             \
2495   do {                                                           \
2496      volatile OrigFn        _orig = (orig);                      \
2497      volatile unsigned long _argvec[3+1];                        \
2498      volatile unsigned long _res;                                \
2499      /* _argvec[0] holds current r2 across the call */           \
2500      _argvec[1]   = (unsigned long)_orig.r2;                     \
2501      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2502      _argvec[2+1] = (unsigned long)arg1;                         \
2503      __asm__ volatile(                                           \
2504         "mr 11,%1\n\t"                                           \
2505         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2506         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2507         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2508         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2509         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2510         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2511         "mr 11,%1\n\t"                                           \
2512         "mr %0,3\n\t"                                            \
2513         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2514         VG_CONTRACT_FRAME_BY(512)                                \
2515         : /*out*/   "=r" (_res)                                  \
2516         : /*in*/    "r" (&_argvec[2])                            \
2517         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2518      );                                                          \
2519      lval = (__typeof__(lval)) _res;                             \
2520   } while (0)
2521
2522#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2523   do {                                                           \
2524      volatile OrigFn        _orig = (orig);                      \
2525      volatile unsigned long _argvec[3+2];                        \
2526      volatile unsigned long _res;                                \
2527      /* _argvec[0] holds current r2 across the call */           \
2528      _argvec[1]   = (unsigned long)_orig.r2;                     \
2529      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2530      _argvec[2+1] = (unsigned long)arg1;                         \
2531      _argvec[2+2] = (unsigned long)arg2;                         \
2532      __asm__ volatile(                                           \
2533         "mr 11,%1\n\t"                                           \
2534         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2535         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2536         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2537         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2538         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2539         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2540         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2541         "mr 11,%1\n\t"                                           \
2542         "mr %0,3\n\t"                                            \
2543         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2544         VG_CONTRACT_FRAME_BY(512)                                \
2545         : /*out*/   "=r" (_res)                                  \
2546         : /*in*/    "r" (&_argvec[2])                            \
2547         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2548      );                                                          \
2549      lval = (__typeof__(lval)) _res;                             \
2550   } while (0)
2551
2552#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2553   do {                                                           \
2554      volatile OrigFn        _orig = (orig);                      \
2555      volatile unsigned long _argvec[3+3];                        \
2556      volatile unsigned long _res;                                \
2557      /* _argvec[0] holds current r2 across the call */           \
2558      _argvec[1]   = (unsigned long)_orig.r2;                     \
2559      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2560      _argvec[2+1] = (unsigned long)arg1;                         \
2561      _argvec[2+2] = (unsigned long)arg2;                         \
2562      _argvec[2+3] = (unsigned long)arg3;                         \
2563      __asm__ volatile(                                           \
2564         "mr 11,%1\n\t"                                           \
2565         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2566         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2567         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2568         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2569         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2570         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2571         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2572         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2573         "mr 11,%1\n\t"                                           \
2574         "mr %0,3\n\t"                                            \
2575         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2576         VG_CONTRACT_FRAME_BY(512)                                \
2577         : /*out*/   "=r" (_res)                                  \
2578         : /*in*/    "r" (&_argvec[2])                            \
2579         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2580      );                                                          \
2581      lval = (__typeof__(lval)) _res;                             \
2582   } while (0)
2583
2584#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2585   do {                                                           \
2586      volatile OrigFn        _orig = (orig);                      \
2587      volatile unsigned long _argvec[3+4];                        \
2588      volatile unsigned long _res;                                \
2589      /* _argvec[0] holds current r2 across the call */           \
2590      _argvec[1]   = (unsigned long)_orig.r2;                     \
2591      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2592      _argvec[2+1] = (unsigned long)arg1;                         \
2593      _argvec[2+2] = (unsigned long)arg2;                         \
2594      _argvec[2+3] = (unsigned long)arg3;                         \
2595      _argvec[2+4] = (unsigned long)arg4;                         \
2596      __asm__ volatile(                                           \
2597         "mr 11,%1\n\t"                                           \
2598         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2599         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2600         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2601         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2602         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2603         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2604         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2605         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2606         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2607         "mr 11,%1\n\t"                                           \
2608         "mr %0,3\n\t"                                            \
2609         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2610         VG_CONTRACT_FRAME_BY(512)                                \
2611         : /*out*/   "=r" (_res)                                  \
2612         : /*in*/    "r" (&_argvec[2])                            \
2613         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2614      );                                                          \
2615      lval = (__typeof__(lval)) _res;                             \
2616   } while (0)
2617
2618#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2619   do {                                                           \
2620      volatile OrigFn        _orig = (orig);                      \
2621      volatile unsigned long _argvec[3+5];                        \
2622      volatile unsigned long _res;                                \
2623      /* _argvec[0] holds current r2 across the call */           \
2624      _argvec[1]   = (unsigned long)_orig.r2;                     \
2625      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2626      _argvec[2+1] = (unsigned long)arg1;                         \
2627      _argvec[2+2] = (unsigned long)arg2;                         \
2628      _argvec[2+3] = (unsigned long)arg3;                         \
2629      _argvec[2+4] = (unsigned long)arg4;                         \
2630      _argvec[2+5] = (unsigned long)arg5;                         \
2631      __asm__ volatile(                                           \
2632         "mr 11,%1\n\t"                                           \
2633         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2634         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2635         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2636         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2637         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
2638         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2639         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2640         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2641         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2642         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2643         "mr 11,%1\n\t"                                           \
2644         "mr %0,3\n\t"                                            \
2645         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2646         VG_CONTRACT_FRAME_BY(512)                                \
2647         : /*out*/   "=r" (_res)                                  \
2648         : /*in*/    "r" (&_argvec[2])                            \
2649         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2650      );                                                          \
2651      lval = (__typeof__(lval)) _res;                             \
2652   } while (0)
2653
2654#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2655   do {                                                           \
2656      volatile OrigFn        _orig = (orig);                      \
2657      volatile unsigned long _argvec[3+6];                        \
2658      volatile unsigned long _res;                                \
2659      /* _argvec[0] holds current r2 across the call */           \
2660      _argvec[1]   = (unsigned long)_orig.r2;                     \
2661      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2662      _argvec[2+1] = (unsigned long)arg1;                         \
2663      _argvec[2+2] = (unsigned long)arg2;                         \
2664      _argvec[2+3] = (unsigned long)arg3;                         \
2665      _argvec[2+4] = (unsigned long)arg4;                         \
2666      _argvec[2+5] = (unsigned long)arg5;                         \
2667      _argvec[2+6] = (unsigned long)arg6;                         \
2668      __asm__ volatile(                                           \
2669         "mr 11,%1\n\t"                                           \
2670         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2671         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2672         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2673         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2674         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2675         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2676         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2677         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2678         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2679         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2680         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2681         "mr 11,%1\n\t"                                           \
2682         "mr %0,3\n\t"                                            \
2683         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2684         VG_CONTRACT_FRAME_BY(512)                                \
2685         : /*out*/   "=r" (_res)                                  \
2686         : /*in*/    "r" (&_argvec[2])                            \
2687         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2688      );                                                          \
2689      lval = (__typeof__(lval)) _res;                             \
2690   } while (0)
2691
2692#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2693                                 arg7)                            \
2694   do {                                                           \
2695      volatile OrigFn        _orig = (orig);                      \
2696      volatile unsigned long _argvec[3+7];                        \
2697      volatile unsigned long _res;                                \
2698      /* _argvec[0] holds current r2 across the call */           \
2699      _argvec[1]   = (unsigned long)_orig.r2;                     \
2700      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2701      _argvec[2+1] = (unsigned long)arg1;                         \
2702      _argvec[2+2] = (unsigned long)arg2;                         \
2703      _argvec[2+3] = (unsigned long)arg3;                         \
2704      _argvec[2+4] = (unsigned long)arg4;                         \
2705      _argvec[2+5] = (unsigned long)arg5;                         \
2706      _argvec[2+6] = (unsigned long)arg6;                         \
2707      _argvec[2+7] = (unsigned long)arg7;                         \
2708      __asm__ volatile(                                           \
2709         "mr 11,%1\n\t"                                           \
2710         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2711         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2712         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2713         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2714         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2715         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2716         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2717         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2718         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2719         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2720         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2721         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2722         "mr 11,%1\n\t"                                           \
2723         "mr %0,3\n\t"                                            \
2724         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2725         VG_CONTRACT_FRAME_BY(512)                                \
2726         : /*out*/   "=r" (_res)                                  \
2727         : /*in*/    "r" (&_argvec[2])                            \
2728         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2729      );                                                          \
2730      lval = (__typeof__(lval)) _res;                             \
2731   } while (0)
2732
2733#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2734                                 arg7,arg8)                       \
2735   do {                                                           \
2736      volatile OrigFn        _orig = (orig);                      \
2737      volatile unsigned long _argvec[3+8];                        \
2738      volatile unsigned long _res;                                \
2739      /* _argvec[0] holds current r2 across the call */           \
2740      _argvec[1]   = (unsigned long)_orig.r2;                     \
2741      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2742      _argvec[2+1] = (unsigned long)arg1;                         \
2743      _argvec[2+2] = (unsigned long)arg2;                         \
2744      _argvec[2+3] = (unsigned long)arg3;                         \
2745      _argvec[2+4] = (unsigned long)arg4;                         \
2746      _argvec[2+5] = (unsigned long)arg5;                         \
2747      _argvec[2+6] = (unsigned long)arg6;                         \
2748      _argvec[2+7] = (unsigned long)arg7;                         \
2749      _argvec[2+8] = (unsigned long)arg8;                         \
2750      __asm__ volatile(                                           \
2751         "mr 11,%1\n\t"                                           \
2752         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2753         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2754         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2755         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2756         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2757         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2758         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2759         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2760         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2761         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2762         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2763         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2764         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2765         "mr 11,%1\n\t"                                           \
2766         "mr %0,3\n\t"                                            \
2767         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2768         VG_CONTRACT_FRAME_BY(512)                                \
2769         : /*out*/   "=r" (_res)                                  \
2770         : /*in*/    "r" (&_argvec[2])                            \
2771         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2772      );                                                          \
2773      lval = (__typeof__(lval)) _res;                             \
2774   } while (0)
2775
2776#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2777                                 arg7,arg8,arg9)                  \
2778   do {                                                           \
2779      volatile OrigFn        _orig = (orig);                      \
2780      volatile unsigned long _argvec[3+9];                        \
2781      volatile unsigned long _res;                                \
2782      /* _argvec[0] holds current r2 across the call */           \
2783      _argvec[1]   = (unsigned long)_orig.r2;                     \
2784      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2785      _argvec[2+1] = (unsigned long)arg1;                         \
2786      _argvec[2+2] = (unsigned long)arg2;                         \
2787      _argvec[2+3] = (unsigned long)arg3;                         \
2788      _argvec[2+4] = (unsigned long)arg4;                         \
2789      _argvec[2+5] = (unsigned long)arg5;                         \
2790      _argvec[2+6] = (unsigned long)arg6;                         \
2791      _argvec[2+7] = (unsigned long)arg7;                         \
2792      _argvec[2+8] = (unsigned long)arg8;                         \
2793      _argvec[2+9] = (unsigned long)arg9;                         \
2794      __asm__ volatile(                                           \
2795         "mr 11,%1\n\t"                                           \
2796         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2797         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2798         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2799         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
2800         /* arg9 */                                               \
2801         "lwz 3,36(11)\n\t"                                       \
2802         "stw 3,56(1)\n\t"                                        \
2803         /* args1-8 */                                            \
2804         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2805         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2806         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2807         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2808         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2809         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2810         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2811         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2812         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2813         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2814         "mr 11,%1\n\t"                                           \
2815         "mr %0,3\n\t"                                            \
2816         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2817         VG_CONTRACT_FRAME_BY(64)                                 \
2818         VG_CONTRACT_FRAME_BY(512)                                \
2819         : /*out*/   "=r" (_res)                                  \
2820         : /*in*/    "r" (&_argvec[2])                            \
2821         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2822      );                                                          \
2823      lval = (__typeof__(lval)) _res;                             \
2824   } while (0)
2825
2826#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2827                                  arg7,arg8,arg9,arg10)           \
2828   do {                                                           \
2829      volatile OrigFn        _orig = (orig);                      \
2830      volatile unsigned long _argvec[3+10];                       \
2831      volatile unsigned long _res;                                \
2832      /* _argvec[0] holds current r2 across the call */           \
2833      _argvec[1]   = (unsigned long)_orig.r2;                     \
2834      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2835      _argvec[2+1] = (unsigned long)arg1;                         \
2836      _argvec[2+2] = (unsigned long)arg2;                         \
2837      _argvec[2+3] = (unsigned long)arg3;                         \
2838      _argvec[2+4] = (unsigned long)arg4;                         \
2839      _argvec[2+5] = (unsigned long)arg5;                         \
2840      _argvec[2+6] = (unsigned long)arg6;                         \
2841      _argvec[2+7] = (unsigned long)arg7;                         \
2842      _argvec[2+8] = (unsigned long)arg8;                         \
2843      _argvec[2+9] = (unsigned long)arg9;                         \
2844      _argvec[2+10] = (unsigned long)arg10;                       \
2845      __asm__ volatile(                                           \
2846         "mr 11,%1\n\t"                                           \
2847         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2848         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2849         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2850         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
2851         /* arg10 */                                              \
2852         "lwz 3,40(11)\n\t"                                       \
2853         "stw 3,60(1)\n\t"                                        \
2854         /* arg9 */                                               \
2855         "lwz 3,36(11)\n\t"                                       \
2856         "stw 3,56(1)\n\t"                                        \
2857         /* args1-8 */                                            \
2858         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2859         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2860         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2861         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2862         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2863         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2864         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2865         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2866         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2867         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2868         "mr 11,%1\n\t"                                           \
2869         "mr %0,3\n\t"                                            \
2870         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2871         VG_CONTRACT_FRAME_BY(64)                                 \
2872         VG_CONTRACT_FRAME_BY(512)                                \
2873         : /*out*/   "=r" (_res)                                  \
2874         : /*in*/    "r" (&_argvec[2])                            \
2875         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2876      );                                                          \
2877      lval = (__typeof__(lval)) _res;                             \
2878   } while (0)
2879
2880#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2881                                  arg7,arg8,arg9,arg10,arg11)     \
2882   do {                                                           \
2883      volatile OrigFn        _orig = (orig);                      \
2884      volatile unsigned long _argvec[3+11];                       \
2885      volatile unsigned long _res;                                \
2886      /* _argvec[0] holds current r2 across the call */           \
2887      _argvec[1]   = (unsigned long)_orig.r2;                     \
2888      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2889      _argvec[2+1] = (unsigned long)arg1;                         \
2890      _argvec[2+2] = (unsigned long)arg2;                         \
2891      _argvec[2+3] = (unsigned long)arg3;                         \
2892      _argvec[2+4] = (unsigned long)arg4;                         \
2893      _argvec[2+5] = (unsigned long)arg5;                         \
2894      _argvec[2+6] = (unsigned long)arg6;                         \
2895      _argvec[2+7] = (unsigned long)arg7;                         \
2896      _argvec[2+8] = (unsigned long)arg8;                         \
2897      _argvec[2+9] = (unsigned long)arg9;                         \
2898      _argvec[2+10] = (unsigned long)arg10;                       \
2899      _argvec[2+11] = (unsigned long)arg11;                       \
2900      __asm__ volatile(                                           \
2901         "mr 11,%1\n\t"                                           \
2902         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2903         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2904         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2905         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
2906         /* arg11 */                                              \
2907         "lwz 3,44(11)\n\t"                                       \
2908         "stw 3,64(1)\n\t"                                        \
2909         /* arg10 */                                              \
2910         "lwz 3,40(11)\n\t"                                       \
2911         "stw 3,60(1)\n\t"                                        \
2912         /* arg9 */                                               \
2913         "lwz 3,36(11)\n\t"                                       \
2914         "stw 3,56(1)\n\t"                                        \
2915         /* args1-8 */                                            \
2916         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2917         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2918         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2919         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2920         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2921         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2922         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2923         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2924         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2925         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2926         "mr 11,%1\n\t"                                           \
2927         "mr %0,3\n\t"                                            \
2928         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2929         VG_CONTRACT_FRAME_BY(72)                                 \
2930         VG_CONTRACT_FRAME_BY(512)                                \
2931         : /*out*/   "=r" (_res)                                  \
2932         : /*in*/    "r" (&_argvec[2])                            \
2933         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2934      );                                                          \
2935      lval = (__typeof__(lval)) _res;                             \
2936   } while (0)
2937
2938#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2939                                arg7,arg8,arg9,arg10,arg11,arg12) \
2940   do {                                                           \
2941      volatile OrigFn        _orig = (orig);                      \
2942      volatile unsigned long _argvec[3+12];                       \
2943      volatile unsigned long _res;                                \
2944      /* _argvec[0] holds current r2 across the call */           \
2945      _argvec[1]   = (unsigned long)_orig.r2;                     \
2946      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2947      _argvec[2+1] = (unsigned long)arg1;                         \
2948      _argvec[2+2] = (unsigned long)arg2;                         \
2949      _argvec[2+3] = (unsigned long)arg3;                         \
2950      _argvec[2+4] = (unsigned long)arg4;                         \
2951      _argvec[2+5] = (unsigned long)arg5;                         \
2952      _argvec[2+6] = (unsigned long)arg6;                         \
2953      _argvec[2+7] = (unsigned long)arg7;                         \
2954      _argvec[2+8] = (unsigned long)arg8;                         \
2955      _argvec[2+9] = (unsigned long)arg9;                         \
2956      _argvec[2+10] = (unsigned long)arg10;                       \
2957      _argvec[2+11] = (unsigned long)arg11;                       \
2958      _argvec[2+12] = (unsigned long)arg12;                       \
2959      __asm__ volatile(                                           \
2960         "mr 11,%1\n\t"                                           \
2961         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2962         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2963         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2964         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
2965         /* arg12 */                                              \
2966         "lwz 3,48(11)\n\t"                                       \
2967         "stw 3,68(1)\n\t"                                        \
2968         /* arg11 */                                              \
2969         "lwz 3,44(11)\n\t"                                       \
2970         "stw 3,64(1)\n\t"                                        \
2971         /* arg10 */                                              \
2972         "lwz 3,40(11)\n\t"                                       \
2973         "stw 3,60(1)\n\t"                                        \
2974         /* arg9 */                                               \
2975         "lwz 3,36(11)\n\t"                                       \
2976         "stw 3,56(1)\n\t"                                        \
2977         /* args1-8 */                                            \
2978         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2979         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2980         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2981         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2982         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2983         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2984         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2985         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2986         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2987         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2988         "mr 11,%1\n\t"                                           \
2989         "mr %0,3\n\t"                                            \
2990         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2991         VG_CONTRACT_FRAME_BY(72)                                 \
2992         VG_CONTRACT_FRAME_BY(512)                                \
2993         : /*out*/   "=r" (_res)                                  \
2994         : /*in*/    "r" (&_argvec[2])                            \
2995         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2996      );                                                          \
2997      lval = (__typeof__(lval)) _res;                             \
2998   } while (0)
2999
3000#endif /* PLAT_ppc32_aix5 */
3001
3002/* ------------------------ ppc64-aix5 ------------------------- */
3003
3004#if defined(PLAT_ppc64_aix5)
3005
3006/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
3007
3008/* These regs are trashed by the hidden call. */
3009#define __CALLER_SAVED_REGS                                       \
3010   "lr", "ctr", "xer",                                            \
3011   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
3012   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
3013   "r11", "r12", "r13"
3014
3015/* Expand the stack frame, copying enough info that unwinding
3016   still works.  Trashes r3. */
3017
3018#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
3019         "addi 1,1,-" #_n_fr "\n\t"                               \
3020         "ld   3," #_n_fr "(1)\n\t"                               \
3021         "std  3,0(1)\n\t"
3022
3023#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
3024         "addi 1,1," #_n_fr "\n\t"
3025
3026/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
3027   long) == 8. */
3028
3029#define CALL_FN_W_v(lval, orig)                                   \
3030   do {                                                           \
3031      volatile OrigFn        _orig = (orig);                      \
3032      volatile unsigned long _argvec[3+0];                        \
3033      volatile unsigned long _res;                                \
3034      /* _argvec[0] holds current r2 across the call */           \
3035      _argvec[1] = (unsigned long)_orig.r2;                       \
3036      _argvec[2] = (unsigned long)_orig.nraddr;                   \
3037      __asm__ volatile(                                           \
3038         "mr 11,%1\n\t"                                           \
3039         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3040         "std  2,-16(11)\n\t" /* save tocptr */                   \
3041         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3042         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3043         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3044         "mr 11,%1\n\t"                                           \
3045         "mr %0,3\n\t"                                            \
3046         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3047         VG_CONTRACT_FRAME_BY(512)                                \
3048         : /*out*/   "=r" (_res)                                  \
3049         : /*in*/    "r" (&_argvec[2])                            \
3050         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3051      );                                                          \
3052      lval = (__typeof__(lval)) _res;                             \
3053   } while (0)
3054
3055#define CALL_FN_W_W(lval, orig, arg1)                             \
3056   do {                                                           \
3057      volatile OrigFn        _orig = (orig);                      \
3058      volatile unsigned long _argvec[3+1];                        \
3059      volatile unsigned long _res;                                \
3060      /* _argvec[0] holds current r2 across the call */           \
3061      _argvec[1]   = (unsigned long)_orig.r2;                     \
3062      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3063      _argvec[2+1] = (unsigned long)arg1;                         \
3064      __asm__ volatile(                                           \
3065         "mr 11,%1\n\t"                                           \
3066         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3067         "std  2,-16(11)\n\t" /* save tocptr */                   \
3068         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3069         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3070         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3071         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3072         "mr 11,%1\n\t"                                           \
3073         "mr %0,3\n\t"                                            \
3074         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3075         VG_CONTRACT_FRAME_BY(512)                                \
3076         : /*out*/   "=r" (_res)                                  \
3077         : /*in*/    "r" (&_argvec[2])                            \
3078         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3079      );                                                          \
3080      lval = (__typeof__(lval)) _res;                             \
3081   } while (0)
3082
3083#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3084   do {                                                           \
3085      volatile OrigFn        _orig = (orig);                      \
3086      volatile unsigned long _argvec[3+2];                        \
3087      volatile unsigned long _res;                                \
3088      /* _argvec[0] holds current r2 across the call */           \
3089      _argvec[1]   = (unsigned long)_orig.r2;                     \
3090      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3091      _argvec[2+1] = (unsigned long)arg1;                         \
3092      _argvec[2+2] = (unsigned long)arg2;                         \
3093      __asm__ volatile(                                           \
3094         "mr 11,%1\n\t"                                           \
3095         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3096         "std  2,-16(11)\n\t" /* save tocptr */                   \
3097         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3098         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3099         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3100         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3101         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3102         "mr 11,%1\n\t"                                           \
3103         "mr %0,3\n\t"                                            \
3104         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3105         VG_CONTRACT_FRAME_BY(512)                                \
3106         : /*out*/   "=r" (_res)                                  \
3107         : /*in*/    "r" (&_argvec[2])                            \
3108         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3109      );                                                          \
3110      lval = (__typeof__(lval)) _res;                             \
3111   } while (0)
3112
3113#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3114   do {                                                           \
3115      volatile OrigFn        _orig = (orig);                      \
3116      volatile unsigned long _argvec[3+3];                        \
3117      volatile unsigned long _res;                                \
3118      /* _argvec[0] holds current r2 across the call */           \
3119      _argvec[1]   = (unsigned long)_orig.r2;                     \
3120      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3121      _argvec[2+1] = (unsigned long)arg1;                         \
3122      _argvec[2+2] = (unsigned long)arg2;                         \
3123      _argvec[2+3] = (unsigned long)arg3;                         \
3124      __asm__ volatile(                                           \
3125         "mr 11,%1\n\t"                                           \
3126         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3127         "std  2,-16(11)\n\t" /* save tocptr */                   \
3128         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3129         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3130         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3131         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3132         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3133         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3134         "mr 11,%1\n\t"                                           \
3135         "mr %0,3\n\t"                                            \
3136         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3137         VG_CONTRACT_FRAME_BY(512)                                \
3138         : /*out*/   "=r" (_res)                                  \
3139         : /*in*/    "r" (&_argvec[2])                            \
3140         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3141      );                                                          \
3142      lval = (__typeof__(lval)) _res;                             \
3143   } while (0)
3144
3145#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3146   do {                                                           \
3147      volatile OrigFn        _orig = (orig);                      \
3148      volatile unsigned long _argvec[3+4];                        \
3149      volatile unsigned long _res;                                \
3150      /* _argvec[0] holds current r2 across the call */           \
3151      _argvec[1]   = (unsigned long)_orig.r2;                     \
3152      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3153      _argvec[2+1] = (unsigned long)arg1;                         \
3154      _argvec[2+2] = (unsigned long)arg2;                         \
3155      _argvec[2+3] = (unsigned long)arg3;                         \
3156      _argvec[2+4] = (unsigned long)arg4;                         \
3157      __asm__ volatile(                                           \
3158         "mr 11,%1\n\t"                                           \
3159         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3160         "std  2,-16(11)\n\t" /* save tocptr */                   \
3161         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3162         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3163         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3164         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3165         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3166         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3167         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3168         "mr 11,%1\n\t"                                           \
3169         "mr %0,3\n\t"                                            \
3170         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3171         VG_CONTRACT_FRAME_BY(512)                                \
3172         : /*out*/   "=r" (_res)                                  \
3173         : /*in*/    "r" (&_argvec[2])                            \
3174         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3175      );                                                          \
3176      lval = (__typeof__(lval)) _res;                             \
3177   } while (0)
3178
3179#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3180   do {                                                           \
3181      volatile OrigFn        _orig = (orig);                      \
3182      volatile unsigned long _argvec[3+5];                        \
3183      volatile unsigned long _res;                                \
3184      /* _argvec[0] holds current r2 across the call */           \
3185      _argvec[1]   = (unsigned long)_orig.r2;                     \
3186      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3187      _argvec[2+1] = (unsigned long)arg1;                         \
3188      _argvec[2+2] = (unsigned long)arg2;                         \
3189      _argvec[2+3] = (unsigned long)arg3;                         \
3190      _argvec[2+4] = (unsigned long)arg4;                         \
3191      _argvec[2+5] = (unsigned long)arg5;                         \
3192      __asm__ volatile(                                           \
3193         "mr 11,%1\n\t"                                           \
3194         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3195         "std  2,-16(11)\n\t" /* save tocptr */                   \
3196         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3197         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3198         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3199         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3200         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3201         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3202         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3203         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3204         "mr 11,%1\n\t"                                           \
3205         "mr %0,3\n\t"                                            \
3206         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3207         VG_CONTRACT_FRAME_BY(512)                                \
3208         : /*out*/   "=r" (_res)                                  \
3209         : /*in*/    "r" (&_argvec[2])                            \
3210         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3211      );                                                          \
3212      lval = (__typeof__(lval)) _res;                             \
3213   } while (0)
3214
3215#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3216   do {                                                           \
3217      volatile OrigFn        _orig = (orig);                      \
3218      volatile unsigned long _argvec[3+6];                        \
3219      volatile unsigned long _res;                                \
3220      /* _argvec[0] holds current r2 across the call */           \
3221      _argvec[1]   = (unsigned long)_orig.r2;                     \
3222      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3223      _argvec[2+1] = (unsigned long)arg1;                         \
3224      _argvec[2+2] = (unsigned long)arg2;                         \
3225      _argvec[2+3] = (unsigned long)arg3;                         \
3226      _argvec[2+4] = (unsigned long)arg4;                         \
3227      _argvec[2+5] = (unsigned long)arg5;                         \
3228      _argvec[2+6] = (unsigned long)arg6;                         \
3229      __asm__ volatile(                                           \
3230         "mr 11,%1\n\t"                                           \
3231         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3232         "std  2,-16(11)\n\t" /* save tocptr */                   \
3233         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3234         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3235         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3236         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3237         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3238         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3239         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3240         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3241         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3242         "mr 11,%1\n\t"                                           \
3243         "mr %0,3\n\t"                                            \
3244         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3245         VG_CONTRACT_FRAME_BY(512)                                \
3246         : /*out*/   "=r" (_res)                                  \
3247         : /*in*/    "r" (&_argvec[2])                            \
3248         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3249      );                                                          \
3250      lval = (__typeof__(lval)) _res;                             \
3251   } while (0)
3252
3253#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3254                                 arg7)                            \
3255   do {                                                           \
3256      volatile OrigFn        _orig = (orig);                      \
3257      volatile unsigned long _argvec[3+7];                        \
3258      volatile unsigned long _res;                                \
3259      /* _argvec[0] holds current r2 across the call */           \
3260      _argvec[1]   = (unsigned long)_orig.r2;                     \
3261      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3262      _argvec[2+1] = (unsigned long)arg1;                         \
3263      _argvec[2+2] = (unsigned long)arg2;                         \
3264      _argvec[2+3] = (unsigned long)arg3;                         \
3265      _argvec[2+4] = (unsigned long)arg4;                         \
3266      _argvec[2+5] = (unsigned long)arg5;                         \
3267      _argvec[2+6] = (unsigned long)arg6;                         \
3268      _argvec[2+7] = (unsigned long)arg7;                         \
3269      __asm__ volatile(                                           \
3270         "mr 11,%1\n\t"                                           \
3271         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3272         "std  2,-16(11)\n\t" /* save tocptr */                   \
3273         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3274         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3275         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3276         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3277         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3278         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3279         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3280         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3281         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3282         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3283         "mr 11,%1\n\t"                                           \
3284         "mr %0,3\n\t"                                            \
3285         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3286         VG_CONTRACT_FRAME_BY(512)                                \
3287         : /*out*/   "=r" (_res)                                  \
3288         : /*in*/    "r" (&_argvec[2])                            \
3289         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3290      );                                                          \
3291      lval = (__typeof__(lval)) _res;                             \
3292   } while (0)
3293
3294#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3295                                 arg7,arg8)                       \
3296   do {                                                           \
3297      volatile OrigFn        _orig = (orig);                      \
3298      volatile unsigned long _argvec[3+8];                        \
3299      volatile unsigned long _res;                                \
3300      /* _argvec[0] holds current r2 across the call */           \
3301      _argvec[1]   = (unsigned long)_orig.r2;                     \
3302      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3303      _argvec[2+1] = (unsigned long)arg1;                         \
3304      _argvec[2+2] = (unsigned long)arg2;                         \
3305      _argvec[2+3] = (unsigned long)arg3;                         \
3306      _argvec[2+4] = (unsigned long)arg4;                         \
3307      _argvec[2+5] = (unsigned long)arg5;                         \
3308      _argvec[2+6] = (unsigned long)arg6;                         \
3309      _argvec[2+7] = (unsigned long)arg7;                         \
3310      _argvec[2+8] = (unsigned long)arg8;                         \
3311      __asm__ volatile(                                           \
3312         "mr 11,%1\n\t"                                           \
3313         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3314         "std  2,-16(11)\n\t" /* save tocptr */                   \
3315         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3316         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3317         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3318         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3319         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3320         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3321         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3322         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3323         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3324         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3325         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3326         "mr 11,%1\n\t"                                           \
3327         "mr %0,3\n\t"                                            \
3328         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3329         VG_CONTRACT_FRAME_BY(512)                                \
3330         : /*out*/   "=r" (_res)                                  \
3331         : /*in*/    "r" (&_argvec[2])                            \
3332         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3333      );                                                          \
3334      lval = (__typeof__(lval)) _res;                             \
3335   } while (0)
3336
3337#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3338                                 arg7,arg8,arg9)                  \
3339   do {                                                           \
3340      volatile OrigFn        _orig = (orig);                      \
3341      volatile unsigned long _argvec[3+9];                        \
3342      volatile unsigned long _res;                                \
3343      /* _argvec[0] holds current r2 across the call */           \
3344      _argvec[1]   = (unsigned long)_orig.r2;                     \
3345      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3346      _argvec[2+1] = (unsigned long)arg1;                         \
3347      _argvec[2+2] = (unsigned long)arg2;                         \
3348      _argvec[2+3] = (unsigned long)arg3;                         \
3349      _argvec[2+4] = (unsigned long)arg4;                         \
3350      _argvec[2+5] = (unsigned long)arg5;                         \
3351      _argvec[2+6] = (unsigned long)arg6;                         \
3352      _argvec[2+7] = (unsigned long)arg7;                         \
3353      _argvec[2+8] = (unsigned long)arg8;                         \
3354      _argvec[2+9] = (unsigned long)arg9;                         \
3355      __asm__ volatile(                                           \
3356         "mr 11,%1\n\t"                                           \
3357         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3358         "std  2,-16(11)\n\t" /* save tocptr */                   \
3359         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3360         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3361         /* arg9 */                                               \
3362         "ld  3,72(11)\n\t"                                       \
3363         "std 3,112(1)\n\t"                                       \
3364         /* args1-8 */                                            \
3365         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3366         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3367         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3368         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3369         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3370         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3371         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3372         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3373         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3374         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3375         "mr 11,%1\n\t"                                           \
3376         "mr %0,3\n\t"                                            \
3377         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3378         VG_CONTRACT_FRAME_BY(128)                                \
3379         VG_CONTRACT_FRAME_BY(512)                                \
3380         : /*out*/   "=r" (_res)                                  \
3381         : /*in*/    "r" (&_argvec[2])                            \
3382         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3383      );                                                          \
3384      lval = (__typeof__(lval)) _res;                             \
3385   } while (0)
3386
3387#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3388                                  arg7,arg8,arg9,arg10)           \
3389   do {                                                           \
3390      volatile OrigFn        _orig = (orig);                      \
3391      volatile unsigned long _argvec[3+10];                       \
3392      volatile unsigned long _res;                                \
3393      /* _argvec[0] holds current r2 across the call */           \
3394      _argvec[1]   = (unsigned long)_orig.r2;                     \
3395      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3396      _argvec[2+1] = (unsigned long)arg1;                         \
3397      _argvec[2+2] = (unsigned long)arg2;                         \
3398      _argvec[2+3] = (unsigned long)arg3;                         \
3399      _argvec[2+4] = (unsigned long)arg4;                         \
3400      _argvec[2+5] = (unsigned long)arg5;                         \
3401      _argvec[2+6] = (unsigned long)arg6;                         \
3402      _argvec[2+7] = (unsigned long)arg7;                         \
3403      _argvec[2+8] = (unsigned long)arg8;                         \
3404      _argvec[2+9] = (unsigned long)arg9;                         \
3405      _argvec[2+10] = (unsigned long)arg10;                       \
3406      __asm__ volatile(                                           \
3407         "mr 11,%1\n\t"                                           \
3408         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3409         "std  2,-16(11)\n\t" /* save tocptr */                   \
3410         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3411         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3412         /* arg10 */                                              \
3413         "ld  3,80(11)\n\t"                                       \
3414         "std 3,120(1)\n\t"                                       \
3415         /* arg9 */                                               \
3416         "ld  3,72(11)\n\t"                                       \
3417         "std 3,112(1)\n\t"                                       \
3418         /* args1-8 */                                            \
3419         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3420         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3421         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3422         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3423         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3424         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3425         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3426         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3427         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3428         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3429         "mr 11,%1\n\t"                                           \
3430         "mr %0,3\n\t"                                            \
3431         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3432         VG_CONTRACT_FRAME_BY(128)                                \
3433         VG_CONTRACT_FRAME_BY(512)                                \
3434         : /*out*/   "=r" (_res)                                  \
3435         : /*in*/    "r" (&_argvec[2])                            \
3436         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3437      );                                                          \
3438      lval = (__typeof__(lval)) _res;                             \
3439   } while (0)
3440
3441#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3442                                  arg7,arg8,arg9,arg10,arg11)     \
3443   do {                                                           \
3444      volatile OrigFn        _orig = (orig);                      \
3445      volatile unsigned long _argvec[3+11];                       \
3446      volatile unsigned long _res;                                \
3447      /* _argvec[0] holds current r2 across the call */           \
3448      _argvec[1]   = (unsigned long)_orig.r2;                     \
3449      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3450      _argvec[2+1] = (unsigned long)arg1;                         \
3451      _argvec[2+2] = (unsigned long)arg2;                         \
3452      _argvec[2+3] = (unsigned long)arg3;                         \
3453      _argvec[2+4] = (unsigned long)arg4;                         \
3454      _argvec[2+5] = (unsigned long)arg5;                         \
3455      _argvec[2+6] = (unsigned long)arg6;                         \
3456      _argvec[2+7] = (unsigned long)arg7;                         \
3457      _argvec[2+8] = (unsigned long)arg8;                         \
3458      _argvec[2+9] = (unsigned long)arg9;                         \
3459      _argvec[2+10] = (unsigned long)arg10;                       \
3460      _argvec[2+11] = (unsigned long)arg11;                       \
3461      __asm__ volatile(                                           \
3462         "mr 11,%1\n\t"                                           \
3463         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3464         "std  2,-16(11)\n\t" /* save tocptr */                   \
3465         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3466         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
3467         /* arg11 */                                              \
3468         "ld  3,88(11)\n\t"                                       \
3469         "std 3,128(1)\n\t"                                       \
3470         /* arg10 */                                              \
3471         "ld  3,80(11)\n\t"                                       \
3472         "std 3,120(1)\n\t"                                       \
3473         /* arg9 */                                               \
3474         "ld  3,72(11)\n\t"                                       \
3475         "std 3,112(1)\n\t"                                       \
3476         /* args1-8 */                                            \
3477         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3478         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3479         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3480         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3481         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3482         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3483         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3484         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3485         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3486         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3487         "mr 11,%1\n\t"                                           \
3488         "mr %0,3\n\t"                                            \
3489         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3490         VG_CONTRACT_FRAME_BY(144)                                \
3491         VG_CONTRACT_FRAME_BY(512)                                \
3492         : /*out*/   "=r" (_res)                                  \
3493         : /*in*/    "r" (&_argvec[2])                            \
3494         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3495      );                                                          \
3496      lval = (__typeof__(lval)) _res;                             \
3497   } while (0)
3498
3499#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3500                                arg7,arg8,arg9,arg10,arg11,arg12) \
3501   do {                                                           \
3502      volatile OrigFn        _orig = (orig);                      \
3503      volatile unsigned long _argvec[3+12];                       \
3504      volatile unsigned long _res;                                \
3505      /* _argvec[0] holds current r2 across the call */           \
3506      _argvec[1]   = (unsigned long)_orig.r2;                     \
3507      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3508      _argvec[2+1] = (unsigned long)arg1;                         \
3509      _argvec[2+2] = (unsigned long)arg2;                         \
3510      _argvec[2+3] = (unsigned long)arg3;                         \
3511      _argvec[2+4] = (unsigned long)arg4;                         \
3512      _argvec[2+5] = (unsigned long)arg5;                         \
3513      _argvec[2+6] = (unsigned long)arg6;                         \
3514      _argvec[2+7] = (unsigned long)arg7;                         \
3515      _argvec[2+8] = (unsigned long)arg8;                         \
3516      _argvec[2+9] = (unsigned long)arg9;                         \
3517      _argvec[2+10] = (unsigned long)arg10;                       \
3518      _argvec[2+11] = (unsigned long)arg11;                       \
3519      _argvec[2+12] = (unsigned long)arg12;                       \
3520      __asm__ volatile(                                           \
3521         "mr 11,%1\n\t"                                           \
3522         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3523         "std  2,-16(11)\n\t" /* save tocptr */                   \
3524         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3525         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
3526         /* arg12 */                                              \
3527         "ld  3,96(11)\n\t"                                       \
3528         "std 3,136(1)\n\t"                                       \
3529         /* arg11 */                                              \
3530         "ld  3,88(11)\n\t"                                       \
3531         "std 3,128(1)\n\t"                                       \
3532         /* arg10 */                                              \
3533         "ld  3,80(11)\n\t"                                       \
3534         "std 3,120(1)\n\t"                                       \
3535         /* arg9 */                                               \
3536         "ld  3,72(11)\n\t"                                       \
3537         "std 3,112(1)\n\t"                                       \
3538         /* args1-8 */                                            \
3539         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3540         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3541         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3542         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3543         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3544         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3545         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3546         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3547         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3548         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3549         "mr 11,%1\n\t"                                           \
3550         "mr %0,3\n\t"                                            \
3551         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3552         VG_CONTRACT_FRAME_BY(144)                                \
3553         VG_CONTRACT_FRAME_BY(512)                                \
3554         : /*out*/   "=r" (_res)                                  \
3555         : /*in*/    "r" (&_argvec[2])                            \
3556         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3557      );                                                          \
3558      lval = (__typeof__(lval)) _res;                             \
3559   } while (0)
3560
3561#endif /* PLAT_ppc64_aix5 */
3562
3563
3564/* ------------------------------------------------------------------ */
3565/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
3566/*                                                                    */
3567/* ------------------------------------------------------------------ */
3568
3569/* Some request codes.  There are many more of these, but most are not
3570   exposed to end-user view.  These are the public ones, all of the
3571   form 0x1000 + small_number.
3572
3573   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
3574   ones start at 0x2000.
3575*/
3576
3577/* These macros are used by tools -- they must be public, but don't
3578   embed them into other programs. */
3579#define VG_USERREQ_TOOL_BASE(a,b) \
3580   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
3581#define VG_IS_TOOL_USERREQ(a, b, v) \
3582   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
3583
3584/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
3585   This enum comprises an ABI exported by Valgrind to programs
3586   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
3587   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
3588typedef
3589   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
3590          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
3591
3592          /* These allow any function to be called from the simulated
3593             CPU but run on the real CPU.  Nb: the first arg passed to
3594             the function is always the ThreadId of the running
3595             thread!  So CLIENT_CALL0 actually requires a 1 arg
3596             function, etc. */
3597          VG_USERREQ__CLIENT_CALL0 = 0x1101,
3598          VG_USERREQ__CLIENT_CALL1 = 0x1102,
3599          VG_USERREQ__CLIENT_CALL2 = 0x1103,
3600          VG_USERREQ__CLIENT_CALL3 = 0x1104,
3601
3602          /* Can be useful in regression testing suites -- eg. can
3603             send Valgrind's output to /dev/null and still count
3604             errors. */
3605          VG_USERREQ__COUNT_ERRORS = 0x1201,
3606
3607          /* These are useful and can be interpreted by any tool that
3608             tracks malloc() et al, by using vg_replace_malloc.c. */
3609          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
3610          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
3611          /* Memory pool support. */
3612          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
3613          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
3614          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
3615          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
3616          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
3617          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
3618          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
3619          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
3620
3621          /* Allow printfs to valgrind log. */
3622          VG_USERREQ__PRINTF           = 0x1401,
3623          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
3624
3625          /* Stack support. */
3626          VG_USERREQ__STACK_REGISTER   = 0x1501,
3627          VG_USERREQ__STACK_DEREGISTER = 0x1502,
3628          VG_USERREQ__STACK_CHANGE     = 0x1503,
3629
3630          /* Wine support */
3631          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601
3632   } Vg_ClientRequest;
3633
3634#if !defined(__GNUC__)
3635#  define __extension__ /* */
3636#endif
3637
3638/* Returns the number of Valgrinds this code is running under.  That
3639   is, 0 if running natively, 1 if running under Valgrind, 2 if
3640   running under Valgrind which is running under another Valgrind,
3641   etc. */
3642#define RUNNING_ON_VALGRIND  __extension__                        \
3643   ({unsigned int _qzz_res;                                       \
3644    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
3645                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
3646                               0, 0, 0, 0, 0);                    \
3647    _qzz_res;                                                     \
3648   })
3649
3650
3651/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
3652   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
3653   since it provides a way to make sure valgrind will retranslate the
3654   invalidated area.  Returns no value. */
3655#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
3656   {unsigned int _qzz_res;                                        \
3657    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3658                               VG_USERREQ__DISCARD_TRANSLATIONS,  \
3659                               _qzz_addr, _qzz_len, 0, 0, 0);     \
3660   }
3661
3662
3663/* These requests are for getting Valgrind itself to print something.
3664   Possibly with a backtrace.  This is a really ugly hack. */
3665
3666#if defined(NVALGRIND)
3667
3668#  define VALGRIND_PRINTF(...)
3669#  define VALGRIND_PRINTF_BACKTRACE(...)
3670
3671#else /* NVALGRIND */
3672
3673/* Modern GCC will optimize the static routine out if unused,
3674   and unused attribute will shut down warnings about it.  */
3675static int VALGRIND_PRINTF(const char *format, ...)
3676   __attribute__((format(__printf__, 1, 2), __unused__));
3677static int
3678VALGRIND_PRINTF(const char *format, ...)
3679{
3680   unsigned long _qzz_res;
3681   va_list vargs;
3682   va_start(vargs, format);
3683   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
3684                              (unsigned long)format, (unsigned long)vargs,
3685                              0, 0, 0);
3686   va_end(vargs);
3687   return (int)_qzz_res;
3688}
3689
3690static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3691   __attribute__((format(__printf__, 1, 2), __unused__));
3692static int
3693VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3694{
3695   unsigned long _qzz_res;
3696   va_list vargs;
3697   va_start(vargs, format);
3698   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
3699                              (unsigned long)format, (unsigned long)vargs,
3700                              0, 0, 0);
3701   va_end(vargs);
3702   return (int)_qzz_res;
3703}
3704
3705#endif /* NVALGRIND */
3706
3707
3708/* These requests allow control to move from the simulated CPU to the
3709   real CPU, calling an arbitary function.
3710
3711   Note that the current ThreadId is inserted as the first argument.
3712   So this call:
3713
3714     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
3715
3716   requires f to have this signature:
3717
3718     Word f(Word tid, Word arg1, Word arg2)
3719
3720   where "Word" is a word-sized type.
3721
3722   Note that these client requests are not entirely reliable.  For example,
3723   if you call a function with them that subsequently calls printf(),
3724   there's a high chance Valgrind will crash.  Generally, your prospects of
3725   these working are made higher if the called function does not refer to
3726   any global variables, and does not refer to any libc or other functions
3727   (printf et al).  Any kind of entanglement with libc or dynamic linking is
3728   likely to have a bad outcome, for tricky reasons which we've grappled
3729   with a lot in the past.
3730*/
3731#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
3732   __extension__                                                  \
3733   ({unsigned long _qyy_res;                                      \
3734    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
3735                               VG_USERREQ__CLIENT_CALL0,          \
3736                               _qyy_fn,                           \
3737                               0, 0, 0, 0);                       \
3738    _qyy_res;                                                     \
3739   })
3740
3741#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
3742   __extension__                                                  \
3743   ({unsigned long _qyy_res;                                      \
3744    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
3745                               VG_USERREQ__CLIENT_CALL1,          \
3746                               _qyy_fn,                           \
3747                               _qyy_arg1, 0, 0, 0);               \
3748    _qyy_res;                                                     \
3749   })
3750
3751#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
3752   __extension__                                                  \
3753   ({unsigned long _qyy_res;                                      \
3754    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
3755                               VG_USERREQ__CLIENT_CALL2,          \
3756                               _qyy_fn,                           \
3757                               _qyy_arg1, _qyy_arg2, 0, 0);       \
3758    _qyy_res;                                                     \
3759   })
3760
3761#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
3762   __extension__                                                  \
3763   ({unsigned long _qyy_res;                                      \
3764    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
3765                               VG_USERREQ__CLIENT_CALL3,          \
3766                               _qyy_fn,                           \
3767                               _qyy_arg1, _qyy_arg2,              \
3768                               _qyy_arg3, 0);                     \
3769    _qyy_res;                                                     \
3770   })
3771
3772
3773/* Counts the number of errors that have been recorded by a tool.  Nb:
3774   the tool must record the errors with VG_(maybe_record_error)() or
3775   VG_(unique_error)() for them to be counted. */
3776#define VALGRIND_COUNT_ERRORS                                     \
3777   __extension__                                                  \
3778   ({unsigned int _qyy_res;                                       \
3779    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
3780                               VG_USERREQ__COUNT_ERRORS,          \
3781                               0, 0, 0, 0, 0);                    \
3782    _qyy_res;                                                     \
3783   })
3784
3785/* Mark a block of memory as having been allocated by a malloc()-like
3786   function.  `addr' is the start of the usable block (ie. after any
3787   redzone) `rzB' is redzone size if the allocator can apply redzones;
3788   use '0' if not.  Adding redzones makes it more likely Valgrind will spot
3789   block overruns.  `is_zeroed' indicates if the memory is zeroed, as it is
3790   for calloc().  Put it immediately after the point where a block is
3791   allocated.
3792
3793   If you're using Memcheck: If you're allocating memory via superblocks,
3794   and then handing out small chunks of each superblock, if you don't have
3795   redzones on your small blocks, it's worth marking the superblock with
3796   VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
3797   detected.  But if you can put redzones on, it's probably better to not do
3798   this, so that messages for small overruns are described in terms of the
3799   small block rather than the superblock (but if you have a big overrun
3800   that skips over a redzone, you could miss an error this way).  See
3801   memcheck/tests/custom_alloc.c for an example.
3802
3803   WARNING: if your allocator uses malloc() or 'new' to allocate
3804   superblocks, rather than mmap() or brk(), this will not work properly --
3805   you'll likely get assertion failures during leak detection.  This is
3806   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.
3807
3808   Nb: block must be freed via a free()-like function specified
3809   with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
3810#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
3811   {unsigned int _qzz_res;                                        \
3812    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3813                               VG_USERREQ__MALLOCLIKE_BLOCK,      \
3814                               addr, sizeB, rzB, is_zeroed, 0);   \
3815   }
3816
3817/* Mark a block of memory as having been freed by a free()-like function.
3818   `rzB' is redzone size;  it must match that given to
3819   VALGRIND_MALLOCLIKE_BLOCK.  Memory not freed will be detected by the leak
3820   checker.  Put it immediately after the point where the block is freed. */
3821#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
3822   {unsigned int _qzz_res;                                        \
3823    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3824                               VG_USERREQ__FREELIKE_BLOCK,        \
3825                               addr, rzB, 0, 0, 0);               \
3826   }
3827
3828/* Create a memory pool. */
3829#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
3830   {unsigned int _qzz_res;                                        \
3831    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3832                               VG_USERREQ__CREATE_MEMPOOL,        \
3833                               pool, rzB, is_zeroed, 0, 0);       \
3834   }
3835
3836/* Destroy a memory pool. */
3837#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
3838   {unsigned int _qzz_res;                                        \
3839    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3840                               VG_USERREQ__DESTROY_MEMPOOL,       \
3841                               pool, 0, 0, 0, 0);                 \
3842   }
3843
3844/* Associate a piece of memory with a memory pool. */
3845#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
3846   {unsigned int _qzz_res;                                        \
3847    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3848                               VG_USERREQ__MEMPOOL_ALLOC,         \
3849                               pool, addr, size, 0, 0);           \
3850   }
3851
3852/* Disassociate a piece of memory from a memory pool. */
3853#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
3854   {unsigned int _qzz_res;                                        \
3855    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3856                               VG_USERREQ__MEMPOOL_FREE,          \
3857                               pool, addr, 0, 0, 0);              \
3858   }
3859
3860/* Disassociate any pieces outside a particular range. */
3861#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
3862   {unsigned int _qzz_res;                                        \
3863    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3864                               VG_USERREQ__MEMPOOL_TRIM,          \
3865                               pool, addr, size, 0, 0);           \
3866   }
3867
3868/* Resize and/or move a piece associated with a memory pool. */
3869#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
3870   {unsigned int _qzz_res;                                        \
3871    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3872                               VG_USERREQ__MOVE_MEMPOOL,          \
3873                               poolA, poolB, 0, 0, 0);            \
3874   }
3875
3876/* Resize and/or move a piece associated with a memory pool. */
3877#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
3878   {unsigned int _qzz_res;                                        \
3879    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3880                               VG_USERREQ__MEMPOOL_CHANGE,        \
3881                               pool, addrA, addrB, size, 0);      \
3882   }
3883
3884/* Return 1 if a mempool exists, else 0. */
3885#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
3886   __extension__                                                  \
3887   ({unsigned int _qzz_res;                                       \
3888    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3889                               VG_USERREQ__MEMPOOL_EXISTS,        \
3890                               pool, 0, 0, 0, 0);                 \
3891    _qzz_res;                                                     \
3892   })
3893
3894/* Mark a piece of memory as being a stack. Returns a stack id. */
3895#define VALGRIND_STACK_REGISTER(start, end)                       \
3896   __extension__                                                  \
3897   ({unsigned int _qzz_res;                                       \
3898    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3899                               VG_USERREQ__STACK_REGISTER,        \
3900                               start, end, 0, 0, 0);              \
3901    _qzz_res;                                                     \
3902   })
3903
3904/* Unmark the piece of memory associated with a stack id as being a
3905   stack. */
3906#define VALGRIND_STACK_DEREGISTER(id)                             \
3907   {unsigned int _qzz_res;                                        \
3908    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3909                               VG_USERREQ__STACK_DEREGISTER,      \
3910                               id, 0, 0, 0, 0);                   \
3911   }
3912
3913/* Change the start and end address of the stack id. */
3914#define VALGRIND_STACK_CHANGE(id, start, end)                     \
3915   {unsigned int _qzz_res;                                        \
3916    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3917                               VG_USERREQ__STACK_CHANGE,          \
3918                               id, start, end, 0, 0);             \
3919   }
3920
3921/* Load PDB debug info for Wine PE image_map. */
3922#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)   \
3923   {unsigned int _qzz_res;                                        \
3924    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3925                               VG_USERREQ__LOAD_PDB_DEBUGINFO,    \
3926                               fd, ptr, total_size, delta, 0);    \
3927   }
3928
3929
3930#undef PLAT_x86_linux
3931#undef PLAT_amd64_linux
3932#undef PLAT_ppc32_linux
3933#undef PLAT_ppc64_linux
3934#undef PLAT_ppc32_aix5
3935#undef PLAT_ppc64_aix5
3936
3937#endif   /* __VALGRIND_H */
3938