valgrind.h revision 32f8d8c0dcb3a7c3ff14aa9892ea2410eba3207c
1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj/* -*- c -*-
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
3e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
4e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Notice that the following BSD-style license applies to this one
57fd15d674f18757167305947732057099e175914njn   file (valgrind.h) only.  The rest of Valgrind is licensed under the
67fd15d674f18757167305947732057099e175914njn   terms of the GNU General Public License, version 2, unless
77fd15d674f18757167305947732057099e175914njn   otherwise indicated.  See the COPYING file in the source
87fd15d674f18757167305947732057099e175914njn   distribution for details.
9e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
11e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
12b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   This file is part of Valgrind, a dynamic binary instrumentation
13b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   framework.
14de4a1d01951937632098a6cda45859afa587a06fsewardj
159f207460d70d38c46c9e81996a3dcdf90961c6dbnjn   Copyright (C) 2000-2009 Julian Seward.  All rights reserved.
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Redistribution and use in source and binary forms, with or without
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   modification, are permitted provided that the following conditions
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   are met:
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   1. Redistributions of source code must retain the above copyright
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      notice, this list of conditions and the following disclaimer.
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   2. The origin of this software must not be misrepresented; you must
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      not claim that you wrote the original software.  If you use this
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      software in a product, an acknowledgment in the product
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      documentation would be appreciated but is not required.
28de4a1d01951937632098a6cda45859afa587a06fsewardj
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   3. Altered source versions must be plainly marked as such, and must
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      not be misrepresented as being the original software.
31de4a1d01951937632098a6cda45859afa587a06fsewardj
32e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   4. The name of the author may not be used to endorse or promote
33e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      products derived from this software without specific prior written
34e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      permission.
35de4a1d01951937632098a6cda45859afa587a06fsewardj
36e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47de4a1d01951937632098a6cda45859afa587a06fsewardj
48e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
49e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
50e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Notice that the above BSD-style license applies to this one file
51e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   (valgrind.h) only.  The entire rest of Valgrind is licensed under
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   the terms of the GNU General Public License, version 2.  See the
53e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   COPYING file in the source distribution for details.
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   ----------------------------------------------------------------
56de4a1d01951937632098a6cda45859afa587a06fsewardj*/
57de4a1d01951937632098a6cda45859afa587a06fsewardj
58de4a1d01951937632098a6cda45859afa587a06fsewardj
5930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* This file is for inclusion into client (your!) code.
6030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   You can use these macros to manipulate and query Valgrind's
6230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   execution inside your own programs.
6330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   The resulting executables will still run without Valgrind, just a
6530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   little bit more slowly than they otherwise would, but otherwise
6630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   unchanged.  When not running on valgrind, each client request
670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   consumes very few (eg. 7) instructions, so the resulting performance
6830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   loss is negligible unless you plan to execute client requests
6930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   millions of times per second.  Nevertheless, if that is still a
7030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   problem, you can compile with the NVALGRIND symbol defined (gcc
7130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn   -DNVALGRIND) so that client requests are not even compiled in.  */
7230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
73de4a1d01951937632098a6cda45859afa587a06fsewardj#ifndef __VALGRIND_H
74de4a1d01951937632098a6cda45859afa587a06fsewardj#define __VALGRIND_H
75de4a1d01951937632098a6cda45859afa587a06fsewardj
7639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#include <stdarg.h>
7739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
783dd0a912e48a4884ee51ab3afe41856c165185canjn/* Nb: this file might be included in a file compiled with -ansi.  So
793dd0a912e48a4884ee51ab3afe41856c165185canjn   we can't use C++ style "//" comments nor the "asm" keyword (instead
803dd0a912e48a4884ee51ab3afe41856c165185canjn   use "__asm__"). */
813dd0a912e48a4884ee51ab3afe41856c165185canjn
82f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Derive some tags indicating what the target platform is.  Note
830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   that in this file we're using the compiler's CPP symbols for
840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   identifying architectures, which are different to the ones we use
850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   within the rest of Valgrind.  Note, __powerpc__ is active for both
860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
87f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   latter (on Linux, that is). */
88f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
89f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
90f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
91f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
92f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_aix5
93f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_aix5
94f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
95f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
96f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(_AIX) && defined(__64BIT__)
97f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_ppc64_aix5 1
98f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(_AIX) && !defined(__64BIT__)
99f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_ppc32_aix5 1
100f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__i386__)
101f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_x86_darwin 1
102f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__x86_64__)
103f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_amd64_darwin 1
104f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__i386__)
105f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_x86_linux 1
106f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__x86_64__)
107f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_amd64_linux 1
108f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__powerpc__) && !defined(__powerpc64__)
109f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc32_linux 1
110f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__powerpc__) && defined(__powerpc64__)
111f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc64_linux 1
112f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else
113f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* If we're not compiling for our target platform, don't generate
1140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   any inline asms.  */
1150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  if !defined(NVALGRIND)
1160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#    define NVALGRIND 1
1170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  endif
118b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#endif
119b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
12130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
1220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
1230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* in here of use to end-users -- skip to the next section.           */
12430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
125de4a1d01951937632098a6cda45859afa587a06fsewardj
1260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
12726aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
12826aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn/* Define NVALGRIND to completely remove the Valgrind magic sequence
1290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   from the compiled code (analogous to NDEBUG's effects on
1300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   assert()) */
1310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
1320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
1339af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
1340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {                                                              \
1350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      (_zzq_rlval) = (_zzq_default);                              \
13626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn   }
13726aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
1380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#else  /* ! NVALGRIND */
1390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* The following defines the magic code sequences which the JITter
1410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   spots and handles magically.  Don't look too closely at them as
1420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   they will rot your brain.
143de4a1d01951937632098a6cda45859afa587a06fsewardj
1440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The assembly code sequences for all architectures is in this one
1450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   file.  This is because this file must be stand-alone, and we don't
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   want to have multiple files.
1470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   value gets put in the return slot, so that everything works when
1500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   this is executed not under Valgrind.  Args are passed in a memory
1510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   block, and so there's no intrinsic limit to the number that could
1529af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj   be passed, but it's currently five.
153e90c6836fd430124799e52896c99ea27b1c88541nethercote
1545426544c9c3fc835ead99fae9e2054625110ef3enethercote   The macro args are:
1555426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_rlval    result lvalue
1565426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_default  default value (result returned when running on real CPU)
1575426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_request  request code
1589af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      _zzq_arg1..5  request params
1595426544c9c3fc835ead99fae9e2054625110ef3enethercote
1600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The other two macros are used to support function wrapping, and are
161d68ac3e974d25f88492774f6baa491999afde9f9sewardj   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
162d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest's NRADDR pseudo-register and whatever other information is
163d68ac3e974d25f88492774f6baa491999afde9f9sewardj   needed to safely run the call original from the wrapper: on
164d68ac3e974d25f88492774f6baa491999afde9f9sewardj   ppc64-linux, the R2 value at the divert point is also needed.  This
165d68ac3e974d25f88492774f6baa491999afde9f9sewardj   information is abstracted into a user-visible type, OrigFn.
166d68ac3e974d25f88492774f6baa491999afde9f9sewardj
167d68ac3e974d25f88492774f6baa491999afde9f9sewardj   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
168d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest, but guarantees that the branch instruction will not be
169d68ac3e974d25f88492774f6baa491999afde9f9sewardj   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
170d68ac3e974d25f88492774f6baa491999afde9f9sewardj   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
171d68ac3e974d25f88492774f6baa491999afde9f9sewardj   complete inline asm, since it needs to be combined with more magic
172d68ac3e974d25f88492774f6baa491999afde9f9sewardj   inline asm stuff to be useful.
173e90c6836fd430124799e52896c99ea27b1c88541nethercote*/
174de4a1d01951937632098a6cda45859afa587a06fsewardj
175f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
1760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
177f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
178c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
179c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
180c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
181c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
182c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
183c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
184c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
1850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
1860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
1871a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "roll $29, %%edi ; roll $19, %%edi\n\t"
1880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
1900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
1919af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
1929af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  { volatile unsigned int _zzq_args[6];                           \
1930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned int _zzq_result;                            \
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
1950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
1960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
1999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
2000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EDX = client_request ( %EAX ) */         \
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ebx,%%ebx"                          \
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
2070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
208c616819253fcf211745060b2be26076174b1df19njn  }
2090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
210c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
211c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
212c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned int __addr;                                 \
2130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EAX = guest_NRADDR */                    \
2150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ecx,%%ecx"                          \
2160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
220c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
221ca0518df66f8c3375a860f1a55a51f18e2a16c44njn  }
2220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_EAX                                 \
2240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%EAX */                     \
2260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%edx,%%edx\n\t"
227f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
2280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
229f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
2300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
231f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
232c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
233c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
234c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
235c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned long long int nraddr; /* where's the code? */
236c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
237c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
238c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
2390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
2411a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
2420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
2440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
2459af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
2469af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  { volatile unsigned long long int _zzq_args[6];                 \
2470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned long long int _zzq_result;                  \
2480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
2490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
2500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
2539af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
2540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RDX = client_request ( %RAX ) */         \
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rbx,%%rbx"                          \
2570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
2610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
26285665ca6fa29dd64754dabe50eb98f25896e752acerion  }
2630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
264c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
265c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
266c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned long long int __addr;                       \
2670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RAX = guest_NRADDR */                    \
2690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rcx,%%rcx"                          \
2700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
274c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
2752c48c7b0a453d32375a4df17e153011b797ef28csewardj  }
2760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_RAX                                 \
2780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%RAX */                     \
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rdx,%%rdx\n\t"
281f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
2820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
283f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
2840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
285f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
286d68ac3e974d25f88492774f6baa491999afde9f9sewardj
287d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
288d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
289c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
290d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
291d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
292d68ac3e974d25f88492774f6baa491999afde9f9sewardj
2930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
2951a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
2960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
2980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
2999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
3000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
3019af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  {          unsigned int  _zzq_args[6];                          \
3021c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int  _zzq_result;                           \
3031c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int* _zzq_ptr;                              \
3040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
3050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
3060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
3070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
3080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
3099af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
3100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
3111c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
3121c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
3131c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
3140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = client_request ( %R4 ) */           \
3151c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 1,1,1\n\t"                               \
3161c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"     /*result*/                     \
3171c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (_zzq_result)                         \
3181c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
3191c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3", "r4");               \
3200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
3210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
3220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
323d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
324d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
3251c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    unsigned int __addr;                                          \
3260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = guest_NRADDR */                     \
3281c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 2,2,2\n\t"                               \
3291c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"                                    \
3301c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (__addr)                              \
3310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
3321c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3"                       \
3330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
334d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
3350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
3360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
3380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
3390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* branch-and-link-to-noredir *%R11 */       \
3400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "or 3,3,3\n\t"
341f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
3420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
343f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
3440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
345f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
346d68ac3e974d25f88492774f6baa491999afde9f9sewardj
347d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
348d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
349d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int nraddr; /* where's the code? */
350d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int r2;  /* what tocptr do we need? */
351d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
352d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
353d68ac3e974d25f88492774f6baa491999afde9f9sewardj
3541a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3551a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
3561a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
3571a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
3590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
3609af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
3610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
3629af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  {          unsigned long long int  _zzq_args[6];                \
3631a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    register unsigned long long int  _zzq_result __asm__("r3");   \
3641a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    register unsigned long long int* _zzq_ptr __asm__("r4");      \
3651a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
3661a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
3671a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
3681a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
3691a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
3709af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
3710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
3721a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3731a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = client_request ( %R4 ) */           \
3741a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 1,1,1"                                   \
3751a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "=r" (_zzq_result)                         \
3760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "0" (_zzq_default), "r" (_zzq_ptr)         \
3771a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "cc", "memory");                           \
3781a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_rlval = _zzq_result;                                     \
3791a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  }
3801a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
381d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
382d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
383d68ac3e974d25f88492774f6baa491999afde9f9sewardj    register unsigned long long int __addr __asm__("r3");         \
3841a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3851a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = guest_NRADDR */                     \
3861a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 2,2,2"                                   \
3871a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "=r" (__addr)                              \
3881a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     :                                            \
3891a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "cc", "memory"                             \
3901a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                    );                                            \
391d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
392d68ac3e974d25f88492774f6baa491999afde9f9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
393d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
394d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     "or 4,4,4"                                   \
395d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     : "=r" (__addr)                              \
396d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     :                                            \
397d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     : "cc", "memory"                             \
398d68ac3e974d25f88492774f6baa491999afde9f9sewardj                    );                                            \
399d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->r2 = __addr;                                       \
4000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
4011a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
4021a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
4031a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4041a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* branch-and-link-to-noredir *%R11 */       \
4051a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 3,3,3\n\t"
4061a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
408f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
409f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-aix5 ------------------------- */
410f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
411f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_aix5)
412f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
413f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjtypedef
414f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   struct {
415f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned int nraddr; /* where's the code? */
416f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned int r2;  /* what tocptr do we need? */
417f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   }
418f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   OrigFn;
419f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
420f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
421f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
422f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
423f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
424f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
425f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
426f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
427f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                                  \
428f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  {          unsigned int  _zzq_args[7];                          \
429f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int  _zzq_result;                           \
430f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int* _zzq_ptr;                              \
431f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
432f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
433f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
434f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
435f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
436f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
437f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
438f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_ptr = _zzq_args;                                         \
439f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile("mr 4,%1\n\t"                                \
440f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "lwz 3, 24(4)\n\t"                           \
441f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
442f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = client_request ( %R4 ) */           \
443f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 1,1,1\n\t"                               \
444f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
445f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (_zzq_result)                         \
446f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "b" (_zzq_ptr)                             \
447f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "r4", "cc", "memory");               \
448f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_rlval = _zzq_result;                                     \
449f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
450f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
451f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
452f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
453f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int __addr;                                 \
454f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
455f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR */                     \
456f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 2,2,2\n\t"                               \
457f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
458f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
459f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
460f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
461f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
462f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->nraddr = __addr;                                   \
463f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
465f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 4,4,4\n\t"                               \
466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
467f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
469f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
471f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->r2 = __addr;                                       \
472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
473f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
474f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
475f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* branch-and-link-to-noredir *%R11 */       \
477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 3,3,3\n\t"
478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_aix5 */
480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-aix5 ------------------------- */
482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_aix5)
484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjtypedef
486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   struct {
487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned long long int nraddr; /* where's the code? */
488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned long long int r2;  /* what tocptr do we need? */
489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   }
490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   OrigFn;
491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                                  \
500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  {          unsigned long long int  _zzq_args[7];                \
501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int  _zzq_result;                 \
502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int* _zzq_ptr;                    \
503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_ptr = _zzq_args;                                         \
511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile("mr 4,%1\n\t"                                \
512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "ld 3, 48(4)\n\t"                            \
513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = client_request ( %R4 ) */           \
515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 1,1,1\n\t"                               \
516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (_zzq_result)                         \
518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "b" (_zzq_ptr)                             \
519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "r4", "cc", "memory");               \
520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_rlval = _zzq_result;                                     \
521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int __addr;                       \
526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR */                     \
528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 2,2,2\n\t"                               \
529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->nraddr = __addr;                                   \
535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 4,4,4\n\t"                               \
538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
540f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
541f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
542f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
543f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->r2 = __addr;                                       \
544f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
545f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* branch-and-link-to-noredir *%R11 */       \
549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 3,3,3\n\t"
550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_aix5 */
55285665ca6fa29dd64754dabe50eb98f25896e752acerion
553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Insert assembly code for other platforms here... */
55426aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
55537091fb739760631f436043c47de612cf9fd2dd1sewardj#endif /* NVALGRIND */
5562e93c50dc50235189661b70e3f27a4098d5cccccsewardj
55769d9c4625034b60c08e04cc246fcf8093d23fde5nethercote
55830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
5600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ugly.  It's the least-worst tradeoff I can think of.               */
5610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
5620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* This section defines magic (a.k.a appalling-hack) macros for doing
5640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   guaranteed-no-redirection macros, so as to get from function
5650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   wrappers to the functions they are wrapping.  The whole point is to
5660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   construct standard call sequences, but to do the call itself with a
5670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   special no-redirect call pseudo-instruction that the JIT
5680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   understands and handles specially.  This section is long and
5690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   repetitious, and I can't see a way to make it shorter.
5700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The naming scheme is as follows:
5720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
5740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   'W' stands for "word" and 'v' for "void".  Hence there are
5760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
5770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   and for each, the possibility of returning a word-typed result, or
5780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   no result.
5790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj*/
5800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Use these to write the name of your wrapper.  NOTE: duplicates
5820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
5830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5845f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn/* Use an extra level of macroisation so as to ensure the soname/fnname
5855f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   args are fully macro-expanded before pasting them together. */
5865f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
5875f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
5880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
5895f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   VG_CONCAT4(_vgwZU_,soname,_,fnname)
5900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
5925f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   VG_CONCAT4(_vgwZZ_,soname,_,fnname)
5930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
594d68ac3e974d25f88492774f6baa491999afde9f9sewardj/* Use this macro from within a wrapper function to collect the
595d68ac3e974d25f88492774f6baa491999afde9f9sewardj   context (address and possibly other info) of the original function.
596d68ac3e974d25f88492774f6baa491999afde9f9sewardj   Once you have that you can then use it in one of the CALL_FN_
597d68ac3e974d25f88492774f6baa491999afde9f9sewardj   macros.  The type of the argument _lval is OrigFn. */
598d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
5990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Derivatives of the main macros below, for calling functions
6010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   returning void. */
6020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_v(fnptr)                                        \
6040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_v(_junk,fnptr); } while (0)
6060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_W(fnptr, arg1)                                  \
6080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
6100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
6120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
6140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6155ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
6165ce4b150ce5d32c9af07a24717081ea34568388asewardj   do { volatile unsigned long _junk;                             \
6175ce4b150ce5d32c9af07a24717081ea34568388asewardj        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
6185ce4b150ce5d32c9af07a24717081ea34568388asewardj
6192b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
6202b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6212b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
6222b5f0a90334a2271791c110548a842fadb5ffc65njn
6232b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
6242b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6252b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
6262b5f0a90334a2271791c110548a842fadb5ffc65njn
6272b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
6282b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6292b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
6302b5f0a90334a2271791c110548a842fadb5ffc65njn
6312b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
6322b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6332b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
6342b5f0a90334a2271791c110548a842fadb5ffc65njn
635f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
6360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
637f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
6380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call.  No need to mention eax
6400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   as gcc can already see that, plus causes gcc to bomb. */
6410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
6420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
6440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 4. */
6450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
64666226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_v(lval, orig)                                   \
6470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
64866226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
6490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
6500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
65166226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
6520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
6530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
6540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
6550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
6560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
6570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
6580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
6590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
6600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
6610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
66266226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
6630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
66466226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
6650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
6660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
66766226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
6680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
6690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
6700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
6710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
6720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
6730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $4, %%esp\n"                                       \
6740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
6750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
6760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
6770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
6780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
6790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
6800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
68166226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
6820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
68366226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
6840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
6850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
68666226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
6870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
6880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
6890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
6900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
6910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
6920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
6930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
6940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $8, %%esp\n"                                       \
6950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
6969e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*in*/    "a" (&_argvec[0])                            \
6979e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
6989e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      );                                                          \
6999e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      lval = (__typeof__(lval)) _res;                             \
7009e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   } while (0)
7019e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
7029e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
7039e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   do {                                                           \
7049e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile OrigFn        _orig = (orig);                      \
7059e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _argvec[4];                          \
7069e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _res;                                \
7079e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7089e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[1] = (unsigned long)(arg1);                         \
7099e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[2] = (unsigned long)(arg2);                         \
7109e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[3] = (unsigned long)(arg3);                         \
7119e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      __asm__ volatile(                                           \
7129e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 12(%%eax)\n\t"                                    \
7139e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 8(%%eax)\n\t"                                     \
7149e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 4(%%eax)\n\t"                                     \
7159e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7169e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7179e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "addl $12, %%esp\n"                                      \
7189e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*out*/   "=a" (_res)                                  \
7190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
72566226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
7260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
72766226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[5];                          \
7290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
73066226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
7330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
7340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
7350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
7370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
7380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
7390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $16, %%esp\n"                                      \
7430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
75066226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
7510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
75266226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[6];                          \
7540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
75566226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
7580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
7590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
7600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
7610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
7630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
7640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
7650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
7660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $20, %%esp\n"                                      \
7700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
77766226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
7780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
77966226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[7];                          \
7810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
78266226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
7850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
7860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
7870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
7880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
7890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
7910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
7920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
7930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
7940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
7950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $24, %%esp\n"                                      \
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
80666226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
80766226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7)                            \
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
80966226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[8];                          \
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
81266226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
8190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
8200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
8220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
8230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $28, %%esp\n"                                      \
8310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
83866226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
83966226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7,arg8)                       \
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
84166226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[9];                          \
8430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
84466226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
8510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
8520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $32, %%esp\n"                                      \
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
87245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
87345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                 arg7,arg8,arg9)                  \
87445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
87545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
87645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[10];                         \
87745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
87845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
87945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
88045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
88145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
88245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
88345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
88445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
88545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
88645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
88745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
88845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
88945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
89045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
89145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
89245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
89345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
89445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
89545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
89645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
89745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
89845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
89945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
90045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "addl $36, %%esp\n"                                      \
90145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
90245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
90345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
90445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
90545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
90645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
90745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
90845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
90945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                  arg7,arg8,arg9,arg10)           \
91045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
91145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
91245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[11];                         \
91345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
91445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
91545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
91645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
91745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
91845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
91945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
92045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
92145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
92245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
92345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
92445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[10] = (unsigned long)(arg10);                       \
92545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
92645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 40(%%eax)\n\t"                                    \
92745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
92845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
92945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
93045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
93145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
93245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
93345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
93445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
93545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
93645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
93745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
93845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "addl $40, %%esp\n"                                      \
93945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
94045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
94145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
94245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
94345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
94445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
94545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
9465ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
9475ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg6,arg7,arg8,arg9,arg10,      \
9485ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg11)                          \
9495ce4b150ce5d32c9af07a24717081ea34568388asewardj   do {                                                           \
9505ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile OrigFn        _orig = (orig);                      \
9515ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _argvec[12];                         \
9525ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _res;                                \
9535ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9545ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[1] = (unsigned long)(arg1);                         \
9555ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[2] = (unsigned long)(arg2);                         \
9565ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[3] = (unsigned long)(arg3);                         \
9575ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[4] = (unsigned long)(arg4);                         \
9585ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[5] = (unsigned long)(arg5);                         \
9595ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[6] = (unsigned long)(arg6);                         \
9605ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[7] = (unsigned long)(arg7);                         \
9615ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[8] = (unsigned long)(arg8);                         \
9625ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[9] = (unsigned long)(arg9);                         \
9635ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[10] = (unsigned long)(arg10);                       \
9645ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[11] = (unsigned long)(arg11);                       \
9655ce4b150ce5d32c9af07a24717081ea34568388asewardj      __asm__ volatile(                                           \
9665ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 44(%%eax)\n\t"                                    \
9675ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 40(%%eax)\n\t"                                    \
9685ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 36(%%eax)\n\t"                                    \
9695ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 32(%%eax)\n\t"                                    \
9705ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 28(%%eax)\n\t"                                    \
9715ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 24(%%eax)\n\t"                                    \
9725ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 20(%%eax)\n\t"                                    \
9735ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 16(%%eax)\n\t"                                    \
9745ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 12(%%eax)\n\t"                                    \
9755ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 8(%%eax)\n\t"                                     \
9765ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 4(%%eax)\n\t"                                     \
9775ce4b150ce5d32c9af07a24717081ea34568388asewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9785ce4b150ce5d32c9af07a24717081ea34568388asewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9795ce4b150ce5d32c9af07a24717081ea34568388asewardj         "addl $44, %%esp\n"                                      \
9805ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*out*/   "=a" (_res)                                  \
9815ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*in*/    "a" (&_argvec[0])                            \
9825ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9835ce4b150ce5d32c9af07a24717081ea34568388asewardj      );                                                          \
9845ce4b150ce5d32c9af07a24717081ea34568388asewardj      lval = (__typeof__(lval)) _res;                             \
9855ce4b150ce5d32c9af07a24717081ea34568388asewardj   } while (0)
9865ce4b150ce5d32c9af07a24717081ea34568388asewardj
98766226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
98866226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
98966226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg11,arg12)                    \
9900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
99166226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[13];                         \
9930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
99466226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
9980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
9990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
10000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
10010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
10020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
10030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[9] = (unsigned long)(arg9);                         \
10040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[10] = (unsigned long)(arg10);                       \
10050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[11] = (unsigned long)(arg11);                       \
10060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[12] = (unsigned long)(arg12);                       \
10070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 48(%%eax)\n\t"                                    \
10090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 44(%%eax)\n\t"                                    \
10100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 40(%%eax)\n\t"                                    \
10110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 36(%%eax)\n\t"                                    \
10120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
10130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
10140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
10150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
10160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
10170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
10180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
10190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
10200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $48, %%esp\n"                                      \
10230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
10260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1030f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
10310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1032f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
10330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1034f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
10350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
10370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
10390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
10400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                            "rdi", "r8", "r9", "r10", "r11"
10410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
10430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 8. */
10440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1045a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1046a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   macros.  In order not to trash the stack redzone, we need to drop
1047a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   %rsp by 128 before the hidden call, and restore afterwards.  The
1048a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   nastyness is that it is only by luck that the stack still appears
1049a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   to be unwindable during the hidden call - since then the behaviour
1050a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   of any routine using this macro does not match what the CFI data
1051a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   says.  Sigh.
1052a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1053a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Why is this important?  Imagine that a wrapper has a stack
1054a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   allocated local, and passes to the hidden call, a pointer to it.
1055a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Because gcc does not know about the hidden call, it may allocate
1056a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   that local in the redzone.  Unfortunately the hidden call may then
1057a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   trash it before it comes to use it.  So we must step clear of the
1058a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   redzone, for the duration of the hidden call, to make it safe.
1059a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1060a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Probably the same problem afflicts the other redzone-style ABIs too
1061a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
1062a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   self describing (none of this CFI nonsense) so at least messing
1063a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   with the stack pointer doesn't give a danger of non-unwindable
1064a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   stack. */
1065a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1066c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_v(lval, orig)                                   \
10670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1068c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
10690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
10700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1071c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1073a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
10740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
10750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1076a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
10770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
10800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1084c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
10850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1086c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
10870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
10880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1089c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1092a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
10930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
10940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
10950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1096a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
10970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1104c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
11050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1106c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
11070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
11080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1109c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
11110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
11120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1113a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
11140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
11150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
11160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
11170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1118a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
11190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1126a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1127a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1128a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1129a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[4];                          \
1130a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1131a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1132a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1133a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1134a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1135a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1136a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1137a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1138a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1139a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1140a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1141a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1142a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1143a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1144a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1145a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1146a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1147a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1148a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1149a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1150a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1151a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1152a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1153a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[5];                          \
1154a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1155a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1156a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1157a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1158a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1159a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1160a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1161a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1162a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1163a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1164a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1165a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1166a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1167a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1168a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1169a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1170a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1171a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1172a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1173a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1174a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1175a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1176a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1177a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1178a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1179a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[6];                          \
1180a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1181a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1182a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1183a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1184a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1185a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1186a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1187a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1188a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1189a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1190a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1191a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1192a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1193a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1194a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1195a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1196a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1197a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1198a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1199a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1200a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1201a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1202a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1203a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1204a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1205a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1206a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1207a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[7];                          \
1208a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1209a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1210a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1211a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1212a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1213a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1214a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1215a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1216a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1217a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1218a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1219a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1220a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1221a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1222a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1223a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1224a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1225a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1226a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1227a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1228a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1229a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1230a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1231a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1232a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1233a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1234a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1235a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7)                            \
1236a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1237a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1238a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[8];                          \
1239a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1240a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1241a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1242a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1243a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1244a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1245a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1246a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1247a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1248a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1249a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1250a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1251a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1252a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1253a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1254a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1255a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1256a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1257a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1258a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1259a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $8, %%rsp\n"                                       \
1260a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1261a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1262a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1263a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1264a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1265a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1266a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1267a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1268a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1269a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8)                       \
1270a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1271a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1272a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[9];                          \
1273a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1274a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1275a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1276a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1277a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1278a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1279a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1280a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1281a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1282a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1283a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1284a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1285a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1286a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1287a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1288a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1289a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1290a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1291a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1292a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1293a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1294a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1295a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $16, %%rsp\n"                                      \
1296a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1297a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1298a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1299a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1300a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1301a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1302a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1303a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1304a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1305a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8,arg9)                  \
1306a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1307a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1308a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[10];                         \
1309a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1310a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1311a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1312a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1313a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1314a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1315a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1316a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1317a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1318a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1319a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1320a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1321a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1322a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1323a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1324a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1325a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1326a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1327a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1328a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1329a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1330a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1331a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1332a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1333a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $24, %%rsp\n"                                      \
1334a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1335a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1336a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1337a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1338a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1339a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1340a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1341a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1342a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1343a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10)           \
1344a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1345a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1346a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[11];                         \
1347a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1348a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1349a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1350a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1351a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1352a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1353a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1354a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1355a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1356a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1357a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1358a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1359a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1360a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1361a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1362a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1363a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1364a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1365a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1366a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1367a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1368a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1369a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1370a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1371a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1372a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1373a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $32, %%rsp\n"                                      \
1374a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1375a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1376a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1377a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1378a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1379a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1380a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1381a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1382a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1383a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
1384a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1385a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1386a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[12];                         \
1387a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1388a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1389a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1390a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1391a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1392a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1393a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1394a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1395a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1396a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1397a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1398a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1399a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1400a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1401a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1402a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1403a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1404a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1405a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1406a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1407a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1408a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1409a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1410a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1411a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1412a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1413a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1414a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1415a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $40, %%rsp\n"                                      \
1416a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1417a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1418a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1419a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1420a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1421a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1422a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1423a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1424a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1425a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
1426a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1427a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1428a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[13];                         \
1429a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1430a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1431a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1432a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1433a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1434a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1435a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1436a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1437a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1438a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1439a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1440a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1441a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1442a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[12] = (unsigned long)(arg12);                       \
1443a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1444a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1445a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 96(%%rax)\n\t"                                    \
1446a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1447a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1448a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1449a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1450a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1451a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1452a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1453a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1454a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1455a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1456a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1457a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1458a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1459a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $48, %%rsp\n"                                      \
1460a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1461a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1462a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1463a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1464a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1465a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1466a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1467a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1468f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
14690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
14710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
14730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1474ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* This is useful for finding out about the on-stack stuff:
1475ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1476ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f9  ( int,int,int,int,int,int,int,int,int );
1477ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1478ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1479ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1480ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1481ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g9 ( void ) {
1482ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f9(11,22,33,44,55,66,77,88,99);
1483ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1484ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g10 ( void ) {
1485ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f10(11,22,33,44,55,66,77,88,99,110);
1486ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1487ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g11 ( void ) {
1488ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f11(11,22,33,44,55,66,77,88,99,110,121);
1489ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1490ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g12 ( void ) {
1491ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1492ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1493ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj*/
1494ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
14950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
14960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
14970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
1498ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define __CALLER_SAVED_REGS                                       \
1499ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "lr", "ctr", "xer",                                            \
1500ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1501ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1502ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r11", "r12", "r13"
15030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1504ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* These CALL_FN_ macros assume that on ppc32-linux,
1505ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   sizeof(unsigned long) == 4. */
15060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
150738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_v(lval, orig)                                   \
15080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1509d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
15100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
15110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1512d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
15130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
15140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
15150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
15160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
15170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
15180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
15190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
15200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
15210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
15220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
15230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
15240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
152538de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
15260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
152738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
15280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
15290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
153038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
15310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
15320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
15330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
15340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
15350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
15360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
15370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
15380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
15390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
15400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
15410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
15420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
15430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
15440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
154538de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
15460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
154738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
15480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
15490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
155038de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
15510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
15520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)arg2;                           \
15530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
15540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
15550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
15560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 4,8(11)\n\t"                                        \
15570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
15580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
15590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
15600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
15610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
15620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
15630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
15640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
15650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
15660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1567ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1568ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1569ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1570ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[4];                          \
1571ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1572ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1573ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1574ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1575ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1576ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1577ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1578ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1579ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1580ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1581ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1582ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1583ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1584ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1585ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1586ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1587ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1588ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1589ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1590ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1591ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1592ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1593ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1594ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[5];                          \
1595ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1596ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1597ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1598ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1599ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1600ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1601ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1602ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1603ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1604ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1605ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1606ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1607ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1608ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1609ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1610ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1611ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1612ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1613ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1614ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1615ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1616ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1617ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1618ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1619ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1620ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[6];                          \
1621ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1622ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1623ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1624ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1625ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1626ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1627ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1628ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1629ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1630ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1631ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1632ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1633ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1634ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1635ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1636ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1637ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1638ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1639ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1640ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1641ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1642ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1643ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1644ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1645ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1646ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1647ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1648ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[7];                          \
1649ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1650ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1651ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1652ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1653ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1654ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1655ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1656ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1657ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1658ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1659ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1660ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1661ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1662ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1663ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1664ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1665ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1666ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1667ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1668ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1669ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1670ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1671ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1672ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1673ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1674ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1675ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1676ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7)                            \
1677ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1678ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1679ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[8];                          \
1680ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1681ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1682ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1683ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1684ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1685ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1686ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1687ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1688ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1689ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1690ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1691ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1692ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1693ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1694ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1695ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1696ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1697ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1698ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1699ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1700ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1701ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1702ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1703ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1704ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1705ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1706ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1707ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1708ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1709ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8)                       \
1710ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1711ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1712ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[9];                          \
1713ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1714ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1715ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1716ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1717ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1718ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1719ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1720ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1721ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1722ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1723ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1724ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1725ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1726ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1727ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1728ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1729ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1730ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1731ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1732ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1733ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1734ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1735ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1736ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1737ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1738ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1739ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1740ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1741ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1742ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1743ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1744ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8,arg9)                  \
1745ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1746ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1747ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[10];                         \
1748ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1749ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1750ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1751ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1752ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1753ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1754ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1755ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1756ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1757ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1758ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1759ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1760ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1761ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
1762ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1763ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1764ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1765ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1766ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1767ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1768ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1769ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1770ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1771ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1772ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1773ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1774ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1775ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1776ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
1777ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1778ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1779ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1780ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1781ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1782ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1783ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1784ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1785ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1786ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10)           \
1787ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1788ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1789ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[11];                         \
1790ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1791ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1792ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1793ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1794ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1795ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1796ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1797ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1798ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1799ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1800ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1801ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1802ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1803ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1804ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
1805ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1806ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1807ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1808ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1809ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1810ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1811ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1812ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1813ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1814ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1815ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1816ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1817ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1818ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1819ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1820ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1821ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1822ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
1823ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1824ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1825ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1826ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1827ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1828ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1829ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1830ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1831ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1832ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10,arg11)     \
1833ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1834ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1835ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[12];                         \
1836ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1837ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1838ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1839ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1840ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1841ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1842ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1843ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1844ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1845ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1846ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1847ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1848ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
1849ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1850ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1851ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
1852ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
1853ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
1854ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
1855ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1856ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1857ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1858ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1859ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1860ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1861ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1862ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1863ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1864ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1865ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1866ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1867ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1868ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1869ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1870ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1871ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1872ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
1873ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1874ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1875ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1876ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1877ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1878ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1879ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1880ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1881ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1882ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
1883ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1884ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1885ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[13];                         \
1886ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1887ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1888ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1889ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1890ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1891ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1892ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1893ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1894ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1895ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1896ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1897ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1898ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
1899ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[12] = (unsigned long)arg12;                         \
1900ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1901ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1902ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
1903ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg12 */                                              \
1904ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,48(11)\n\t"                                       \
1905ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,20(1)\n\t"                                        \
1906ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
1907ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
1908ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
1909ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1910ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1911ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1912ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1913ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1914ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1915ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1916ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1917ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1918ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1919ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1920ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1921ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1922ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1923ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1924ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1925ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1926ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
1927ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1928ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1929ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1930ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1931ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1932ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1933ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1934ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1935f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
19360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1937f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
19380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1939f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
19409734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
19419734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
19429734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
19439734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These regs are trashed by the hidden call. */
1944cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define __CALLER_SAVED_REGS                                       \
1945cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "lr", "ctr", "xer",                                            \
1946cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1947cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1948cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r11", "r12", "r13"
19499734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
19509734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
19519734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   long) == 8. */
19529734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
1953d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_v(lval, orig)                                   \
19549734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
1955d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
1956d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+0];                        \
19579734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
1958d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
1959d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
1960d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
19619734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
19629734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
1963d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
1964d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
1965d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
19669734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
19679734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
19689734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
1969d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
19709734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
1971d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
19729734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
19739734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
19749734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
19759734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
19769734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
1977d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
19789734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
1979d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
1980d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+1];                        \
19819734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
1982d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
1983d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
1984d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
1985d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
19869734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
19879734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
1988d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
1989d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
1990d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
1991d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
19929734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
19939734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
19949734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
1995d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
19969734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
1997d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
19989734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
19999734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
20009734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
20019734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
20029734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2003d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
20049734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2005d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2006d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+2];                        \
20079734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2008d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2009d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2010d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2011d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2012d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
20139734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
20149734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2015d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2016d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2017d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2018cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2019cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2020cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2021cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2022cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2023cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2024cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2025cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2026cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2027cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2028cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2029cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2030cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2031cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2032cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2033cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2034cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+3];                        \
2035cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2036cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2037cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2038cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2039cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2040cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2041cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2042cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2043cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2044cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2045cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2046cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2047cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2048cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2049d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
20509734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20519734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
20529734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2053d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
20549734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2055d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
20569734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2057cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2058cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2059cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2060cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2061cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2062cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2063cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2064cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+4];                        \
2065cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2066cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2067cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2068cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2069cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2070cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2071cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2072cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2073cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2074cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2075cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2076cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2077cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2078cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2079cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2080cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2081cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2082cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2083cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2084cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2085cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2086cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2087cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2088cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2089cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2090cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2091cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2092cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2093cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2094cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2095cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2096cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+5];                        \
2097cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2098cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2099cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2100cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2101cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2102cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2103cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2104cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2105cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2106cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2107cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2108cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2109cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2110cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2111cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2112cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2113cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2114cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2115cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2116cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2117cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2118cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2119cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2120cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2121cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2122cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2123cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2124cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2125cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2126cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2127cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2128cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2129cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2130cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+6];                        \
2131cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2132cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2133cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2134cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2135cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2136cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2137cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2138cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2139cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2140cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2141cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2142cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2143cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2144cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2145cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2146cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2147cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2148cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2149cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2150cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2151cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2152cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2153cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2154cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2155cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2156cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2157cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2158cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2159cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2160cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2161cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2162cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2163cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2164cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7)                            \
2165cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2166cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2167cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+7];                        \
2168cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2169cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2170cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2171cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2172cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2173cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2174cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2175cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2176cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2177cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2178cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2179cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2180cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2181cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2182cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2183cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2184cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2185cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2186cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2187cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2188cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2189cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2190cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2191cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2192cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2193cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2194cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2195cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2196cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2197cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2198cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2199cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2200cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2201cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2202cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2203cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8)                       \
2204cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2205cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2206cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+8];                        \
2207cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2208cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2209cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2210cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2211cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2212cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2213cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2214cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2215cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2216cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2217cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2218cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2219cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2220cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2221cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2222cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2223cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2224cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2225cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2226cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2227cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2228cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2229cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2230cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2231cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2232cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2233cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2234cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2235cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2236cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2237cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2238cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2239cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2240cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2241cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2242cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2243cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2244cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8,arg9)                  \
2245cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2246cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2247cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+9];                        \
2248cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2249cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2250cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2251cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2252cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2253cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2254cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2255cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2256cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2257cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2258cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2259cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2260cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2261cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2262cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2263cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2264cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2265cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2266cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2267cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2268cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2269cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2270cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2271cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2272cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2273cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2274cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2275cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2276cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2277cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2278cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2279cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2280cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2281cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2282cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2283cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2284cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2285cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2286cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2287cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2288cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2289cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2290cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2291cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2292cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10)           \
2293cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2294cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2295cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+10];                       \
2296cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2297cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2298cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2299cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2300cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2301cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2302cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2303cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2304cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2305cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2306cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2307cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2308cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2309cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2310cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2311cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2312cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2313cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2314cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2315cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2316cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2317cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2318cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2319cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2320cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2321cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2322cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2323cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2324cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2325cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2326cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2327cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2328cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2329cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2330cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2331cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2332cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2333cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2334cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2335cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2336cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2337cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2338cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2339cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2340cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2341cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2342cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2343cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2344cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2345cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2346cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2347cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+11];                       \
2348cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2349cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2350cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2351cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2352cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2353cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2354cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2355cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2356cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2357cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2358cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2359cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2360cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2361cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2362cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2363cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2364cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2365cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2366cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2367cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2368cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2369cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2370cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2371cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2372cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2373cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2374cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2375cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2376cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2377cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2378cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2379cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2380cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2381cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2382cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2383cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2384cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2385cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2386cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2387cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2388cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2389cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2390cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2391cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2392cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2393cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2394cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2395cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2396cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2397cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2398cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2399cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2400cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2401cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2402cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2403cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+12];                       \
2404cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2405cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2406cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2407cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2408cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2409cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2410cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2411cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2412cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2413cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2414cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2415cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2416cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2417cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2418cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2419cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
2420cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2421cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2422cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2423cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2424cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2425cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg12 */                                              \
2426cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,96(11)\n\t"                                       \
2427cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,136(1)\n\t"                                       \
2428cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2429cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2430cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2431cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2432cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2433cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2434cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2435cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2436cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2437cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2438cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2439cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2440cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2441cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2442cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2443cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2444cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2445cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2446cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2447cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2448cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2449cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2450cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2451cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2452cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2453cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2454cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
24559734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
24569734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
24579734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
24589734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2459f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
2460f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2461f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-aix5 ------------------------- */
2462f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2463f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_aix5)
2464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2465f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2467f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These regs are trashed by the hidden call. */
2468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __CALLER_SAVED_REGS                                       \
2469f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "lr", "ctr", "xer",                                            \
2470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2471f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r11", "r12", "r13"
2473f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2474f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Expand the stack frame, copying enough info that unwinding
2475f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   still works.  Trashes r3. */
2476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
2478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1,-" #_n_fr "\n\t"                               \
2479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3," #_n_fr "(1)\n\t"                               \
2480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  3,0(1)\n\t"
2481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
2483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1," #_n_fr "\n\t"
2484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
2486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   long) == 4. */
2487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_v(lval, orig)                                   \
2489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+0];                        \
2492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
2495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
2496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
2515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+1];                        \
2518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2540f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2541f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2542f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
2543f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2544f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2545f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+2];                        \
2546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2552f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2554f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2555f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2556f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2557f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2558f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2560f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2561f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2562f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2563f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2564f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2565f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2566f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2567f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2568f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2569f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2570f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2571f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2572f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2573f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2574f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2575f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+3];                        \
2576f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2577f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2578f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2579f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2580f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2581f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2582f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2583f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2584f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2585f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2586f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2587f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2588f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2589f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2590f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2591f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2592f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2593f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2594f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2595f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2596f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2597f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2598f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2599f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2600f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2601f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2602f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2603f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2604f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2605f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2606f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2607f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+4];                        \
2608f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2609f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2610f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2611f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2612f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2613f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2614f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2615f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2616f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2617f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2618f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2619f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2620f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2621f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2622f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2623f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2624f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2625f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2626f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2627f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2628f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2629f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2630f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2631f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2632f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2633f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2634f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2635f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2636f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2637f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2638f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2639f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2640f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2641f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+5];                        \
2642f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2643f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2644f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2645f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2646f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2647f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2648f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2649f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2650f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2651f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2652f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2653f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2654f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2655f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2656f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2657f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
2658f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2659f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2660f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2661f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2662f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2663f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2664f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2665f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2666f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2667f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2668f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2669f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2670f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2671f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2672f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2673f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2674f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2675f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2676f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2677f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+6];                        \
2678f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2679f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2680f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2681f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2682f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2683f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2684f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2685f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2686f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2687f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2688f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2689f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2690f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2691f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2692f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2693f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2694f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2695f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2696f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2697f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2698f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2699f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2700f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2701f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2702f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2703f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2704f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2705f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2706f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2707f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2708f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2709f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2710f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2711f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2712f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2713f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7)                            \
2714f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2715f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2716f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+7];                        \
2717f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2718f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2719f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2720f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2721f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2722f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2723f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2724f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2725f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2726f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2727f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2728f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2729f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2730f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2731f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2732f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2733f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2734f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2735f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2736f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2737f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2738f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2739f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2740f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2741f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2742f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2743f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2744f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2745f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2746f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2747f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2748f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2749f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2750f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2751f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2752f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2753f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2754f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8)                       \
2755f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2756f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2757f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+8];                        \
2758f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2759f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2760f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2761f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2762f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2763f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2764f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2765f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2766f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2767f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2768f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2769f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2770f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2771f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2772f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2773f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2774f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2775f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2776f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2777f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2778f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2779f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2780f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2781f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2782f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2783f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2784f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2785f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2786f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2787f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2788f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2789f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2790f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2791f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2792f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2793f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2794f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2795f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2796f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2797f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8,arg9)                  \
2798f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2799f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2800f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+9];                        \
2801f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2802f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2803f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2804f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2805f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2806f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2807f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2808f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2809f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2810f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2811f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2812f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2813f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2814f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2815f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2816f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2817f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2818f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2819f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
2820f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
2821f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
2822f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
2823f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
2824f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2825f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2826f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2827f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2828f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2829f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2830f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2831f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2832f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2833f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2834f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2835f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2836f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2837f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(64)                                 \
2838f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2839f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2840f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2841f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2842f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2843f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2844f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2845f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2846f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2847f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10)           \
2848f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2849f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2850f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+10];                       \
2851f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2852f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2853f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2854f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2855f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2856f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2857f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2858f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2859f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2860f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2861f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2862f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2863f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2864f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2865f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2866f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2867f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2868f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2869f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2870f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
2871f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
2872f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
2873f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
2874f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
2875f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
2876f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
2877f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
2878f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2879f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2880f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2881f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2882f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2883f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2884f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2885f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2886f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2887f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2888f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2889f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2890f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2891f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(64)                                 \
2892f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2893f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2894f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2895f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2896f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2897f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2898f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2899f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2900f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2901f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2902f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2903f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2904f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+11];                       \
2905f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2906f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2907f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2908f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2909f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2910f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2911f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2912f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2913f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2914f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2915f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2916f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2917f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2918f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2919f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2920f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2921f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2922f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2923f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2924f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2925f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
2926f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
2927f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,44(11)\n\t"                                       \
2928f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,64(1)\n\t"                                        \
2929f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
2930f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
2931f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
2932f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
2933f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
2934f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
2935f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
2936f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2937f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
2938f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
2939f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
2940f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
2941f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
2942f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
2943f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
2944f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2945f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2946f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2947f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2948f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2949f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(72)                                 \
2950f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2951f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2952f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2953f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2954f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2955f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2956f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2957f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2958f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2959f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2960f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2961f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2962f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+12];                       \
2963f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2964f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2965f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2966f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2967f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2968f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2969f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2970f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2971f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2972f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2973f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2974f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2975f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2976f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2977f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2978f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
2979f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
2980f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2981f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
2982f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
2983f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
2984f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
2985f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg12 */                                              \
2986f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,48(11)\n\t"                                       \
2987f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,68(1)\n\t"                                        \
2988f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
2989f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,44(11)\n\t"                                       \
2990f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,64(1)\n\t"                                        \
2991f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
2992f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
2993f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
2994f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
2995f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
2996f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
2997f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
2998f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
2999f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3000f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3001f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3002f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3003f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3004f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3005f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3006f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3007f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3008f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3009f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3010f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3011f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(72)                                 \
3012f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3013f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3014f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3015f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3016f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3017f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3018f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3019f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3020f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_aix5 */
3021f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3022f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-aix5 ------------------------- */
3023f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3024f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_aix5)
3025f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3026f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
3027f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3028f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These regs are trashed by the hidden call. */
3029f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __CALLER_SAVED_REGS                                       \
3030f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "lr", "ctr", "xer",                                            \
3031f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
3032f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
3033f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r11", "r12", "r13"
3034f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3035f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Expand the stack frame, copying enough info that unwinding
3036f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   still works.  Trashes r3. */
3037f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3038f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
3039f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1,-" #_n_fr "\n\t"                               \
3040f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3," #_n_fr "(1)\n\t"                               \
3041f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  3,0(1)\n\t"
3042f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3043f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
3044f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1," #_n_fr "\n\t"
3045f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3046f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
3047f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   long) == 8. */
3048f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3049f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_v(lval, orig)                                   \
3050f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3051f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3052f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+0];                        \
3053f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3054f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3055f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
3056f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
3057f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3058f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3059f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3060f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3061f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3062f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3063f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3064f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3065f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3066f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3067f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3068f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3069f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3070f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3071f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3072f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3073f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3074f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3075f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
3076f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3077f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3078f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+1];                        \
3079f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3080f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3081f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3082f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3083f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3084f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3085f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3086f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3087f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3088f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3089f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3090f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3091f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3092f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3093f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3094f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3095f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3096f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3097f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3098f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3099f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3100f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3102f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3103f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3104f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3105f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3106f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+2];                        \
3107f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3108f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3109f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3110f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3111f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3112f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3113f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3114f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3116f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3118f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3119f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3120f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3121f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3122f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3123f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3124f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3125f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3126f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3127f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3128f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3129f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3130f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3131f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3132f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3133f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3134f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3135f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3136f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+3];                        \
3137f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3138f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3139f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3140f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3141f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3142f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3143f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3144f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3145f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3146f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3147f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3148f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3149f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3150f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3151f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3152f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3153f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3154f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3155f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3156f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3157f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3158f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3159f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3160f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3161f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3162f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3163f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3164f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3165f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3166f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3167f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3168f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+4];                        \
3169f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3170f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3171f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3172f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3173f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3174f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3175f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3176f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3177f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3178f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3179f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3180f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3181f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3182f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3183f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3184f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3185f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3186f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3187f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3188f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3189f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3190f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3191f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3192f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3193f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3194f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3195f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3196f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3197f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3198f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3199f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3200f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3201f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3202f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+5];                        \
3203f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3204f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3205f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3206f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3207f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3208f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3209f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3210f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3211f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3212f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3213f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3214f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3215f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3216f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3217f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3218f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3219f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3220f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3221f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3222f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3223f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3224f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3225f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3226f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3227f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3228f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3229f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3230f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3231f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3232f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3233f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3234f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3235f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3236f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3237f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3238f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+6];                        \
3239f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3240f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3241f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3242f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3243f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3244f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3245f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3246f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3247f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3248f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3249f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3250f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3251f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3252f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3253f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3254f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3255f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3256f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3257f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3258f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3259f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3260f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3261f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3262f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3263f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3264f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3265f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3266f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3267f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3268f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3269f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3270f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3271f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3272f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3273f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3274f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7)                            \
3275f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3276f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3277f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+7];                        \
3278f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3279f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3280f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3281f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3282f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3283f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3284f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3285f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3286f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3287f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3288f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3289f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3290f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3291f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3292f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3293f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3294f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3295f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3296f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3297f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3298f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3299f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3300f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3301f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3302f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3303f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3304f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3305f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3306f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3307f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3308f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3309f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3310f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3311f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3312f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3313f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3314f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3315f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8)                       \
3316f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3317f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3318f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+8];                        \
3319f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3320f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3321f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3322f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3323f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3324f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3325f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3326f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3327f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3328f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3329f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3330f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3331f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3332f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3333f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3334f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3335f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3336f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3337f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3338f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3339f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3340f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3341f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3342f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3343f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3344f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3345f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3346f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3347f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3348f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3349f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3350f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3351f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3352f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3353f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3354f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3355f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3356f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3357f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3358f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8,arg9)                  \
3359f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3360f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3361f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+9];                        \
3362f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3363f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3364f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3365f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3366f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3367f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3368f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3369f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3370f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3371f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3372f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3373f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3374f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3375f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3376f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3377f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3378f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3379f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3380f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3381f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3382f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3383f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3384f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3385f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3386f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3387f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3388f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3389f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3390f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3391f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3392f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3393f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3394f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3395f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3396f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3397f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3398f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(128)                                \
3399f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3400f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3401f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3402f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3403f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3404f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3405f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3406f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3408f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10)           \
3409f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3410f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3411f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+10];                       \
3412f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3413f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3414f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3415f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3416f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3417f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3418f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3419f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3420f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3421f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3422f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3423f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3424f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3425f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3426f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3427f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3428f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3429f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3430f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3431f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3432f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3433f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
3434f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
3435f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3436f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3437f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3438f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3439f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3440f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3441f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3442f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3443f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3444f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3445f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3446f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3447f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3448f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3449f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3450f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3451f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3452f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(128)                                \
3453f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3454f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3455f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3456f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3457f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3458f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3459f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3460f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3461f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3462f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
3463f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3465f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+11];                       \
3466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3467f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3469f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3471f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3473f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3474f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3475f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
3481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
3487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
3488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,88(11)\n\t"                                       \
3489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,128(1)\n\t"                                       \
3490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
3492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
3493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(144)                                \
3511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
3521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+12];                       \
3524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
3539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
3540f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3541f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3542f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3543f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3544f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3545f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
3546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg12 */                                              \
3547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,96(11)\n\t"                                       \
3548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,136(1)\n\t"                                       \
3549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
3550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,88(11)\n\t"                                       \
3551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,128(1)\n\t"                                       \
3552f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
3554f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
3555f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3556f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3557f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3558f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3560f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3561f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3562f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3563f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3564f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3565f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3566f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3567f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3568f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3569f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3570f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3571f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3572f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(144)                                \
3573f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3574f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3575f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3576f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3577f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3578f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3579f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3580f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3581f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_aix5 */
35829734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
35830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
35840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
35850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
35860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/*                                                                    */
358730d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
358830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
35892e93c50dc50235189661b70e3f27a4098d5cccccsewardj/* Some request codes.  There are many more of these, but most are not
35902e93c50dc50235189661b70e3f27a4098d5cccccsewardj   exposed to end-user view.  These are the public ones, all of the
3591e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   form 0x1000 + small_number.
3592d799418996812817596beaa8b59563e3f3cb2ddanjn
35930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
35940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ones start at 0x2000.
35952e93c50dc50235189661b70e3f27a4098d5cccccsewardj*/
35962e93c50dc50235189661b70e3f27a4098d5cccccsewardj
35970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These macros are used by tools -- they must be public, but don't
35980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   embed them into other programs. */
3599fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_USERREQ_TOOL_BASE(a,b) \
36004c791211835f0e90cbde578187c06e563de3b023njn   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
3601fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_IS_TOOL_USERREQ(a, b, v) \
3602fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
360334042515c1715b3e0c5c0a5e0bd033e9d4858f01sewardj
36045ce4b150ce5d32c9af07a24717081ea34568388asewardj/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
36055ce4b150ce5d32c9af07a24717081ea34568388asewardj   This enum comprises an ABI exported by Valgrind to programs
36065ce4b150ce5d32c9af07a24717081ea34568388asewardj   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
36075ce4b150ce5d32c9af07a24717081ea34568388asewardj   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
3608e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjntypedef
36094c791211835f0e90cbde578187c06e563de3b023njn   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
36104c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
36113e88418f808bf2840646504481d6a5be1df16541njn
36120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These allow any function to be called from the simulated
36130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             CPU but run on the real CPU.  Nb: the first arg passed to
36140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             the function is always the ThreadId of the running
36150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             thread!  So CLIENT_CALL0 actually requires a 1 arg
3616d4795be03ad94334c7517d93d3f5b35a97c7bba0njn             function, etc. */
36174c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL0 = 0x1101,
36184c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL1 = 0x1102,
36194c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL2 = 0x1103,
36204c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL3 = 0x1104,
36213e88418f808bf2840646504481d6a5be1df16541njn
36220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* Can be useful in regression testing suites -- eg. can
36230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             send Valgrind's output to /dev/null and still count
36240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             errors. */
36254c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__COUNT_ERRORS = 0x1201,
362647363aba8fa03b094195bca99fc232ce5f85605dnjn
36270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These are useful and can be interpreted by any tool that
36280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             tracks malloc() et al, by using vg_replace_malloc.c. */
3629d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
3630d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
3631bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          /* Memory pool support. */
3632bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
3633bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
3634bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
3635bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
36362c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
3637c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
3638c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
3639c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
3640d799418996812817596beaa8b59563e3f3cb2ddanjn
364139de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge          /* Allow printfs to valgrind log. */
364230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn          VG_USERREQ__PRINTF           = 0x1401,
36430140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
36440140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
36450140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          /* Stack support. */
36460140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_REGISTER   = 0x1501,
36470140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_DEREGISTER = 0x1502,
3648c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__STACK_CHANGE     = 0x1503,
3649c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
3650c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          /* Wine support */
3651c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601
3652e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   } Vg_ClientRequest;
36532e93c50dc50235189661b70e3f27a4098d5cccccsewardj
36540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if !defined(__GNUC__)
36550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define __extension__ /* */
3656c9b365507e9bd5d500476e3e83f4d30f9c68a351mueller#endif
36572e93c50dc50235189661b70e3f27a4098d5cccccsewardj
36580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Returns the number of Valgrinds this code is running under.  That
36590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   is, 0 if running natively, 1 if running under Valgrind, 2 if
36600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   running under Valgrind which is running under another Valgrind,
36610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   etc. */
36620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define RUNNING_ON_VALGRIND  __extension__                        \
36630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qzz_res;                                       \
36640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
36650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
36669af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0, 0);                    \
36670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qzz_res;                                                     \
3668de4a1d01951937632098a6cda45859afa587a06fsewardj   })
3669de4a1d01951937632098a6cda45859afa587a06fsewardj
3670de4a1d01951937632098a6cda45859afa587a06fsewardj
367118d7513cc08bf982711c8a22b70d56af6aa87b33sewardj/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
367218d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
367318d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   since it provides a way to make sure valgrind will retranslate the
367418d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   invalidated area.  Returns no value. */
36750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
36760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
36770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
36780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__DISCARD_TRANSLATIONS,  \
36799af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qzz_addr, _qzz_len, 0, 0, 0);     \
368018d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   }
368118d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
368226aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
36830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These requests are for getting Valgrind itself to print something.
36840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   Possibly with a backtrace.  This is a really ugly hack. */
36850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
36860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
36870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
36880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define VALGRIND_PRINTF(...)
36890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define VALGRIND_PRINTF_BACKTRACE(...)
369026aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
369126aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn#else /* NVALGRIND */
369239de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
36937eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj/* Modern GCC will optimize the static routine out if unused,
36947eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   and unused attribute will shut down warnings about it.  */
36957eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF(const char *format, ...)
36967eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
36977eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
3698a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF(const char *format, ...)
369939de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
3700c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
370139de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_list vargs;
370239de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_start(vargs, format);
37030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
37049af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              (unsigned long)format, (unsigned long)vargs,
37059af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
370639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_end(vargs);
3707c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
370839de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
370939de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
37107eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
37117eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
37127eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
3713a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF_BACKTRACE(const char *format, ...)
371439de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
3715c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
371639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_list vargs;
371739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_start(vargs, format);
37180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
37199af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              (unsigned long)format, (unsigned long)vargs,
37209af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
372139de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge   va_end(vargs);
3722c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
372339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
372439de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
372539de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#endif /* NVALGRIND */
372618d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
37270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
37283e88418f808bf2840646504481d6a5be1df16541njn/* These requests allow control to move from the simulated CPU to the
37291319b49115bd0763628273b8a3fe08ac30712e31njn   real CPU, calling an arbitary function.
37301319b49115bd0763628273b8a3fe08ac30712e31njn
37311319b49115bd0763628273b8a3fe08ac30712e31njn   Note that the current ThreadId is inserted as the first argument.
37321319b49115bd0763628273b8a3fe08ac30712e31njn   So this call:
37331319b49115bd0763628273b8a3fe08ac30712e31njn
37341319b49115bd0763628273b8a3fe08ac30712e31njn     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
37351319b49115bd0763628273b8a3fe08ac30712e31njn
37361319b49115bd0763628273b8a3fe08ac30712e31njn   requires f to have this signature:
37371319b49115bd0763628273b8a3fe08ac30712e31njn
37381319b49115bd0763628273b8a3fe08ac30712e31njn     Word f(Word tid, Word arg1, Word arg2)
37391319b49115bd0763628273b8a3fe08ac30712e31njn
37401319b49115bd0763628273b8a3fe08ac30712e31njn   where "Word" is a word-sized type.
374145fb4d304f59e4e4cca917d372278eeb75be2c33njn
374245fb4d304f59e4e4cca917d372278eeb75be2c33njn   Note that these client requests are not entirely reliable.  For example,
374345fb4d304f59e4e4cca917d372278eeb75be2c33njn   if you call a function with them that subsequently calls printf(),
374445fb4d304f59e4e4cca917d372278eeb75be2c33njn   there's a high chance Valgrind will crash.  Generally, your prospects of
374545fb4d304f59e4e4cca917d372278eeb75be2c33njn   these working are made higher if the called function does not refer to
374645fb4d304f59e4e4cca917d372278eeb75be2c33njn   any global variables, and does not refer to any libc or other functions
374745fb4d304f59e4e4cca917d372278eeb75be2c33njn   (printf et al).  Any kind of entanglement with libc or dynamic linking is
374845fb4d304f59e4e4cca917d372278eeb75be2c33njn   likely to have a bad outcome, for tricky reasons which we've grappled
374945fb4d304f59e4e4cca917d372278eeb75be2c33njn   with a lot in the past.
37501319b49115bd0763628273b8a3fe08ac30712e31njn*/
37510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
3752315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
37530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
37540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
37550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL0,          \
37560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
37579af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0);                       \
37580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
37593e88418f808bf2840646504481d6a5be1df16541njn   })
37603e88418f808bf2840646504481d6a5be1df16541njn
37610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
3762315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
37630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
37640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
37650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL1,          \
37660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
37679af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, 0, 0, 0);               \
37680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
37693e88418f808bf2840646504481d6a5be1df16541njn   })
37703e88418f808bf2840646504481d6a5be1df16541njn
37710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
3772315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
37730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
37740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
37750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL2,          \
37760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
37779af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, _qyy_arg2, 0, 0);       \
37780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
37793e88418f808bf2840646504481d6a5be1df16541njn   })
37803e88418f808bf2840646504481d6a5be1df16541njn
37810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
3782315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
37830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
37840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
37850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL3,          \
37860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
37879af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, _qyy_arg2,              \
37889af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg3, 0);                     \
37890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
37903e88418f808bf2840646504481d6a5be1df16541njn   })
37913e88418f808bf2840646504481d6a5be1df16541njn
37923e88418f808bf2840646504481d6a5be1df16541njn
37937cc9c239f785f2903b597cdb34418bed42d25331nethercote/* Counts the number of errors that have been recorded by a tool.  Nb:
37947cc9c239f785f2903b597cdb34418bed42d25331nethercote   the tool must record the errors with VG_(maybe_record_error)() or
379547363aba8fa03b094195bca99fc232ce5f85605dnjn   VG_(unique_error)() for them to be counted. */
37960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_COUNT_ERRORS                                     \
3797315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
37980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qyy_res;                                       \
37990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
38000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__COUNT_ERRORS,          \
38019af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0, 0);                    \
38020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
380347363aba8fa03b094195bca99fc232ce5f85605dnjn   })
380447363aba8fa03b094195bca99fc232ce5f85605dnjn
38053ac96953bf8c912a2aaa2870652dda8b9b75337bnjn/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
38063ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   when heap blocks are allocated in order to give accurate results.  This
38073ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happens automatically for the standard allocator functions such as
38083ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
38093ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   delete[], etc.
38103ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38113ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   But if your program uses a custom allocator, this doesn't automatically
38123ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happen, and Valgrind will not do as well.  For example, if you allocate
38133ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   superblocks with mmap() and then allocates chunks of the superblocks, all
38143ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind's observations will be at the mmap() level and it won't know that
38153ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   the chunks should be considered separate entities.  In Memcheck's case,
38163ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that means you probably won't get heap block overrun detection (because
38173ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   there won't be redzones marked as unaddressable) and you definitely won't
38183ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   get any leak detection.
38193ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38203ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   The following client requests allow a custom allocator to be annotated so
38213ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that it can be handled accurately by Valgrind.
38223ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38233ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
38243ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   by a malloc()-like function.  For Memcheck (an illustrative case), this
38253ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   does two things:
38263ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38273ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been allocated.  This means any addresses
38283ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     within the block mentioned in error messages will be
38293ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     identified as belonging to the block.  It also means that if the block
38303ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     isn't freed it will be detected by the leak checker.
38313ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38323ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being addressable and undefined (if 'is_zeroed' is
38333ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     not set), or addressable and defined (if 'is_zeroed' is set).  This
38343ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     controls how accesses to the block by the program are handled.
38353ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38363ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   'addr' is the start of the usable block (ie. after any
38373ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
38383ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   can apply redzones -- these are blocks of padding at the start and end of
38393ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   each block.  Adding redzones is recommended as it makes it much more likely
38403ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
38413ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroed (or filled with another predictable value), as is the case for
38423ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   calloc().
38433ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38443ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
38453ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block -- that will be used by the client program -- is allocated.
38463ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   It's best to put it at the outermost level of the allocator if possible;
38473ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   for example, if you have a function my_alloc() which calls
38483ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   internal_alloc(), and the client request is put inside internal_alloc(),
38493ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   stack traces relating to the heap block will contain entries for both
38503ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   my_alloc() and internal_alloc(), which is probably not what you want.
38513ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38523ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
38533ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Memcheck, it does two things:
38543ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38553ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been deallocated.  This assumes that the
38563ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     block was annotated as having been allocated via
38573ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
38583ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38593ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being unaddressable.
38603ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38613ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
38623ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block is deallocated.
38633ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38643ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   In many cases, these two client requests will not be enough to get your
38653ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator working well with Memcheck.  More specifically, if your allocator
38663ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
38673ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   will be necessary to mark the memory as addressable just before the zeroing
38683ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   occurs, otherwise you'll get a lot of invalid write errors.  For example,
38693ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   you'll need to do this if your allocator recycles freed blocks, but it
38703ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
38713ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Alternatively, if your allocator reuses freed blocks for allocator-internal
38723ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
38733ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38743ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Really, what's happening is a blurring of the lines between the client
38753ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
38763ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   memory should be considered unaddressable to the client program, but the
38773ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator knows more than the rest of the client program and so may be able
38783ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   to safely access it.  Extra client requests are necessary for Valgrind to
38793ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   understand the distinction between the allocator and the rest of the
38803ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program.
38813ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
38823ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request;  it
38833ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   has to be emulated with MALLOCLIKE/FREELIKE and memory copying.
3884d799418996812817596beaa8b59563e3f3cb2ddanjn
3885479db774b080e3eef41b2ebb94d67f82d5c1788enjn   WARNING: if your allocator uses malloc() or 'new' to allocate
3886479db774b080e3eef41b2ebb94d67f82d5c1788enjn   superblocks, rather than mmap() or brk(), this will not work properly --
3887479db774b080e3eef41b2ebb94d67f82d5c1788enjn   you'll likely get assertion failures during leak detection.  This is
3888479db774b080e3eef41b2ebb94d67f82d5c1788enjn   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.
388932f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn
389032f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
38913ac96953bf8c912a2aaa2870652dda8b9b75337bnjn*/
38920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
38930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
38940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
38950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MALLOCLIKE_BLOCK,      \
38969af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               addr, sizeB, rzB, is_zeroed, 0);   \
3897d799418996812817596beaa8b59563e3f3cb2ddanjn   }
3898d799418996812817596beaa8b59563e3f3cb2ddanjn
389932f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
390032f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
390132f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn*/
39020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
39030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__FREELIKE_BLOCK,        \
39069af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               addr, rzB, 0, 0, 0);               \
3907d799418996812817596beaa8b59563e3f3cb2ddanjn   }
3908d799418996812817596beaa8b59563e3f3cb2ddanjn
3909bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Create a memory pool. */
39100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
39110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CREATE_MEMPOOL,        \
39149af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, rzB, is_zeroed, 0, 0);       \
3915bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
3916bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3917bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Destroy a memory pool. */
39180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
39190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__DESTROY_MEMPOOL,       \
39229af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, 0, 0, 0, 0);                 \
3923bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
3924bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3925bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Associate a piece of memory with a memory pool. */
39260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
39270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MEMPOOL_ALLOC,         \
39309af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, addr, size, 0, 0);           \
3931bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
3932bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
3933bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Disassociate a piece of memory from a memory pool. */
39340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
39350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MEMPOOL_FREE,          \
39389af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, addr, 0, 0, 0);              \
3939bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
3940bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
39412c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj/* Disassociate any pieces outside a particular range. */
39422c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
39432c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj   {unsigned int _qzz_res;                                        \
39442c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39452c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj                               VG_USERREQ__MEMPOOL_TRIM,          \
39462c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj                               pool, addr, size, 0, 0);           \
39472c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj   }
39482c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj
3949c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
3950c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
3951c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   {unsigned int _qzz_res;                                        \
3952c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3953c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MOVE_MEMPOOL,          \
3954c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               poolA, poolB, 0, 0, 0);            \
3955c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   }
3956c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
3957c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
3958c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
3959c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   {unsigned int _qzz_res;                                        \
3960c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3961c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_CHANGE,        \
3962c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               pool, addrA, addrB, size, 0);      \
3963c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   }
3964c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
3965c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Return 1 if a mempool exists, else 0. */
3966c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
39674486297d932a229cb383ca0671d57657677dd56enjn   __extension__                                                  \
3968c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   ({unsigned int _qzz_res;                                       \
3969c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
3970c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_EXISTS,        \
3971c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               pool, 0, 0, 0, 0);                 \
3972c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    _qzz_res;                                                     \
3973c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   })
3974c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
39750140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Mark a piece of memory as being a stack. Returns a stack id. */
39760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_REGISTER(start, end)                       \
39774486297d932a229cb383ca0671d57657677dd56enjn   __extension__                                                  \
39780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qzz_res;                                       \
39790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_REGISTER,        \
39819af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               start, end, 0, 0, 0);              \
39820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qzz_res;                                                     \
39830140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   })
39840140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
39850140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Unmark the piece of memory associated with a stack id as being a
39860140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   stack. */
39870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_DEREGISTER(id)                             \
39880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_DEREGISTER,      \
39919af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               id, 0, 0, 0, 0);                   \
39920140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   }
39930140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
39940140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Change the start and end address of the stack id. */
39950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_CHANGE(id, start, end)                     \
39960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
39970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
39980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_CHANGE,          \
39999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               id, start, end, 0, 0);             \
40000140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   }
40010140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
4002c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* Load PDB debug info for Wine PE image_map. */
4003c8259b85b701d25d72aabe9dc0a8154517f96913sewardj#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)   \
4004c8259b85b701d25d72aabe9dc0a8154517f96913sewardj   {unsigned int _qzz_res;                                        \
4005c8259b85b701d25d72aabe9dc0a8154517f96913sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
4006c8259b85b701d25d72aabe9dc0a8154517f96913sewardj                               VG_USERREQ__LOAD_PDB_DEBUGINFO,    \
4007c8259b85b701d25d72aabe9dc0a8154517f96913sewardj                               fd, ptr, total_size, delta, 0);    \
4008c8259b85b701d25d72aabe9dc0a8154517f96913sewardj   }
4009c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
40100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4011f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
4012f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
4013f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
4014f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
4015f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_aix5
4016f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_aix5
40170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
40183e88418f808bf2840646504481d6a5be1df16541njn#endif   /* __VALGRIND_H */
4019